postmortem · final review
The 12 June export delays
One export that could never succeed returned to the head of the queue for 94 minutes. This is the settled incident record: mechanism, impact, chronology, and the changes that prevent one bad job from holding every export behind it.
- Detected
- 09:14, queue-depth alert
- Resolved
- 10:48, poison job quarantined
- Blast radius
- exports only; imports and sync unaffected
What happened
A workspace uploaded attachment metadata that our validator accepted but the export worker could not serialize. The worker treated every failure as retryable, so the same job returned to the front of the queue every 45 seconds and all later exports waited behind it.
graph LR Q[queue head] --> W[worker] W -->|serialize fails| R[retry in 45s] R --> Q Q -.->|starved| B[1,204 jobs behind]
Why a declared attachment size of −1 fails every attempt
The upload predates the size check added in March. Two other workspaces held the same shape; both were quarantined before their next export. The customer data triggered the path, but our validator and retry policy made it an incident.
Impact
| Exports delayed | 1,204 |
|---|---|
| Exports lost | 0 |
| Workspaces affected | 412 |
| Longest delay | 81 minutes |
Timeline
The first fix stays in the record because it briefly drained the queue without removing the job that was filling it again.
What changed
- A job that cannot succeed is now set aside and pages a person instead of retrying.
- Every retry rejoins at the back, so a single export cannot hold the queue. Both changes shipped on 13 June.
- A new alert fires when one job fails repeatedly, before queue depth becomes the first visible symptom.