Back to Blog

On-Demand Delivery Platform Development: How to Build Scalable Infrastructure for Restaurants and Retail

Dima Kasperovich,  | dev.family
Dima Kasperovich
lead backend developer

Jul 22, 2026

13 minutes reading

On-Demand Delivery Platform Development: How to Build Scalable Infrastructure for Restaurants and Retail - dev.family

A delivery app that runs 50 orders a day looks finished. Couriers get assigned, customers watch a little icon move across a map, orders land on time. Then the same business hits 500 orders a day, and the exact same architecture starts to buckle: couriers get routed to the wrong address, order status lags behind reality, and the menu you publish to three aggregators quietly drifts out of sync. None of that is bad luck. Those failures were designed in on day one, because the system was never built for the load it eventually carried.

On-demand delivery platform development is the work of building infrastructure that survives its own growth. This article breaks a delivery platform into five architectural layers that decide whether it scales or snaps: routing and dispatch, real-time tracking, dispatcher tooling, aggregator integration, and offline resilience. Most teams bolt these on after the pain starts. We'll walk through each layer for both restaurants and retailers, using a public industrial benchmark — DoorDash's own dispatch architecture — as the north star, and our own production builds as honest, mid-market reference points.

Why the second layer is the one that breaks

The order-taking layer is the easy part. A checkout flow, a payment provider, a catalog — these are solved problems, and a competent MVP nails them in weeks. What separates a demo from a platform is everything that happens after the tap on "Place order": deciding who carries it, keeping every party honest about where it is, and holding the whole thing together when a courier drives into a dead zone or a store's Wi-Fi drops.

Those systems rarely get engineered up front because they don't hurt at low volume. A dispatcher can eyeball ten open orders and assign them by hand. Polling the server every few seconds for order status feels instant when a hundred people do it. One aggregator is easy to keep in sync manually. Scale multiplies each of these into a genuine engineering problem at roughly the same time, which is why growth-stage delivery teams tend to hit a wall all at once rather than gradually.

The reader this article is written for has usually already felt the first tremor: an MVP built by an outsourced team, a "nearest available courier" rule that made sense at launch, order status wired through polling — all working, all starting to strain. The goal here is to lay out what the mature version of each layer looks like, and, just as importantly, what you realistically need to build at your current stage versus what can wait.

Routing & Dispatch Logic — what actually decides who carries the order

Dispatch is the decision engine of a delivery platform: given an open order and a pool of couriers (or pickup locations), who takes it, and in what sequence? Get it wrong and you produce the two classic failure modes — a courier who arrives before the food is ready and burns paid minutes waiting, or one who arrives late and hands over a cold order. At volume, you also want to batch: group two or three orders leaving the same kitchen or neighboring stores onto one courier run without wrecking anyone's delivery window.

It helps to think about dispatch as a maturity ladder rather than a single feature you either have or don't.

The first rung is manual or map-assisted dispatch. A human looks at a map, sees which orders are geographically close, groups them, and hands the batch to whoever is next in line. This is exactly how our rider operation for Sizl, a Chicago dark kitchen network, works today: in the bundling view, a packer sees ready orders and available riders side by side, uses a map to group nearby addresses into an efficient bundle, and assigns it manually. We plan to automate that grouping later — for now the manual step is deliberate, because it lets the team watch where real bottlenecks form before hard-coding rules around them. That honesty matters: this is a working, mid-market solution, not automated optimization, and pretending otherwise would set the wrong expectation.

<span>Routing &amp; Dispatch Logic — what actually decides who carries the order</span>

The second rung is rule-based batching — encoding the packer's judgment into deterministic rules (same kitchen, within X minutes of each other, within Y meters, cap of Z orders per run). It removes the human from routine decisions while staying predictable and cheap to reason about. The reason batching is worth the trouble is that it directly attacks the early/late tradeoff: a courier who leaves with two orders bound for the same block spends less idle time and covers more drops per hour, as long as the second order doesn't cool while the first is delivered. Encode the wrong rule — batch too aggressively — and you trade a small routing win for a customer holding a lukewarm bag. That balance is exactly why the jump to the next rung is about math, not willpower.

The top rung is ML plus optimization, and the clearest public example is DoorDash's DeepRed system, which the company describes in detail on its engineering blog (first published in August 2021 and updated in April 2025, so it reflects a maintained system rather than a one-off snapshot). DeepRed is a two-layer design: machine-learning models estimate order-ready time, travel time, and the probability a courier accepts an offer; then a mixed-integer optimization model — solved with the commercial Gurobi solver — makes the final assignment and batching decision, with the market partitioned into geographic zones to keep the computation tractable. This is not DoorDash-specific exotica. Uber's research team describes the same class of real-time matching and dynamic-pricing algorithms for ride-hailing, and the underlying task has a name in the literature — the Vehicle Routing Problem — with tooling as standard as Google's OR-Tools routing library, which handles multi-stop batching under capacity and time-window constraints out of the box.

Which rung you need depends on order density and the number of pickup points, not on ambition. A retailer running its own last-mile delivery from a handful of stores and a restaurant chain feeding a few kitchens face the same question in the same order: start where the volume actually is, and climb only when the numbers justify the added complexity.

The choice to run your own delivery starts one level up, with the question of who physically dispatches it — the operational side we unpack separately. And the dispatch layer never lives alone; how it connects to the rest of the restaurant stack shapes what you can realistically automate later.

Take back control of your last-mile delivery

Automate routing and in-app tracking to boost margins and stop sharing revenue with aggregators

Ghost Kitchen Software: Why Running 3 Brands Out of One Kitchen Breaks Standard Restaurant Tech - dev.family

Ghost Kitchen Software: Why Running 3 Brands Out of One Kitchen Breaks Standard Restaurant Tech

This piece breaks down where multi-brand operations fail in the POS, aggregator menus, kitchen view, and merchant portal, with the same mid-market honesty

Real-Time Tracking — sockets, not polling

Every delivery app promises live tracking. Far fewer implement it in a way that holds up. The common shortcut is polling: the client asks the server "any update?" on a fixed interval. At low volume it feels fine. At scale it drains device batteries, floods the server with requests that mostly return "nothing changed," and still lags — the update you see is only as fresh as the last poll.

Production delivery apps use a persistent WebSocket connection instead, pushing changes to the client the moment they happen. Ably, a realtime-infrastructure provider, lays out the technical case cleanly in its comparison of long polling and WebSockets (May 2025): a persistent connection cuts latency and server load relative to periodic polling as the number of connected users climbs. That advantage applies to both directions of tracking — pushing order-status changes to the customer, and streaming the courier's live location onto a map.

We made exactly this move on Yapoki, a high-volume food delivery app (20k+ downloads, 200+ orders a day, 35% of the brand's total order share). Order status runs over sockets so customers can follow preparation live rather than refreshing for updates, and the delivery screen shows the courier's movement on a map, updated in real time. There was an honest wrinkle worth naming: an early version of the geocoder hit a ceiling of 200 address lookups per day, which forced rework once volume grew — the kind of limit you only discover in production, and the reason tracking infrastructure deserves load-testing before you need it.

<span>Real-Time Tracking — sockets, not polling</span>

On the courier side, our Sizl rider app syncs live rider geolocation to an in-app map that updates automatically while the rider is en route. Across these builds the geolocation toolkit is deliberately boring and proven: Mapbox, Google Maps, and OpenStreetMap.

<span>Real-Time Tracking — sockets, not polling</span>

For a retailer, none of this changes shape. A customer waiting on a same-day grocery or pharmacy order wants the same live status and the same map that a restaurant customer does, and the same socket architecture serves both.

Choosing the right monitoring and tracking tools for operational processes is its own discipline — our simple guide to setting up a monitoring system walks through it. Tracking is also usually the first thing to buckle at scale; what happens when order tracking can't keep up with a growing network is the cautionary version of this section.

Dispatcher Tools & the Merchant/Ops Side

Almost all the design energy in a delivery product goes into the consumer app — the part investors and customers see. The dispatcher and ops panel, the interface a station manager or operations lead actually uses to keep deliveries on time, tends to get built last and cheapest. That order of priorities is backwards, because the ops panel is where on-time delivery is won or lost.

The Sizl rider admin panel is a concrete example of what this layer looks like in production. An order moves through a visible pipeline — confirmed, cooking, bundling, handed to a rider. When a rider reaches the station, they tap "Ready to Go," which flips their status in the panel so the packer knows exactly who's next in line. The packer assembles the bundle and hands it off. The whole point is that no one wastes time guessing: the kitchen, the packer, and the rider are looking at the same live state.

<span>Dispatcher Tools &amp; the Merchant/Ops Side</span>

As covered in the dispatch section, the bundling itself is a manual operation here — the packer groups nearby orders using a map view, and automation of that step is on the backlog. This is worth restating plainly rather than dressing up: at Sizl's current volume, manual bundling is a deliberate choice that surfaces bottlenecks, and it sits on a different rung of the maturity ladder than DoorDash's fully automated dispatch. The two solve the same problem at deliberately different scales.

A retailer running its own delivery needs the identical thing under a different label: a panel where store staff see the queue of orders, mark them ready, and release them to whoever is carrying them. The vocabulary changes; the workflow does not.

The ops panel is also where money quietly leaks — where exactly in the delivery operation it disappears is worth reading before you optimize anything. And keeping the customer, courier, and operator apps in a single repository is what lets a small team maintain all three at once, which is why we spend the time on a monorepo for large digital ecosystems.

Automating Delivery, Inventory & Orders in Dark Kitchens - dev.family

Automating Delivery, Inventory & Orders in Dark Kitchens

This piece goes one level deeper into the automation layer underneath

Aggregator Integration Without Menu/Order Drift

Most restaurants and many retailers don't sell through a single channel. They run their own app and list on aggregators — Wolt, DoorDash, Uber Eats, Glovo, Grubhub for restaurants; various marketplaces for retail. The technical trap is that each platform exposes a different integration model. Some push order events to you via webhooks; others expect you to poll them. Menu and catalog updates propagate at different frequencies. Left unmanaged, the result is drift: an item marked out of stock in your POS is still orderable on one platform, a price change lands on two channels but not the third, and customers order things you can't fulfill.

The architectural answer is a dedicated menu- and catalog-management layer that sits above your POS or product catalog and treats every sales channel as a downstream target it keeps in sync — rather than syncing each channel by hand. The principle is identical whether the downstream targets are restaurant aggregators or retail marketplaces.

Two differences between platforms are worth designing around explicitly. The first is how orders arrive: a webhook-based platform pushes each new order to your endpoint the instant it's placed, so your integration has to be a reliable listener that acknowledges and retries; a poll-based platform expects you to ask for new orders on a schedule, which means you own the polling cadence and the deduplication logic. The second is update frequency: item availability and price changes propagate at different rates on different platforms, so a "sold out" flag that's instant on one channel may lag on another. A management layer normalizes both — one internal representation of the catalog, one place that decides what "available" means, and per-channel adapters that translate that truth into each platform's format and timing. For a retailer syncing thousands of SKUs across marketplaces, that normalization is the difference between clean reconciliation and a nightly spreadsheet cleanup.

For the physical delivery itself, there's a parallel integration pattern worth knowing. Instead of hiring a courier fleet, a merchant can call an external logistics provider by API. DoorDash publishes developer documentation for DoorDash Drive, a white-label service that dispatches a DoorDash courier through a single API call, no fleet required — and it's built for non-restaurant use cases too, including pharmacies and retail stores, not just food. In our own stack we lean on a delivery-orchestration platform (Nash) to abstract this layer rather than wiring each logistics partner separately, which keeps the integration surface small as channels multiply.

If the integration layer itself is unfamiliar, how an order aggregator is actually built on the technical side is a useful primer, and how the same external-platform integration principle plays out in the grocery vertical shows it isn't restaurant-specific.

Creating a customized platform for online ordering

Offline Resilience — what happens when the network drops

A delivery platform that assumes constant connectivity has a hidden single point of failure: the network. Connectivity is not guaranteed for a courier working a route, and it's not guaranteed at a point of sale in a basement stockroom either. A cloud-only design simply stops working the moment the signal does, at exactly the moment when work is happening.

Offline-first architecture flips the default. The courier app keeps functioning without a connection — accepting statuses, capturing proof of delivery — and syncs automatically when the signal returns. On the Sizl rider app this is a shipped feature, not a plan: riders can take a delivery-confirmation photo with no internet, the app stores it locally, and it syncs on its own once connectivity is back. The driver behind building it was blunt and specific — in the team's own words, "some areas in Chicago have spotty internet." The pattern underneath is a local-first approach, built with React Native and RxDB. The term "local-first" itself traces back to the canonical 2019 essay from the Ink & Switch research lab, which named and framed the category.

<span>Offline Resilience — what happens when the network drops</span>

For retail, the same resilience shows up in the store: an in-store fulfillment app that keeps letting staff pick and confirm orders during a connectivity blip, then reconciles when the network recovers, protects the operation the same way the courier app does.

For the implementation detail — how the offline-first layer of a courier app is built technically — we've written it up separately, and what fault tolerance means at the level of the whole platform, not just the courier app, extends the same idea end to end.

The five-layer stack, and when to build custom

Pulling the layers together, a delivery platform built to scale has a recognizable shape:

Layer

What it does

Typical tooling / pattern

Order Intake

Accept orders from app, web, aggregators

POS / catalog + checkout

Routing / Dispatch

Decide who delivers what, in what order; batch nearby orders

Manual → rule-based → ML + optimization (VRP)

Real-Time Tracking

Push order status and courier location live

WebSocket connection; Mapbox / Google Maps / OpenStreetMap

Dispatcher / Ops Panel

Let staff manage the live order queue and hand-offs

Merchant/ops web panel synced to kitchen/store

Aggregator Integration

Keep menu/catalog and orders in sync across channels

Menu-management layer over POS; delivery orchestration (e.g., Nash)

Offline-First Client

Keep courier/store apps working without a connection

Local-first (React Native + RxDB), auto-sync

The harder question is how much of this to build yourself. Off-the-shelf is genuinely enough for some operations. If you run a single sales channel, connect to one or two aggregators or marketplaces, and your order volume doesn't require batching, a ready-made orchestration platform plus standard dispatch will carry you — building custom infrastructure would be over-engineering.

The threshold for custom development is specific. It's worth it when you're running three or more aggregators or channels at once and need a single merchant portal to manage them; when order density has grown to the point that ML-assisted dispatch actually pays for itself; or when offline resilience is operationally critical because your couriers work zones with weak connectivity. Those are the conditions under which a generic stack starts costing you more in workarounds than a custom build would cost to develop.

Wanna talk about your problem right now?

Write to us – we know how to help!

FoodTech MVP Development: Idea to Investor-Ready in 12 Weeks - dev.family

FoodTech MVP Development: Idea to Investor-Ready in 12 Weeks

Here's what that looks like in practice, with the Sizl rebuild as the reference case

FAQ

AnnaS, Business Development Manager - dev.family

Ready to offer digital native purchasing? Boost online sales and expand coverage. Book a free consultation

Anna S., Business Development Manager




You may also like: