Skip to main content
Scale Evolution Timeline
6 rungs · 10K → 1B RPS

Ride Sharing: Junior → Architect Evolution

The mandated interactive flow. Step through each rung, ask what breaks FIRST, weigh the options, and defend the chosen architecture. This is how architectural thinking is learned — not by reading a fixed design, but by tracing how it evolves under growth pressure.

Back to Ride Sharing

Scale Evolution Timeline

Step through 6 architectural rungs, from 10K RPS to 1B RPS. At each rung, ask: what will break FIRST? Why? What options exist? Which one do we pick — and what are we accepting?

This is the reasoning cycle that separates a Junior developer ("here's an architecture") from an Architect ("here's why this architecture, why now, and what breaks next").

Rung 1 of 610K RPS
10K RPS

10K RPS — single-server nearest-driver in Postgres

1. Current architecture

Where we are before growth pressure

1 × c6i.xlarge Rails/Go app + Postgres RDS db.r6i.large. `drivers(driver_id, lat, lon, status)` table with a GiST (PostGIS) index on `(lat, lon)`. Riders POST `/request_ride` with pickup coords → app runs `SELECT driver_id FROM drivers WHERE status='available' ORDER BY earth_distance(...) LIMIT 5`. Driver polls `/next_dispatch` every 2s.

2. Growth trigger

What changed — the traffic/data force

Founding city launch — one metro, ~500 drivers online, ~5K ride requests/hour peak. Traffic peaks at 10K RPS during commute hours (mostly driver location updates every 4s, minority ride requests).

3. Bottleneck — what breaks FIRST?

The component that saturates as growth arrives

Bottleneck component

None yet — PostGIS handles the load

Why it breaks

10K RPS with 500 online drivers is trivially handled by PostGIS GiST index. Each ride-match query traverses ~50 drivers within a 5-mile radius and picks nearest. p99 latency: 40-80ms. DB CPU 30%.

Signal you'd see

DB CPU 30%, PostGIS query time 35ms p99, driver location update rate 500/4s = 125 writes/sec (well within DB write capacity)

4. Options — what could we do?

Alternatives an architect must consider before picking

Do nothing — Postgres + PostGIS is enough
CHOSEN
  • + Zero new infrastructure
  • + Single source of truth for driver state (no cache invalidation)
  • + Familiar tech stack — team already knows SQL
  • Single point of failure — Postgres restart = full outage
  • Ceiling near 50-100K RPS on this hardware
$310/mo

5. Chosen

The specific decision we're making

Do nothing — PostGIS on Postgres is genuinely enough at 10K RPS in one metro

6. Trade-offs

What we're explicitly accepting to move forward

  • Accept single-DB SPOF — plan for 60s of downtime on failover
  • Accept 40-80ms p99 — riders barely notice, drivers unaffected
  • Accept 4-second driver location update cadence (any faster wastes battery + bandwidth)

7. New architecture

The system after this decision — headroom for the next 5-10x

1 × c6i.xlarge app + PostGIS Postgres db.r6i.large. Total cost: $310/mo. Ships within 6 weeks with a 2-engineer team.

Estimated: $310/mo (1 app + Postgres)

8. Next bottleneck — what will break at the NEXT rung?

This is the seed of the next rung

At ~100K RPS (10 cities, 50K drivers), PostGIS GiST index becomes the write bottleneck. Every driver location update triggers an index rebuild — write throughput ceiling is 1-2K writes/sec. Need a spatial-index-native tech — L5 shape.

What comes next in your Junior → Architect journey

You've traced 6 rungs of Ride Sharing evolution. Now try the same reasoning cycle on a system you don't know yet — pick from the Systems catalog and answer the same questions: current arch → growth trigger → bottleneck → options → chosen → trade-offs → new arch → next bottleneck. That is architecture.