Skip to main content
Live. This area is documented as current, user-reliable behavior.

Goal

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

Prerequisites

  • A job handler with access to state

Workflow

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

Get, set, and delete

Track progress
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
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
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
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.

Idempotency

Use idempotency keys so duplicate requests do not create duplicate work.

Observability

Inspect each job run through status, attempts, logs, payload, result, errors, and timeline.