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

Goal

Build a backend flow that survives retries and external waiting.

Prerequisites

  • A handler route exposed to StackShift

Workflow

1
Wrap side effects in named steps.
2
Wait for external events with a correlation key.
3
Let StackShift save progress and resume the job when the event arrives.
4
Handle timeout behavior explicitly.

Onboarding workflow

This flow creates a user, sends email, waits for verification, then unlocks the account.
stackshift.job<{ userId: string; email: string }>('userOnboarding', async ({ payload, step }) => {
  const { userId, email } = payload

  const user = await step.run('create-user', () => {
    return createUser({ id: userId, email })
  })

  await step.run('send-verification-email', () => {
    return sendVerificationEmail(user.email)
  })

  const event = await step.waitForEvent<{ userId: string }>('email.verified', {
    correlationKey: `user:${userId}`,
    timeout: '24h',
    onTimeout: 'fail',
  })

  await step.run('unlock-account', () => {
    return unlockAccount(event.payload.userId)
  })

  return { onboarded: true }
})

Resume behavior

  • Before the wait, completed step results are saved.
  • While waiting, the run is not consuming compute.
  • When the matching event arrives, StackShift invokes the handler again with the event result.
  • Completed steps return their saved outputs and the job continues after the wait.

Failure handling

  • If a step throws, the run is retried according to its retry policy.
  • Completed steps are not repeated on retry.
  • If the wait times out, StackShift follows the configured timeout behavior.

Expected result

A multi-step job resumes from saved state instead of starting over.

Event Waiting + Correlation

Pause a workflow until the right external event arrives, then resume the correct run.

Retries & Failure Handling

Durable Jobs retries transient failures, preserves completed steps, and gives failed work a clear recovery path.