Launch offer: the first 1,000 users get Settl free for a year*Claim your spot
settlbuilding in public

Move Slow Work Out of the Request Path

R050 is the CPU-heavy request that blocks every other request in a Node process. R075 is the signup endpoint waiting for an email provider. Both are the same architecture mistake: work that does not need to finish before the HTTP response is sitting inside the response path.

Async syntax does not move CPU work somewhere else. await gives the event loop room while an external operation is waiting. A large PDF render or image transform still occupies the process.

Split request from work

The request handler should do four things:

  1. authenticate and validate the input;
  2. create a stable idempotency key;
  3. persist a job and its payload;
  4. return 202 Accepted with a job ID and status URL.

The worker claims the job, performs the slow work, records the external result, and moves the job to succeeded or failed. CPU-heavy work belongs in a worker process or worker thread. Slow email, webhook, export, and third-party API calls belong in a durable queue.

Do not return 202 before the job is durable. Otherwise the server can crash after the response and before the work exists anywhere.

Give the job a real state machine

Use visible states:

queued -> running -> succeeded
                 -> retry_wait -> queued
                 -> dead_letter
                 -> cancelled

Record attempt count, next attempt time, last error, worker lease, created time, and final external ID. A stuck running job needs a lease timeout so another worker can recover it.

Make retries safe

The queue may deliver a job more than once. Design for at-least-once delivery:

Retry transient failures with backoff and jitter. Do not retry invalid input, cancellation, or a permanent permission failure forever. Move exhausted jobs into a visible dead-letter state with an owner and replay button.

Let the user see the truth

The API response should say queued, not completed. The client can poll the status URL, subscribe to updates, or wait for a notification. If email delivery fails later, preserve the account and expose the failed welcome-email job instead of rolling back a successful signup.

Claude can summarize errors or draft a customer message. Code owns validation, state transitions, idempotency, and retry timing.

Run the starter locally

npm test
npm run validate
npm run sample

Docker Compose starts the workflow boundary and n8n. The starter returns a proposed queue contract in dry-run mode and executes no external job.

Download the runnable pack

Get the next one in your inbox