A last mile delivery tracking system, scoped around the cash
Everyone briefs this as a map with a moving dot. The map is the easy half. The part that decides whether the system is worth running is what happens to the money the driver collected, and whether the app still works in a basement with no signal.
The brief arrives as a tracking map. A courier operation has thirty drivers, customers keep ringing the office to ask where their parcel is, and somebody has decided the answer is a live map with a moving dot. That is a real feature and it is roughly a fifth of the work.
The reason these builds disappoint is that the map answers the customer's question while leaving the operator's two actual problems untouched. The operator needs to know which stops will not be made today, early enough to do something about it, and needs the cash the drivers collected to reconcile at the end of the day without a spreadsheet and an argument.
The four parts, in the order they earn their keep
Scope it as four pieces rather than one app, because they fail independently and the last one is where these projects actually go wrong.
- Dispatch: turning a day's orders into routes and assigning them to drivers.
- The driver app: the only piece that touches reality, and the only one used offline.
- Proof of delivery: what you captured at the door, and whether it stands up later.
- Reconciliation: cash collected versus cash banked, per driver, per day.
Build them in that order if you can, but scope reconciliation first. It is the one that determines your data model, and retrofitting it is expensive because it reaches back into every delivery record you have already written.
Cash on delivery is the whole design problem
In Egypt and across much of the Gulf a large share of parcels are paid in cash at the door. That single fact changes the system from a logistics tracker into something closer to a cash handling ledger that happens to have a map attached.
Think about what the driver is carrying by mid afternoon. Cash from a dozen deliveries, some partial payments, a refusal where the customer looked at the item and declined, and a parcel they could not deliver because nobody answered. Each of those is a different money state, and if your schema only knows delivered and not delivered, the office is reconstructing the day from WhatsApp messages.
So model the money explicitly: expected amount, collected amount, currency, who holds it now, and when it moved from driver to supervisor to bank. The transfer from driver to the office is a transaction in its own right and it needs a record, a timestamp and a person attached, because this is the point where disputes happen and where losses hide.
A related trap: partial collection. A customer takes two items of three and pays for two. If the system cannot represent that, drivers will record the delivery as complete and settle the difference informally, which is exactly the behaviour you built the system to remove.
The driver app has one hard requirement
It has to work with no connection. Not degrade gracefully, not show a spinner. Work. Deliveries happen in basements, in lifts, in industrial areas and inside buildings with thick walls, and the moment a driver cannot record a delivery without signal they will stop recording deliveries at the door and batch them from memory in the evening. Your timestamps then become fiction, and timestamps are most of what you were buying.
That means local storage on the device, a queue of pending actions, and a sync that survives the app being killed. It also means conflict rules decided up front: if the office reassigns a stop while the driver is offline and the driver then marks it delivered, you need a stated winner rather than whichever write arrives last.
Keep the screen count low for the same reason. A driver with twenty five stops is working one handed in traffic. The common case, arrive and deliver and collect the exact amount, should be two taps. Everything else can be slower.
What the tracking layer actually gives you
If you use a hosted tracking service rather than building location handling yourself, read its defaults before you design around it, because they set the resolution of everything you can promise a customer. Google's fleet tracking reference for its Last Mile Fleet Solution is specific about them.
The delivery vehicle location provider polls on a default interval of 5000 milliseconds, which the documentation describes as the minimum: "If you set the polling interval to a lower non-zero value, 5000 is used." Setting it to zero does not mean faster, it disables recurring updates. Stale positions are hidden rather than shown as current, and that threshold "Defaults to 24 hours in milliseconds".
There is also a gotcha in the fleet view worth knowing before you spend a day debugging an empty map: the documentation states that "If no bounds are set, no delivery vehicles will be tracked", and suggests setting bounds equivalent to the entire earth if you want everything. An empty map is the documented default, not a bug.
What a customer facing tracking page can actually show is also documented rather than a matter of taste. The Fleet Engine delivery API reference describes a task tracking call that returns the vehicle's last reported location, a route polyline to the task, estimated arrival and completion times, and the task's state and outcome. That list is a good specification for your own tracking page even if you build the location handling yourself: those are the fields a customer asks about, and nothing more.
The practical point is that a five second floor on position updates is plenty for a customer facing arrival estimate and nowhere near enough to adjudicate a dispute about whether a driver stopped at an address. If you need the second thing, you need proof at the door, not a better map.
Proof of delivery, and what it is worth later
Capture proof as though you will need it in three months in front of somebody unhappy, because that is when it gets used. A photo of the parcel at the door, a name, a timestamp and a position are usually enough. A signature scrawled on a phone screen is the weakest of the options and the one clients ask for most.
| Piece | What it answers | What it costs you |
|---|---|---|
| Live map | Where is my parcel now | Cheapest, and the least disputed |
| Driver app offline queue | Did this happen, and when | Real engineering, non negotiable |
| Photo proof at the door | Was it actually delivered | Storage, and a retention policy |
| Cash ledger per driver | Where is the money | Hardest, and the reason to build |
| Route optimisation | Could the day be shorter | Last, and often not worth it |
The bottom row is the one to resist early. Route optimisation is appealing, it demos well, and it is the piece most likely to be ignored in practice because drivers know their areas and will reorder stops regardless. Get the record of what happened correct first. Optimising a day you cannot yet measure is premature.
Where this connects to what you already run
This system is never standalone. Orders arrive from somewhere, usually a shop or an order management system, and the delivery outcome has to go back there so customer service can see it. That integration is the part that gets underestimated: it is covered in API integration between two systems, and what it really costs.
If the orders come from several channels, the shape of the problem upstream is the same one described in a restaurant order management system: the channels disagree, and somebody has to decide which one is authoritative. And if what you have today is a spreadsheet per driver, internal tools for a small business, and when to stop using Excel is the honest read on whether it is time yet.
One more thing that bites later than you expect. Delivery records accumulate fast, a photo per stop faster still, and the queries that were instant in month one are the ones that time out in month eighteen. Why does my web app get slower as data grows is the companion to that, and the fix is cheaper to design in than to retrofit.
The honest limits
There is no figure here for how much a tracking system reduces failed deliveries, because we do not have one worth citing. The numbers in circulation come from vendor material without a published method, and quoting one would make it a target for a team that has not measured its own baseline. Measure your current failed delivery rate for a month before you build, and you will have the only number that matters for your own operation.
Two cases where you should not build this. If you hand everything to a third party carrier, you are buying their tracking, not building your own, and the decision you actually face is which carrier, which is a different question: kfagency has a piece on the selection criteria for Egyptian stores, best shipping companies for stores in Egypt, which is in Arabic. And if you run five drivers who all report to one person in one room, the spreadsheet is genuinely fine and the system would be overhead.
Last caveat. The hardest part of this project is not technical, it is that the system makes driver performance visible for the first time. That is the point, and it is also why adoption fails when it is introduced as surveillance rather than as the thing that ends the evening argument about cash. How that lands is decided before any code is written.
Describe it. We build it.
Seven or twelve days, pay on delivery, a year of maintenance included. Bring the problem, not a spec.
Book a meetingRead next
A field service job tracking app, and what the phone must do
A field service job tracking app: the two facts the office is chasing, why the phone must work with no signal, and why photos break the naive offline plan.
ReadShipping faster without hiring, and where the weeks actually go
How to speed up software development without hiring more developers: where the weeks actually go, what DORA publishes about batch size, and what to cut.
Read