Skip to content

Part 1 of 7 · Delivery exception handler series ~6 min read

A delivery exception handler on AWS for a few dollars a month

A customer emails on Thursday asking where their order is. Tracking says “in transit”, which it has said since Saturday. Nobody looked, because nothing flagged it: there is no exception status, no failed delivery, no problem at all according to the carrier. The parcel has been sitting behind a roller door in a depot for five days. This post walks through a small system that notices on Tuesday.

woman standing near three red pendant lamps
Photo by Rohan G on Unsplash

Key takeaways

  • Silence is the signal. No scan for several days beats any exception code.
  • Carrier statuses are unreliable in known directions and need translating.
  • Triage matters: most exceptions resolve themselves and a few need action today.
  • Never give a customer a delivery date you do not have.
  • Designed on AWS for about $2 a month.

The whole system on one page

Before any code, here is the shape of what we are designing.

System: delivery exceptions detected, triaged and communicatedThree boxes across the top sit outside the AWS account. On the left, Carrier tracking, providing events and gaps. In the middle, The orders, holding what was promised. On the right, The customer, who is told what is known. Each connects by an arrow to the AWS account container below. Scans, or the absence of them, flow down into the account. Promised dates feed in. One honest message goes back out. Inside the AWS account are three components in a row. On the left, the Watcher, following events and silence both. In the middle, Triage, asking whether this will fix itself. On the right, Contact, sending facts only with no invented dates. A note at the bottom says the watcher's most valuable input is the event that did not arrive.AWS ACCOUNTCarrier trackingevents, and gapsThe orderswhat was promisedThe customertold what is knownWatcherevents and silence,bothTriagewill this fixitself?Contactfacts only,no invented datesscans, or nonepromised datesone honest messageThe watcher's most valuable input is the event that did not arrive.
Fig 1. Three things outside the account, three pieces inside it. The first box is doing something unusual: watching for nothing happening.
  • App integration
  • Analytics
  • Front-end & mobile
  • People

Why carrier statuses are not enough

Every carrier provides exception codes and they are genuinely useful for the cases they cover: address not found, refused, damaged in transit. The problem is what they do not cover, and the specific ways they mislead.

“Attempted delivery, nobody home” is sometimes exactly that and is sometimes a driver who ran out of hours and needed to close the round. A parcel mis-sorted to the wrong depot generates no exception at all; it simply stops moving. And a shipment that was never actually collected shows as despatched forever, because the first scan never happened.

What runs (the inside)

  • The watcher. Ingests tracking events and, more importantly, notices when they stop. Part 2.
  • Triage. Sorts exceptions into the ones that fix themselves and the ones that need somebody today. Part 3.
  • Contact. Tells the customer what is known, in the cases where telling them helps. Part 4.

One exception, end to end

One stuck shipment detected from a gap in tracking eventsA horizontal row of five boxes joined by arrows. Despatched: Friday. Last scan: Saturday, in transit. Silence: Sunday, Monday, Tuesday. Flagged Tuesday: three working days. Traced and told: before they asked. A note says the carrier reported no problem at any point, and the gap was the whole signal.ONE EXCEPTION, END TO ENDDespatchedFridayLast scanSaturday, in transitSilenceSun, Mon, TueFlagged Tuesday3 working daysTraced, toldbefore they askedThe carrier reported no problem at any point. The gap was the whole signal.
Fig 2. The same system as one line. Every stage after the second is driven by something not happening, which is why it needs a system rather than a dashboard.
  • App integration
  • Management
  • Analytics

In plain words

An order goes out on Friday. It is scanned into the network on Saturday morning and then nothing happens. Sunday is not a working day, Monday passes with no scan, Tuesday passes with no scan.

On Tuesday afternoon the watcher flags it: three working days since the last event, against a service where the typical gap between scans is under a day. That threshold is not a guess — it comes from the carrier’s own observed behaviour on that service, which the system has been measuring.

Somebody raises a trace with the carrier on Tuesday and emails the customer: your parcel has not moved since Saturday, we have asked the carrier to find it, we will tell you tomorrow what they say. No new delivery date, because there is not one. That message is the entire product, and it lands two days before the customer would have written in annoyed.

Design rules that shaped every decision

  • Watch for silence, not just for exception codes.
  • Thresholds come from each carrier and service’s observed behaviour, not from a guess.
  • Triage before contact. Most exceptions resolve themselves within a day.
  • Never state a delivery date that is not a fact.
  • One message per exception, and a follow-up only when something actually changed.
  • Record which exceptions resolved on their own, so the thresholds can be tuned.

Why this shape

The failure mode this replaces is not that nobody cares about late deliveries; it is that nothing surfaces them until a customer does. Support then spends its time reacting to people who are already annoyed, on parcels that have been stuck for days, with no information beyond the tracking page the customer has already read.

Shifting that by two days changes the interaction completely. The same problem, communicated first and honestly, generates a fraction of the support load and a different customer reaction, without any improvement in the actual delivery performance.

The next four posts walk through each piece: how an exception is detected, what each kind actually needs, how the customer gets told, and what the exceptions reveal in aggregate. One diagram per post, a cost breakdown, and an engineering reference at the end.

All posts