Documentation

State Store

Use durable state for progress, deduplication, counters, TTL-backed markers, and locks.

Search Docs

Durable Jobs

State Store

Live

Use durable state for progress, deduplication, counters, TTL-backed markers, and locks.

Goal

Store small pieces of durable job memory without adding a separate database table for every workflow concern.

Current status

Live

This area is documented as current, user-reliable behavior.

Workflow

  1. 1Read state when a job starts or resumes.
  2. 2Set state after meaningful progress.
  3. 3Use TTLs for temporary markers.
  4. 4Use counters for progress and rate-aware flows.
  5. 5Use locks when only one run should own a resource at a time.

Get, set, and delete

Track progress

ts
const progressKey = `imports:${payload.importId}:progress`

await state.set(progressKey, { processed: 100, total: 500 })

const progress = await state.get<{ processed: number; total: number }>(progressKey)

if (progress.processed === progress.total) {
  await state.delete(progressKey)
}

TTL

Use TTL-backed state for temporary dedupe markers, short-lived locks, and status values that should expire automatically.

Temporary webhook marker

ts
await state.set('webhooks:stripe:evt_123', { processed: true }, {
  expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
})

Counters and locks

  • Use counters for import progress, retry-aware limits, and lightweight metrics.
  • Use locks for work that should have one owner, such as rebuilding a customer search index or provisioning a shared resource.
  • Give locks a short TTL so abandoned work can recover.

Count processed rows

ts
const processed = await state.increment(`imports:${payload.importId}:processed`)

if (processed % 100 === 0) {
  await publishProgress(payload.importId, processed)
}

Webhook deduplication

Dedupe with state and idempotency

ts
await stackshift.queue('webhooks').enqueue(
  'processStripeWebhook',
  { eventId: event.id, type: event.type },
  { idempotencyKey: `stripe:${event.id}` }
)

Expected result

Workflow progress and deduplication survive retries and process restarts.