
A logistics or distribution platform phase one runs 1,550 to 2,760 hours, which is about $101,000 to $179,000 at a $65 blended rate, plus a stated 15 to 20 percent contingency rather than padding hidden inside the module numbers. Five people at around 600 useful hours a month puts that at three to five months.
A full platform — offline driver app, dispatch and multiple warehouses — runs roughly 2,500 to 4,700 hours, about $160,000 to $310,000. For reference, published market figures for a custom warehouse system of average complexity sit in the $200,000 to $400,000 range, so the upper half of our band is where a serious warehouse build lands.
The module that surprises people is not dispatch and it is not the warehouse. It is the offline driver app, at 400 to 700 hours, because the requirement is not "an app for drivers" but "an app that is correct when there is no signal and reconciles when there is". That is a distributed systems problem wearing a delivery uniform.
Most quotes for this work price the screens. The screens are the cheap half. What costs money is that a van, a warehouse and a retailer portal all hold a version of the same truth at the same time, and somebody has to decide which one wins.

Module | Published range |
Platform foundations | 300 to 500 h |
Product catalogue | 180 to 320 h |
Order management | 320 to 560 h |
Warehouse basics | 400 to 700 h |
Dispatch and route | 300 to 560 h |
Offline partner or driver app | 400 to 700 h |
Retailer portal, reporting and the first integration | 440 to 880 h |
Phase one | 1,550 to 2,760 h |
Note what the last row includes: the first integration, singular. The second and third integrations are not free repeats, because each one brings a different vendor's API at your specific version, and that is where mid-build surprises come from.
Maintenance budgets at 15 to 20 percent of build cost per year, which matches the industry norm. On a $179,000 build that is $27,000 to $36,000 a year, and a plan that omits it is not a cheaper plan, it is an incomplete one.
A driver spends part of every day without a usable connection: inside a warehouse, in a basement car park, in a rural gap. The app has to keep working, which means it holds its own copy of the data and accepts writes against it.
That single requirement produces most of the 400 to 700 hours. Every write made offline is a claim that has to be reconciled later, and claims conflict: a driver marks a delivery complete while dispatch reassigns the same stop. Both actions were valid when made. Resolving them needs a rule — last write wins, driver wins, server wins, or a human decides — and that rule has to be chosen per field rather than per app, because "delivery completed" and "customer phone number" deserve different answers.
Then there is proof of delivery: a signature or a photo captured offline is a file that has to survive an app restart, upload when signal returns, and never be lost even if the device is replaced. And there is sequencing, because a stop completed at 14:10 and synced at 16:00 must appear in the record at 14:10.
None of that is visible in a wireframe, which is why "we need a driver app" is one of the cheapest sentences a buyer can say and one of the more expensive things they can buy.
There is a cheaper path worth considering before committing the hours. If your drivers genuinely always have signal, say in a dense urban operation on company handsets with a data plan, an online-only app is a fraction of the work and you can treat loss of signal as an error state rather than a supported mode. That is a real choice, not a corner cut, and the honest way to make it is to measure rather than assume: give three drivers a logging app for a fortnight and count the minutes offline on real routes. The answer decides whether you are buying a 150-hour app or a 700-hour one.
400 to 700 hours is the largest single module in phase one, and the word "basics" does a lot of quiet work.
It covers knowing what you hold, where it is, and what state it is in. That means locations rather than a single stock figure, because a case on a pallet in receiving is not available to pick in the same way as one on a shelf. It means receiving against a purchase order with a discrepancy path, since what arrives and what the paperwork says differ often enough that the exception is a normal flow rather than an error. And it means stock movements as events rather than edits to a number, for the same reason a ledger records entries: a count that disagrees with the system has to be investigable.
Where it stops being basics is batch, expiry and temperature. Food, pharmaceutical and chemical distribution need lot tracking with expiry-driven picking rules, and a cold chain needs the temperature record to be part of the stock record rather than a separate log. Each of those pushes you toward the upper end of the range, and each is far cheaper designed in than added once stock already exists in the system.
The test for your own scope is simple: ask whether two units of the same product are ever meaningfully different from each other. If they are — different lot, different expiry, different condition — you need the identity model from day one.
"Dispatch" on a requirements list usually means a map. In the estimate it is three separate things that happen to share a screen.
Assignment decides which order goes to which person or vehicle, against skills, capacity, vehicle type and shift. Routing sequences the assigned stops, which is a genuinely hard optimisation once time windows and vehicle constraints enter it. Tracking reports what is actually happening against the plan, which is the part customers see and the part that needs the driver app to be honest.
Most operations need all three but do not need all three to be sophisticated. A business with thirty stops a day and one depot gets further with good assignment and a sensible manual route than with an optimiser nobody trusts. The optimiser is the right purchase when the number of feasible routes exceeds what a dispatcher can hold in their head, and that threshold arrives later than vendors suggest.
A worked example of why the local shape of the problem changes the build. Building Al Amri Express, which delivers groceries across Oman, we hit an assumption buried in almost every routing stack.
Oman's addressing standard excludes a location-based postcode. The codes in circulation belong to post office boxes, and street names are only unique within a wilayat. So the pin drop becomes the primary key and the text is commentary. Zones get drawn as polygons rather than looked up from a code table, and the landmark a customer types is a field the rider reads verbatim rather than a thing the system parses.
A second market-shape question usually follows it: whether an address is a place or a person. In operations where the customer meets the driver at a landmark, or where the same building has no unit numbers, the delivery point is effectively a conversation rather than a coordinate, and the app has to support that rather than treat it as bad data.
That is not a localisation task bolted on at the end. It changes the address model, the zone model and the route input, which is to say it changes three modules at once. Ask early which of your markets has an addressing scheme your software can actually depend on, because the ones that do not will not announce themselves until the first delivery fails.
The most useful economic fact we learned on that build has nothing to do with software architecture, and it should shape what you build first.
Picking, packaging and rider time are near fixed whether the basket holds three items or twenty. Contribution scales with basket size, while cost scales with order count. That inverts the instinct to chase order volume: two small orders cost roughly twice one large one and earn considerably less.
The levers that follow are specific. Batch picking, so one trip through the warehouse serves several orders. Drop clustering, so one rider journey serves several stops. And slot capacity set by picking throughput rather than rider headcount, because the warehouse is usually the real constraint and sizing slots to riders quietly oversells the picking line.
Each of those is a software feature with a direct margin consequence, which makes them the right things to build in phase one and the things most commonly deferred to phase two.
It also reframes the reporting you ask for. Cost per order is the number most operations track and the least useful of the three, because it barely moves whatever you do. Contribution per order and orders per picking hour move, respond to the levers above, and tell you whether a change worked. Build those two before anything prettier, and put them where the operations lead sees them daily rather than in a monthly pack.
Where cash on delivery is normal, the money model changes shape, and it changes it in the data rather than the interface.
Two specifics from the same build. The Omani rial carries three decimal places, so money must be stored in integer minor units with an exponent of three; anything defaulting to two truncates silently, with no error and a slow drift nobody can reconcile. And cash makes refusal partial: a shopper rejects one substituted item, not the whole order, so the door needs per-item accept and reject that reprices collection on the spot.
That second one is the part that reaches back into every other module. If an order can change value at the door, then the order is not final at dispatch, the driver app needs to carry prices rather than just a list, and reconciliation has to account for the difference between what was dispatched and what was collected — per item, per stop, per driver, per day.
The customer-facing app gets the attention and the warehouse app is the harder half.
On Al Amri we built a separate staff application with access split across admin, packer and delivery, where orders move through picking, packing and ready-for-dispatch with staff assignment and dispatch tracking. Three roles, one application, and the roles are not a permissions decoration — they are three different jobs with three different screens, three different error cases and three different definitions of "done".
A packer's done is a sealed order matching a list. A driver's done is a customer holding goods and money changing hands. An admin's done is a day that reconciles. Build one screen with role-based hiding and you get an interface that is wrong for everyone; build three and the hours go up but the operation actually adopts it.
The sequencing that worked was shipping the customer app first and the operations app after, so each entered production against something stable. That is worth copying, with one caveat: it only works if the data model for both was designed together, because the operations app is where every shortcut in the order model becomes visible.
Three categories, each worth confirming before a quote is accepted.
Hardware and the physical layer. Scanners, label printers, mounts, device management and replacement devices are capital and operating costs that live outside a software estimate entirely.
Devices deserve a sentence of their own, because they are the line operations teams most often discover late. A rugged handset costs several times a consumer one and lasts far longer in a warehouse; a consumer handset is cheaper to buy and becomes a running replacement cost plus the support burden of a driver whose screen has failed mid-round. Neither is wrong, but the choice belongs in the business case rather than in a procurement conversation three weeks before go-live.
Integrations beyond the first. The published band includes one. Each additional ERP, accounting system, carrier or marketplace is its own piece of work, sized by that vendor's API at your version rather than at the version in the documentation.
The contingency, which we state rather than hide. 15 to 20 percent on top, because in this sector the unknowns are operational — what the floor actually does, in what units — and they surface during build rather than during discovery, however good the discovery was.
Not in the warehouse module, which is well understood and well specified.
They fail when the offline driver app was scoped as a mobile front end and turns out to be a synchronisation problem, discovered at the point where two valid writes conflict and nobody has decided which wins. They fail when the addressing model assumed a postcode that does not exist in the market, so zones, routes and delivery proof all inherit an identifier that cannot be relied on. They fail when slot capacity was sized against riders rather than picking throughput, so the business sells more deliveries than the warehouse can prepare and the failure arrives as late orders rather than as a capacity alert.
And they fail on units. Discovery on distribution software is mostly an inventory of what the floor already does and in what units — cases or pieces, pallets or cartons, kilograms or units, per-stop or per-order. A system that encodes one answer where the business uses two will produce numbers that are internally consistent and operationally wrong, which is the hardest class of bug to find because nothing crashes.
Phase one runs 1,550 to 2,760 hours across seven modules, which is about $101,000 to $179,000 at a $65 blended rate, plus a stated 15 to 20 percent contingency. A full platform including an offline driver app, dispatch and multiple warehouses runs roughly 2,500 to 4,700 hours, about $160,000 to $310,000. Published market figures for a custom warehouse system of average complexity sit in the $200,000 to $400,000 range. Maintenance budgets separately at 15 to 20 percent of build cost per year.
Because the requirement is not an app for drivers, it is an app that stays correct without a connection and reconciles when one returns. Every offline write is a claim that may conflict with another valid action — a driver completing a stop that dispatch reassigned — and resolving those needs a rule chosen per field rather than per app. Proof of delivery captured offline has to survive restarts and device changes, and events must appear in the record at the time they happened rather than the time they synced. That is 400 to 700 hours of distributed systems work.
Three things that share a screen. Assignment decides which order goes to which person or vehicle against skills, capacity and shift. Routing sequences the assigned stops, which becomes a hard optimisation once time windows and vehicle constraints apply. Tracking reports actual progress against the plan. Most operations need all three but not all three sophisticated: with thirty stops and one depot, good assignment plus a sensible manual route beats an optimiser nobody trusts.
Five people at around 600 useful hours a month puts phase one at three to five months. The hours set the calendar and a deadline cannot shrink them, so a shorter date is met by moving modules out of phase one rather than by working faster. What actually paces these projects is operational rather than technical: establishing what the floor does today and in what units, and getting API access to the systems the platform must integrate with at the version you actually run.
Hardware and the physical layer — scanners, printers, mounts, device management, replacement devices — which are capital and operating costs rather than software. Integrations beyond the first, since the published band covers one and each additional system is sized by that vendor's API at your version. And the contingency, which we state at 15 to 20 percent on top rather than hiding inside the module numbers, because the unknowns in this sector are operational and surface during the build.
Because routing stacks assume a postcode, and not every market has one. Oman's addressing standard excludes a location-based postcode: the codes in circulation are post office routing codes, and street names are only unique within a wilayat. So the pin drop becomes the primary key, zones are drawn as polygons rather than looked up, and the customer's landmark text is read by the rider rather than parsed. That changes the address model, the zone model and the route input together, which is three modules rather than a localisation task.
On Al Amri Express the customer app shipped first and the operations app followed, so each entered production against something stable, and that sequencing is worth copying. The caveat is that both data models have to be designed together from the start, because the operations app is where every shortcut in the order model becomes visible. The warehouse half is also the harder half, so a plan that treats it as a phase two add-on is usually underestimating the whole project.

Vikas has around fifteen years of experience building software and now builds generative AI systems at Zyneto. His work covers retrieval augmented generation, agentic AI, knowledge graphs, AI memory, and the evaluation and guardrails that decide whether any of it is safe to put in front of customers. He has shipped enterprise copilots, document AI, chatbots and predictive analytics for e-commerce, fintech and marketing teams, and works day to day in Python, JavaScript and SQL. He follows multimodal models, business process automation and enterprise AI security closely, and mentors engineers moving into AI. He writes about architecture, inference cost and the failure modes that only show up at production scale.
Share your details and we will talk soon.
Be the first to access expert strategies, actionable tips, and the trends actually shaping the digital world. No fluff - just practical insights delivered straight to your inbox.
Dive into our blog and stay ahead of the curve with expert perspectives, future-ready trends, and tech tips written for decision-makers and doers alike.