Resource Estimation
In one line: the estimation has all the ingredients for the chapter's central number and never assembles them. Doing that one division is the most valuable thing in this lesson.
Assumptions
- 500 million total riders (20 million daily active)
- 5 million total drivers (3 million daily active)
- 20 million daily trips
- Active drivers update their location every four seconds
Three ratios worth noticing before any arithmetic
20 million daily active riders, 20 million daily trips. So the average active rider takes exactly one trip per day. Clean, and it means rider activity and trip volume are the same number.
3 million of 5 million drivers are active — 60%. Against riders, where 20 million of 500 million are active, or 4%. Drivers are an order of magnitude more engaged, which makes sense: it is their job.
Every 4 seconds, forever. This is the assumption that dominates the chapter, and it is qualitatively unlike the others. Riders and trips generate events; drivers generate a continuous stream. A driver sitting idle at a taxi rank still emits 900 updates an hour.
That third one is the tell. When one input is a rate rather than a count, it will dominate — check it first.
Storage
| Category | Calculation | Result |
|---|---|---|
| Rider metadata | 500M x 1,000 B | 500 GB (one-time) plus 500 MB/day for new riders |
| Driver metadata | 5M x 1,000 B | 5 GB (one-time) plus 100 MB/day for new drivers |
| Driver locations | 3M x 36 B | 108 MB |
| Trip metadata | 20M x 100 B | 2 GB/day |
| Total | 108 MB + 2 GB + 500 MB + 100 MB | 2.71 GB/day |
All of these reproduce exactly.
The 108 MB is a snapshot, and it is being summed as a daily rate
Look at what 3,000,000 × 36 bytes computes: one location record per active driver. That is the current position — the Driver_location table from Lesson 10, which is overwritten on every update, not appended.
So 108 MB is a standing size, like the 500 GB of rider metadata. It is not a daily accumulation, and adding it to a per-day total mixes a stock with a flow.
The magnitude of the confusion is worth computing. If every update were retained:
Updates per driver per day = 86,400 / 4 = 21,600 3,000,000 drivers x 36 B x 21,600 = 2.33 TB/day
21,600 times the published figure. The gap between "the latest position" and "every position" is four orders of magnitude, which makes it the most consequential modelling choice in the estimate — and it is never stated.
The error direction is benign: 108 MB is a rounding error against 2 GB of trips, so the 2.71 GB total is fine as arithmetic. But the habit matters. Check whether each line in a storage estimate is a stock or a flow before adding them, because the two are only comparable by accident.
Route traces are missing entirely, and they dwarf everything counted
Lesson 6 says the location manager "during trips, records the route taken." Lesson 5's updateDriverLocation API sends old and new coordinates specifically so "the service can reconstruct the route."
So routes are stored. And the storage estimate has no line for them.
15-minute trip = 900 s / 4 s = 225 points x 36 B = 8.1 KB per trip 8.1 KB x 20,000,000 trips = 162 GB/day
162 GB per day, against a published total of 2.71 GB. The omitted item is roughly 60 times everything counted.
The range is worth having, since trip length is a guess:
| Average trip | Route storage |
|---|---|
| 10 minutes | 108 GB/day |
| 15 minutes | 162 GB/day |
| 20 minutes | 216 GB/day |
Even the low end is 40× the published total, so the conclusion does not depend on the assumption.
This changes what the storage story is. The published estimate suggests a system storing a few gigabytes a day — trivially small, like Yelp. Including routes, it is tens of terabytes a year of append-only time-series data, which is a genuinely different workload and precisely what Cassandra is chosen for in Lesson 10.
Two mitigations a real system would use, worth mentioning: downsample completed routes, since 4-second granularity is needed live but not for a receipt, and compress — consecutive GPS points differ in only their last few digits, so delta encoding shrinks traces enormously.
Bandwidth
Trips: 20,000,000 / 86,400 = 232 trips/second
232 x 100 B x 8 = 185.6 kb/s
Drivers: 3,000,000 x (3 + 16) B = 57 MB per 4-second cycle
57 MB x 8 / 4 = 114 Mb/s
Total = 114.19 Mb/s
Both figures reproduce exactly.
Two different sizes for the same object
The storage section uses 36 bytes per location update. The bandwidth section uses 19 — a 3-byte driver ID plus a 16-byte location. Same object, 1.89x apart, two sections of one lesson.
Both are defensible in isolation. Nineteen bytes is a tight wire format: two 8-byte coordinates and a compact ID. Thirty-six is a plausible stored row with a timestamp and some padding.
But they should be reconciled explicitly, because they answer different questions — what goes on the wire versus what lands on disk — and a reader cannot tell whether the difference is deliberate or accidental.
If you meet this, say which you are carrying and why: 19 for bandwidth, 36 for storage, and the difference is serialization overhead. That is almost certainly the intent, and stating it is better than silently picking one.
114 Mb/s hides the number that actually matters
The bandwidth figure is small — 114 Mb/s total, less than a single server's network interface, and trivial beside YouTube's 12 Tb/s or Maps' 297 Gb/s.
That smallness is misleading, and here is why. The calculation performs 3,000,000 ÷ 4 to get a per-second rate, then multiplies by 19 bytes. The multiplication produces a comfortable number. The division produced an uncomfortable one, and it is never written down:
3,000,000 active drivers / 4 seconds = 750,000 location updates per second
Put that beside the other rate in the same lesson:
| Operation | Rate |
|---|---|
| Location updates | 750,000 / second |
| Trips | 232 / second |
| Ratio | 3,240 : 1 |
Three thousand two hundred location updates for every trip. That is the chapter's central quantitative fact, and everything difficult in the design follows from it:
- Lesson 7's quadtree problem — an index that must absorb 750,000 writes per second while being read for matches.
- The hash table decoupling current position from indexed position.
- Redis absorbing writes and flushing in batches.
- Updating the tree every 15 seconds rather than every 4 — which divides that write rate by 3.75, to 200,000 per second.
- Cassandra, chosen in Lesson 10 for exactly this write profile.
The bytes are trivial; the operations are not. Bandwidth measures volume, not rate — and when the objects are tiny, a colossal request rate can hide inside a small bandwidth figure.
Compare the previous two chapters, where the same trap ran the other way. ChatGPT's tiny bandwidth hid an enormous compute cost; Uber's tiny bandwidth hides an enormous write rate. In both, the standard template measured the wrong thing.
Number of servers
With 23 million total daily active users (20M riders, 3M drivers), we estimate peak load at 23 million requests per second, using our DAU-to-RPS proxy assumption.
23,000,000 / 64,000 = about 360 servers
The convention overestimates here — and lands near a plausible answer by accident
This is the course's DAU-as-RPS shorthand again, used identically in the Google Maps and Yelp chapters. As always it assumes every daily active user issues a request every second, all day.
What is interesting is that here it overestimates by less than usual, because this system genuinely does have a continuous stream:
DAU-as-RPS convention: 23,000,000 RPS -> 360 servers Coherent request rate: 750,231 RPS -> 11.7 servers
Still 31x apart, and the coherent figure is the honest one — 750,000 location updates plus 232 trip operations.
But a real fleet would be much larger than 12 servers, for reasons the arithmetic does not capture: WebSocket connections are held open for millions of concurrent users, which is a connection-count problem rather than a request-rate one; the quadtree, matching, ETA, and payment services scale independently; and location ingestion at 750,000 writes per second needs headroom for regional peaks.
So the honest summary is: 360 is roughly the right order of magnitude for the wrong reason. The convention accidentally lands near a plausible fleet size, and a candidate who reproduces it without the reasoning cannot tell that from luck.
Say the coherent number and then say why the real fleet exceeds it. The value of an estimate is the reasoning it exposes, not the number it produces.
Building blocks
| Block | Role |
|---|---|
| Cache | Stores frequently accessed data for low latency |
| Load balancer | Distributes requests across services |
| CDN | Delivers static content efficiently, reducing latency and server load |
| Databases | Store persistent metadata for riders, drivers, and trips |
Key takeaway
The estimate's published figures all reproduce, but two lines are wrong in kind: the 108 MB of driver locations is a snapshot summed as a daily rate (every update retained would be 2.33 TB/day), and route traces are omitted entirely at roughly 162 GB/day — 60x the published total. The same update is 36 bytes in storage and 19 on the wire. Most importantly, the bandwidth calculation performs the division that yields the chapter's central number and never writes it down: 750,000 location updates per second against 232 trips — a 3,240:1 ratio that drives the quadtree problem, the hash table, Redis, and the choice of Cassandra. A colossal request rate can hide inside a small bandwidth figure when the objects are tiny.
Interview signal by level
| Level | What a strong answer sounds like |
|---|---|
| L4 | "20 million trips a day is about 232 per second, driver location updates are around 114 Mb/s, and storage is a few gigabytes a day." |
| L5 | Converts to a rate: "3 million drivers updating every 4 seconds is 750,000 writes per second — the bandwidth is small because the records are tiny, but that write rate is the real design constraint." |
| Staff+ | States the ratio and corrects the estimate: "750,000 location writes per second against 232 trips is a 3,240-to-1 ratio, and everything hard here follows from it — the quadtree can't absorb that, hence a hash table in front and a 15-second flush that divides it by 3.75. I'd also flag two things in the storage estimate: the 108 MB of driver locations is a snapshot being summed as a daily rate, and route traces are missing entirely at roughly 162 GB a day, which is sixty times everything counted — and that append-only time-series workload is precisely why Cassandra is the right choice later." |
Next: the workflow and the high-level design.