The Thursday Promise
Operations review · Spring 2026
How one order crosses five teams, fails twice, and still arrives on time.
Ada Lindqvist, Operations · Spring 2026
Order #4711 · the promise
One promise, five hand-offs
- The shop promises Thursday the moment the customer pays
- Payments, warehouse and courier each own one hand-off
- Every team hits its own target, and still one order in eleven arrives late
- Nobody owns the promise from end to end
The five hand-offs, start to finish
- One order, three teams; the dot is the promise in flight
The journey on one screen
- Five stations, one order, three tiles the customer sees on the tracking page
Payment: declined, then paid
- 21:04: the card fails a fraud check, the tracking page says so
- 21:05: an automatic retry thirty seconds later goes through
The warehouse falls behind
- Tuesday 06:00: a promotion lands 1,200 orders on one picker, the promise slips to Friday
- 06:20: a second picker joins from returns, the queue drains in 40 minutes
- 07:10: order #4711 is packed, Thursday is back on the tile
On the road
What changed after #4711
Before
- Each team watched its own queue
- A declined card ended the order
- Promotions were planned by marketing alone
After
- One tracking screen, owned by operations
- One automatic retry, then a message to the customer
- The returns desk lends a picker above 500 waiting orders
The retry rule
- One retry, thirty seconds later, with the same idempotency key
- A second decline is final: the customer gets a message, not silence
- The key makes a double charge impossible
Before #4711
// one try: a timeout became a "payment failed" email
func charge(ctx context.Context, o Order) error {
return payments.Charge(ctx, o.Total, "order-"+o.ID)
}After #4711
// retry once; the key makes a second charge a no-op
func charge(ctx context.Context, o Order) error {
key := "order-" + o.ID
err := payments.Charge(ctx, o.Total, key)
if errors.Is(err, payments.ErrDeclined) {
time.Sleep(30 * time.Second)
err = payments.Charge(ctx, o.Total, key)
}
return err
}- The order id is the idempotency key
- Thirty seconds: the bank's batch is done by then
98.7%
of Thursday promises kept in the first month, up from 91%.
The customer never saw the declined card or the queue. She saw Thursday.
Route 7 courier log, Thursday 14:32
The floor, after the change
- The second picker starts at the packing end and works backwards
- Pickers meet in the middle aisle, so no order waits for a full walk
- The packing table moved next to the loading door
Wednesday, 05:40
The first vans leave while the city is still asleep.
Every route, every morning
- 42 routes leave between 05:30 and 07:00
- Each van carries about 120 parcels
- Thursday promises ride on Wednesday's first wave
Where a promise breaks
A late parcel
- Payment
- Bank timeout
- Fraud review
- Warehouse
- One short-staffed shift
- Road
- A cut-off that leaves too early
Three habits to keep
- Follow one order end to end every month
- Retry once, then tell the customer
- Lend people before you add systems
The numbers behind each habit are in the appendix.
Part 1
Appendix: the numbers
Where the time goes, and what each change bought.
Where an order spends its time
flowchart LR
shop[Shop] --> pay[Payments]
pay -- declined --> retry{{Retry in 30 s}}
retry --> pay
pay --> wh[Warehouse]
wh --> courier[Courier]
courier --> door[Doorstep]
Hand-off times, median
| Hand-off | Before | After |
|---|---|---|
| Paid to picked | 9 h 40 min | 3 h 05 min |
| Picked to packed | 35 min | 22 min |
| Packed to on a van | 14 h | 13 h 30 min |
| Declined payments recovered | 0% | 61% |
Three changes that held
Retry once, after 30 s
A declined card waits half a minute and tries again, once.
Pick by evening wave
Orders paid before 18:00 are picked the same night.
One dusk departure
Vans leave at 21:40 with every parcel picked that day.
Two views of route 7
Now, let's do a Lab!
Thank you
Questions about order #4711, the retry rule or the returns desk are welcome.