You order biryani on Swiggy. You keep refreshing. A little bike icon crawls across the map toward your house. It feels like magic.
It isn't. It's four tools, each doing exactly one job. This post breaks the whole thing down using that one everyday moment — no heavy theory, just the flow.
Swiggy runs on AWS; I've mapped everything to its Azure equivalent so you can build the same thing.
The cast: 4 tools, 4 jobs
| Tool | Its one job | Real-life analogy |
|---|---|---|
| Service Bus | Carry the order — must never be lost | Registered post |
| Event Hubs | Carry the GPS firehose — millions of pings | CCTV recording |
| Redis | Hold "where's the bike right now" | Sticky note |
| Cosmos DB / SQL | Keep the order forever | Filing cabinet |
The whole trick is: never make one tool do two jobs. Each is great at exactly one thing.
The journey, step by step
1. You tap "Place Order"
Tap → Service Bus (1 order message) → Order Service → saved to Cosmos
Service Bus = reliable, so the order can't vanish or double. Cosmos = the permanent record.
2. Restaurant gets notified
Order Service → Service Bus → Restaurant App: "New order!"
A discrete command that must arrive → Service Bus again.
3. Rider assigned — and GPS starts immediately
Rider assigned → phone GPS starts streaming → Event Hubs
This is why you can watch the bike drive to the restaurant first, then to you. GPS begins at "assigned," not at "picked up."
4. The firehose hits the pipe
Bike GPS (every ~4 sec) → Event Hubs
One bike is tiny. 500,000 bikes = ~125,000 pings/sec. Event Hubs swallows it without blinking.
5. A processor turns the firehose into one value
Event Hubs → Stream Processor → Redis: "bike_4471 = 12.97, 77.59"
Each new ping overwrites the last one in Redis. 15 pings a minute collapse into 1 sticky note.
6. You refresh the map
Your app → reads Redis (1 value, <1ms) → 🛵 dot moves
You read Redis, not Event Hubs. It's instant because it's a single lookup, not a firehose.
7. Delivered — keep only what matters
Order Service → status "Delivered" → Cosmos
Processor → sampled trail → Lakehouse
The raw 4-second pings are thrown away. Kept: the final order (Cosmos) + a thinned route trail (Lakehouse).
The one idea that makes it all click: TWO LANES
Beginners picture one straight line. It's actually two independent lanes that meet only at Redis.
WRITE lane (always on, background): GPS → Event Hubs → Processor → Redis
READ lane (only when you refresh): You → Redis → 🛵
- The processor is always filling Redis in the background.
- Your refresh only reads Redis.
- You never touch Event Hubs or the processor.
Analogy: a chef (processor) keeps refilling the buffet tray (Redis). You (refresh) grab from the tray. You never wait for the chef.
The 4 confusions everyone hits (and the fix)
"Isn't the cached position outdated?"
It can be — by design. You only cache things where "a few seconds old is fine" (bike position). You never cache the wallet balance. Redis holds a fresh value because the processor overwrites it every few seconds.
"Is Event Hubs just a database?"
No. A database lets you ask "give me bike 4471's location." Event Hubs can't — it only lets you read the stream front-to-back, like a ticker. It's a log that forgets (data expires after 1–7 days). Filing cabinet vs conveyor belt.
"Event Hubs overwrites, so no history?"
Swapped tools. Event Hubs KEEPS history (every ping, in order, for days). Redis is the one that overwrites. History survives in Event Hubs short-term and Lakehouse long-term.
"Won't the database get the same 125k/sec firehose anyway?"
No — the consumer is a filter + funnel, not a pass-through:
- Reduce — Redis overwrites; only a sampled trail is kept (drop ~87%)
- Batch — 1,000 events → 1 bulk write
- Smooth — the buffer absorbs the dinner-time spike so the DB sees a calm, flat rate
By the time data reaches the DB, it's a trickle — sampled, batched, and calm.
Bonus: how does it say "25 mins" before the food is even made?
It's a prediction, not a measurement. An ML model adds three guesses:
ETA = prep time + rider-to-restaurant + restaurant-to-you
| Piece | Guessed from |
|---|---|
| Prep time | This restaurant's history for this dish + kitchen load |
| Pickup travel | Rider GPS distance + live traffic |
| Delivery travel | Route distance + live traffic |
That's why your ETA sometimes jumps 25 → 35 mid-order: the model re-adjusts as reality changes.
Why not just use one big tool?
Because every tool is great at one thing and bad at the others:
| If you forced Event Hubs to also be the database | If you forced Redis to keep history |
|---|---|
| Can't look up by key | Runs out of memory fast |
| Data expires and vanishes | Loses "current" clarity |
Splitting the jobs is the same trade-off principle behind all system design: pick the right tool for each job, and accept that no single tool wins at everything.
The whole thing in 3 lines
Order → Service Bus → Cosmos (keep forever)
GPS → Event Hubs → Redis (keep "now") → your map
The database never sees the firehose — only the trickle that matters.
Next time you watch that bike crawl toward your door, you'll know: it's not magic. It's a write lane quietly filling a sticky note, and a read lane grabbing it every time you refresh.
Top comments (0)