incident · messaging
Orders are occasionally processed twice.
Support has three complaints this week about duplicate fulfilment. It is not every order. It is not a particular customer. Your worker code has no obvious loop, the queue has no obvious misconfiguration, and the failure will not reproduce when you run it by hand.
Visibility timeout: 30s
Median processing time 6s. p99 41s — and only on orders with many line items.
Receive count > 1 on a small fraction of messages. No dead letters.
A retry wrapper in the HTTP client, added last month, with three attempts.
A recent deploy that doubled worker concurrency.
Processing time exceeds the visibility timeout. When a worker takes longer than 30s, the queue decides the message was never handled and makes it visible again — so a second worker legitimately picks up an order the first worker is still processing. Both complete. Both fulfil.
Nothing is broken. The queue honoured its contract exactly. The bug is that your code assumed “received” meant “nobody else will get this”.
The retry wrapper and the concurrency deploy both correlate with the symptom and neither causes it — which is precisely why the incident took three days in real life.