Production checklist
Everything to settle before real customers receive webhooks, with a link to the details for each item.
Work through this list once before launch. Each item links to the page that explains it.
Keys and secrets
- The storage encryption key is generated once, kept in a secret manager, and loaded by every app and worker process. Never generate it at startup. Manage endpoints
- Signing secrets are shown to the customer once, over a secure channel, and never logged. Security model
- You know how to rotate both a signing secret and the storage key. Key rotation
Database
- Migrations run through your migration tool, not at app startup. Migrations
- Every process calls
check()at startup and fails fast onSCHEMA_MISMATCH. - Pool sizes and statement timeouts are budgeted across app, worker, and cleanup processes. Run workers
Publishing
- Events are published inside the transaction that changes your data, where the tables share a database. Publish events
- Every
publish()that can repeat has anidempotencyKeyderived from the business fact. - Your app authorizes the caller before choosing a scope. Scopes don't check permissions. Scopes
-
allowLocalhostis off.
Worker
- At least one worker runs as its own supervised process, restarted with backoff on failure. Run workers
-
SIGTERMaborts the worker's signal, and the supervisor's kill deadline is longer thanshutdownGraceMs. - Worker failures are logged and alerted on: either
run()rejects and the process exits, or youronErrorlogs and you watch that deliveries keep moving. Handle failures - You have read what a crash, a dropped connection, and a hard kill do to in-flight work. Failure behavior
- You have compared your receiver latency and volume against the measured profile and sized
concurrencyandmaxInFlightaccordingly. Performance
History
- A cleanup job calls
prune()on a schedule. Workers never delete history. Retention - Delivery history is treated as customer data: it holds payloads and response bodies.
- Support staff know how to inspect deliveries and replay one. Retries and replay
Receivers
- Receivers verify the raw body and record
event.idwith their change, so retries and replays are harmless. Receive webhooks - Event names stay backward compatible. Breaking payload changes get a new name, such as
invoice.paid.v2.
Upgrades
- The package version is pinned exactly, and you read the release notes before upgrading. Compatibility