3.17 Billion Orders a Year

In 2025, DoorDash handled 3.17 billion orders and $102 billion in Marketplace GOV (the total value of orders on its platform), according to its annual report. Every one of those orders means a customer, a merchant and a Dasher (driver) have to come together at roughly the right moment. The food shouldn't wait on a counter, and the Dasher shouldn't wait for the food.

This post explains how DoorDash's system is built, based on what its engineering team has published: the move off a monolith, the services behind checkout, and DeepRed, the dispatch engine that decides which Dasher gets which order.


🎯 Quick Answer (30-Second Read)

  • Started as: one Django app on a single PostgreSQL database.
  • Now: microservices, standardised mainly on Kotlin, talking over gRPC, with Kafka for events and Cassandra where checkout needs scale.
  • DeepRed (dispatch): ML models predict prep time and travel time, then a mixed-integer optimisation model decides which orders to offer to which Dashers.
  • Routing: an NP-hard problem, solved fast with a ruin-and-recreate heuristic split up by region.
  • Scale (2025): 3.17B orders (+23%), $102.0B Marketplace GOV (+27%), $13.7B revenue.

DoorDash in Numbers (2025)

3.17B
orders (+23%)
$102B
Marketplace GOV (+27%)
$13.7B
revenue
~8.7M
orders per day on average
xychart-beta title "DoorDash total orders (millions)" x-axis ["2023", "2024", "2025"] y-axis "Orders (M)" 0 --> 3500 bar [2161, 2583, 3172]

The 2025 figures include DoorDash's acquisition of Deliveroo. Excluding it, Marketplace GOV grew 23% rather than 27%.


High-Level Architecture

flowchart TB subgraph Apps["Client apps"] CA["📱 Customer app"] MA["🏪 Merchant tablet / POS"] DA["🛵 Dasher app"] end CA --> GW["API gateway / BFF"] MA --> GW DA --> GW GW --> CAT["Store & menu service"] GW --> CO["Checkout service
(Kotlin, Cassandra)"] CO --> PAY["Payments"] CO --> K[["Kafka: order events"]] K --> MER["Merchant order service"] K --> DR["DeepRed dispatch"] DR --> ML["ML estimates
prep time, travel time"] DR --> OPT["Optimiser
(mixed-integer program)"] OPT --> OFFER["Offer to Dasher"] OFFER --> DA DA --> LOC["Location updates"] LOC --> DR LOC --> TRACK["Live tracking for customer"]

1. From Monolith to Microservices

DoorDash began like many startups: frontend and backend in one Django application backed by one PostgreSQL instance. That's the right choice early on, because it's fast to build and simple to run.

As orders grew, the monolith became a bottleneck. One bad deploy could take everything down, and hundreds of engineers were working in the same codebase. Interestingly, the first service DoorDash pulled out, in 2014, was DeepRed, the logistics AI. Dispatch was the most specialised and compute-heavy part.

A full re-architecture started around 2019:

  • Early services were written in Python 3, Kotlin, Java and Go
  • DoorDash then standardised on Kotlin: JVM performance with null safety and coroutines
  • In 2020, the checkout flow moved out of the monolith into a Kotlin service using Cassandra, Kafka, Cadence (workflows) and gRPC
  • Hard parts included shared sessions: during migration, some pages were still served by the monolith, which could create two session IDs for one user

(For the general trade-offs, see Microservices Architecture Explained.)

Key takeaway: DoorDash didn't start with microservices. It split off the part with the most distinct needs first (dispatch), then moved the rest gradually once the monolith was really holding the company back.

2. Placing an Order

sequenceDiagram participant C as Customer app participant CO as Checkout service participant P as Payments participant K as Kafka participant M as Merchant participant D as DeepRed C->>CO: Place order (cart, address, tip) CO->>CO: Validate menu, prices, store hours CO->>P: Authorise card P-->>CO: Authorised CO->>K: OrderCreated event CO-->>C: Order confirmed K->>M: Send to restaurant tablet K->>D: Add to dispatch pool M-->>K: Order accepted, prep started

Checkout must never charge twice or lose an order, even when a phone retries on a flaky network. That's why requests carry idempotency keys (Idempotency Explained) and why downstream work runs off events (Message Queue Explained) instead of one long chain of synchronous calls.


3. DeepRed: The Dispatch Brain

Dispatch is DoorDash's hardest problem. Assign a Dasher too early and they wait at the restaurant. Too late and the food goes cold. It also has to work across thousands of stores and Dashers at the same moment.

DoorDash describes DeepRed as two layers:

flowchart LR subgraph L1["Layer 1: ML predictions"] P1["Food prep time"] P2["Dasher travel time"] P3["Chance a Dasher accepts"] end subgraph L2["Layer 2: optimisation"] MIP["Mixed-integer program
(solver: Gurobi)"] end L1 --> MIP MIP --> DEC["Which order goes to which Dasher,
and whether to batch orders"]
  1. Predict: ML models estimate how long the restaurant will take, how long each Dasher needs to get there and deliver, and how likely they are to accept.
  2. Optimise: a mixed-integer optimisation model takes all of that and decides the best set of offers across the region, balancing delivery speed, food freshness and Dasher efficiency.

The earlier system assigned one delivery at a time and treated it as bipartite matching (orders on one side, Dashers on the other). Moving to a mixed-integer program let DeepRed consider batching: one Dasher carrying two orders from nearby restaurants. DoorDash reported its new solver ran up to 10 times faster than the Hungarian algorithm it replaced, and the swap happened with zero downtime.


4. Routing at Scale

When a Dasher carries several orders, the order of stops matters. This is a version of the vehicle routing problem, which is NP-hard: no known algorithm finds the perfect answer quickly as the problem grows.

DoorDash's approach:

  • Ruin and recreate: take a good route, remove a few stops, reinsert them in better positions, and keep the change if it improves things. Repeat many times
  • Shard by geography: each region is solved separately, so work runs in parallel
  • Multithreading to get good answers within seconds, since dispatch decisions can't wait

More recently, DoorDash re-architected real-time dispatch to split the global state into geospatial clusters. It has also written about using reinforcement learning to adjust the optimiser's goals in real time, for example during a dinner rush versus a quiet afternoon.


5. Live Tracking

The Dasher app sends location updates. These feed two things:

  • Back into DeepRed, so estimates and future assignments use real positions
  • To the customer's app, for the moving map and arrival time (WebSocket vs SSE)

The same pattern powers ride-hailing (Uber System Design), with one big difference: DoorDash also has to predict when the food will be ready, which a ride-hailing app never deals with.


Design Lessons

Challenge DoorDash's approach
Monolith slowing teams down Gradual move to Kotlin microservices
Checkout must be reliable Dedicated service, idempotency, Cassandra, Kafka events
Matching Dashers to orders ML predictions + mixed-integer optimisation
NP-hard routing Heuristics (ruin and recreate), sharded by region
Peaks like dinner rush Real-time tuning of optimiser goals

Frequently Asked Questions

What is DeepRed at DoorDash?

DeepRed is DoorDash's dispatch system. Machine learning models predict food preparation time, Dasher travel time and the chance a Dasher accepts an offer, then a mixed-integer optimisation model decides which orders to offer to which Dashers, including when to batch orders together.

What tech stack does DoorDash use?

DoorDash started with a Django monolith on PostgreSQL. It moved to microservices and standardised mainly on Kotlin, using gRPC between services, Kafka for events, Cassandra for services such as checkout, and Cadence for workflows. Some services were also built in Python, Java and Go.

How many orders does DoorDash handle?

DoorDash reported 3.17 billion total orders in 2025, up 23% from 2024, which averages to roughly 8.7 million orders a day. The 2025 figures include its acquisition of Deliveroo.


Conclusion

DoorDash's system is a logistics engine wrapped in a shopping app. A Django monolith became Kotlin microservices, checkout became a reliable event-driven service, and DeepRed combines ML predictions with mathematical optimisation to match billions of orders with Dashers. The hard part isn't taking the order. It's getting the right Dasher to the restaurant just as the food is ready.


Sources

Last verified: 2 November 2026.


Related reads: Uber System Design · How Swiggy Built Logistics Without Addresses · Microservices Architecture Explained · Message Queue Explained

I write about system design and how real products get built. Follow on LinkedIn or X, or invite me to speak.