When an endpoint delivery fails, Nevo retries it on an exponential schedule tied to the endpoint’s policy. Deliveries that exhaust the policy land in the dead-letter queue (DLQ) so you can inspect, diagnose, and replay them from the dashboard.
Failure model
A delivery fails when any of these happens:
- Your endpoint returns a non-2xx HTTP status (any 4xx or 5xx counts).
- The request times out (10 seconds today).
- The connection can’t be established at all (DNS, TLS, network error).
On failure, Nevo schedules the next attempt. The delivery row shows status=retrying until either a later attempt succeeds or the budget is exhausted.
Retry policy
Every endpoint carries two fields that control its retry behaviour:
| Field | Default | What it controls |
|---|---|---|
retry_max_attempts | 5 | Total attempts (including the first). |
retry_backoff_base_seconds | 60 | Base delay in seconds; doubles each retry. |
With the defaults a failing delivery produces attempts at roughly:
t=0s → t=60s → t=120s → t=240s → t=480s (five total). After attempt 5, the
delivery transitions to status=failed and the event lands in the DLQ.
Edit these fields from Endpoints → your endpoint → Retry policy in the dashboard. Changes apply to new deliveries only — in-flight retries use the policy that was in effect when they were scheduled.
Picking a policy
- A low-volume endpoint on a flaky third-party service wants a longer base and
more attempts —
max=7, base=120slets the delivery ride out a 20-minute incident. - A high-volume internal endpoint usually wants the defaults or lower — the system it’s calling will be healthy again within a few minutes or you have bigger problems.
- Setting
max=1disables retry entirely for that endpoint. The delivery goes straight to DLQ on first failure.
Delivery attempts in the event detail
Open any event in the dashboard and the Deliveries section lists every attempt per endpoint:
- A single successful delivery reads
200 · 142ms · 1x. - A delivery that retried twice before succeeding reads
200 · 93ms · 3x. - A delivery still retrying shows the attempt count and a countdown:
retrying · 2x · next retry in 1m 46s. - A terminal failure reads
failed · 5xand surfaces the last error message.
The event’s overall status reflects the aggregate of its deliveries:
delivered— at least one delivery succeeded (after any number of retries).failed— every delivery exhausted its policy and terminally failed.pending— one or more deliveries are still mid-retry.
A retry that succeeds after the initial round automatically walks the event
back from failed to delivered.
Dead-letter queue
The DLQ view (Projects → your project → DLQ) lists every delivery that
terminally failed across the project — one row per (event × endpoint). For
each row you see:
- The originating event (source, summary, timestamp), clickable to open the full event detail.
- The endpoint URL that failed.
- The last HTTP status code and error message.
- How many attempts were made before giving up.
From here you can replay the event with one click, or open the event and use edit-and-replay to tweak the body before re-dispatching.
Signatures on retried requests
Every attempt — first try or fifth — carries the same HMAC signature scheme as
live deliveries. The Nevo-Origin header is live for all attempts, even
retries, since the retry is part of the same delivery lifecycle. Only explicit
dashboard replays mark Nevo-Origin: replay.
Plan availability
Retries ship on every plan. DLQ retention follows your plan’s replay retention window:
| Tier | DLQ retention |
|---|---|
| Hobby | 7 days |
| Hacker | 14 days |
| Pro | 30 days |
| Scale | 90 days |
After the retention window, DLQ rows age out alongside their parent events.
Related
- Endpoints — where the retry policy lives.
- Events view — inspecting deliveries + replaying.