Deliveries.
When N pipelines match one event, the worker writes N delivery rows — one per pipeline. Each row is the unit of retry. A row covers all of that pipeline's destinations: if any of them fails, the whole row retries (so destinations that already succeeded receive the event again, idempotently).
Statuses
Four values.
- pendingCreated, awaiting first attempt. Lives briefly before the run starts.
- retryingFailed at least once; scheduled for another attempt at the backoff time.
- deliveredAll destinations 2xx'd, or the pipeline short-circuited (filter / dedupe / throttle drop).
- deadFive attempts exhausted. No further retries. Visible for inspection.
Retry curve
Exponential, capped.
After a failed attempt, the next attempt is scheduled further out each time:
- 1.
- +30s
- first retry
- 2.
- +2m
- second retry
- 3.
- +10m
- third retry
- 4.
- +1h
- fourth retry
- 5.
- —
- delivery is marked dead
Dead deliveries stick around for inspection — you can read the last error and replay them by hand from the dashboard.
Throttle delay
Yield, not fail.
A throttle action in delay mode pushes the next attempt out by the throttle window — without bumping the attempt count or counting it as a failure. The delivery sits in retrying with a "delayed by throttle" note until the window rolls.
Filter / dedupe drops
Logically delivered.
When a control action short-circuits the pipeline — a filter returning false, a dedupe hit, a throttle drop — the delivery is marked delivered. The pipeline ran to completion and the event correctly went nowhere. There's no separate "dropped" status.
Inspecting
Per-event view.
Open any event from /events and the detail page shows every delivery tied to it: which pipeline, which destination kinds, status, attempts, last error. That's where to look first when an event you sent didn't arrive somewhere.