Retail & e-commerce
Cutting failed deliveries by more than half by fixing the address, not the map
An order state machine, delivery slots tied to real rider capacity, and a customer app and a rider app built for the phones and networks people actually have, not the ones a demo runs on.
- On-time delivery rate
- low seventies → low nineties, percent
- Failed first-attempt deliveries
- cut by more than half
- Repeat purchase share via the app
- roughly tripled
- Sector
- D2C retail & quick commerce
- Estate
- ~40 dark stores/hubs across 3 metros
- Engagement
- Product build, then a retained pod
- Duration
- 10 months to first market, ongoing
Stack
- Flutter
- NestJS
- PostgreSQL
- Redis
- Kafka
- OSRM routing
- Google Maps Platform
- Razorpay
- Kubernetes
Practices involved
Discuss a similar problemThe situation
The retailer's stack had grown by accretion: a storefront plugin, order tracking in a shared spreadsheet once a marketplace integration fell over, and delivery handled by whichever local courier picked up the phone that day. There was no owned customer app, so no push notification, no saved address, and no channel for a second order that did not go back through a marketplace taking a cut of it.
The constraint
Two things made a straightforward rebuild the wrong plan. First, a delivery promise like "in 90 minutes" has to reflect the rider capacity and stock actually available from the nearest hub at that moment, not a flat radius on a map — overpromising a slot was the single biggest driver of bad reviews before we started. Second, addresses in the markets served are frequently informal — a landmark and a floor number, not a reliable postal code — and a failed delivery costs a return trip, a frustrated rider and a customer who does not order again.
What we built
Order orchestration as the source of truth
One order state machine spans cart, payment, pack, dispatch, delivery and returns, replacing three disconnected systems. Every state change is an event; the customer app, the rider app, the hub dashboard and finance subscribe to it rather than polling three different sources that used to disagree.
Slot promising tied to real capacity
Delivery slot availability is computed from live rider capacity, hub inventory and a real drive-time matrix, recomputed as conditions change, rather than a static radius set once at launch.
Address resolution that assumes the address is wrong
Customers drop a map pin and add a landmark note; the rider app shows both, and a reusable "last 200 metres" note attaches to the saved address for next time. Most of the reduction in failed first attempts came from this, not from a better map provider.
A rider app for the phones people actually carry
Offline-first, with a local queue of assigned stops and opportunistic sync, running acceptably on low-end Android devices, because a meaningful share of the delivery fleet uses hand-me-down phones on patchy data. Cash-on-delivery collections log against the order automatically and reconcile at day close instead of on a whiteboard.
A customer app built around the second order, not the first
Push-driven reorder flows, live tracking with a recalculated ETA instead of a static countdown, and saved addresses that get more accurate every time they are used.
What changed
On-time delivery moved from the low seventies into the low nineties, percentage-wise, and failed first attempts fell by more than half, mostly from the address work rather than routing changes. The app now carries a meaningful share of orders as repeat purchases, which is revenue the retailer keeps instead of paying a marketplace for it a second time.
What we would do differently
The first rider app version polled GPS location every five seconds to keep tracking smooth. It drained batteries within a shift, and riders started quietly turning the app off mid-route, which silently broke tracking for exactly the deliveries where it mattered most. We moved to adaptive, event-driven location pings in month four. Battery and data budget should have been a stated constraint from day one, not something we learned from riders switching the app off.
Outcomes
- On-time delivery rate
- low seventies → low nineties, percent
- Failed first-attempt deliveries
- cut by more than half
- Repeat purchase share via the app
- roughly tripled
Client identity withheld under a mutual NDA. Figures are illustrative — rounded and directional, meant to show the shape of the change rather than an audited result. We will walk through the real numbers, and how they were measured, under NDA on a call.
More work
Other engagements.
Case studiesCutting stockouts across 240 stores with a forecast the buyers trust
A hierarchical demand forecast, a promo-aware feature store and a replenishment workflow the category team can override — because a model nobody overrides is a model nobody uses.
Read the case studyShipping firmware to 6,000 imaging consoles without a truck roll
A signed, resumable, rollback-safe update channel for regulated ultrasound hardware sitting on hospital networks that block almost everything.
Read the case studyA reproducible pipeline for a diagnostics lab that had outgrown its scripts
Genomic and assay data moving from instruments to reportable results, with provenance for every derived value and a turnaround clock the lab director can see.
Read the case studyNext step
Tell us what you're trying to ship.
Send the brief, the RFP, or three messy sentences about the problem. You get a written point of view from an architect within two working days — not a sales deck.