System Design Labs: Learn by Building, Not Just Reading
Interactive Python notebooks for mastering system design patterns through hands-on experimentation with real infrastructure.
Introduction
System design interviews are notorious. You're asked about scaling databases, handling concurrent writes, or building real-time notification systems. Most preparation involves reading blog posts and watching videos. But there's a problem: you can't truly understand distributed systems until you break them.
That's why I created System Design Labs - a collection of interactive Jupyter notebooks that let you run, break, and fix actual distributed systems on your laptop.
📦 Source Code: github.com/ShonP/system-design-patterns
The Problem with Learning System Design
Traditional learning approaches fail for several reasons:
You read that "optimistic locking is better when conflicts are rare" - but what does that actually mean? How rare is rare? What happens when conflicts aren't rare?
System Design Labs lets you:
- Run real code that demonstrates each pattern
- See failures happen and understand why
- Compare approaches side-by-side with actual metrics
- Experiment freely without production consequences
What's Inside
The repository covers 7 major patterns with 42 notebooks total:
| Pattern | Description | Notebooks |
|---|---|---|
| Real-Time Updates | Polling, SSE, WebSockets, Pub/Sub | 7 |
| Dealing with Contention | Locks, optimistic concurrency, CRDTs | 5 |
| Scaling Reads | Caching, read replicas, materialized views | 6 |
| Scaling Writes | Sharding, partitioning, write buffering | 6 |
| Handling Large Blobs | Chunked uploads, presigned URLs, CDN | 6 |
| Long Running Tasks | Queues, workers, DLQ, backpressure | 6 |
| Multi-Step Processes | Workflows, sagas, Temporal | 6 |
A Taste: The Concert Ticket Problem
One of my favorite notebooks demonstrates race conditions with a concert ticket scenario:
Timeline of a Race Condition:
────────────────────────────────────────────
Alice's Request Bob's Request
────────────────────────────────────────────
READ: "1 seat available"
READ: "1 seat available"
CHECK: 1 >= 1 ✓
CHECK: 1 >= 1 ✓
UPDATE: seats = 0
UPDATE: seats = -1
Result: Both get the SAME seat! 🔥
────────────────────────────────────────────
You don't just read about this - you run the code and watch it fail. Then you implement solutions: pessimistic locking, optimistic concurrency, and distributed locks. You see exactly when each approach works and when it doesn't.
Real Infrastructure Included
Each pattern comes with Docker Compose configuration for real services:
| Service | Purpose |
|---|---|
| PostgreSQL | Database operations, transactions, locks |
| Redis | Caching, queues, pub/sub, distributed locks |
| MinIO | S3-compatible blob storage |
| Temporal | Workflow orchestration |
| Adminer | Database visualization |
| RedisInsight | Redis monitoring |
All visualization tools are included - you can watch locks being acquired, cache keys expiring, and messages flowing through queues in real-time!
Real-World Applications
These aren't theoretical patterns - they're battle-tested solutions used by companies you know:
| Company | Problem | Pattern Used |
|---|---|---|
| Ticketmaster | Seat booking conflicts | Pessimistic locking |
| Like counts on viral posts | Sharded counters | |
| YouTube | Billions of view updates | Hierarchical aggregation |
| Uber | Real-time driver locations | WebSockets + pub/sub |
| Message delivery | SSE + presigned URLs |
Quick Start
Getting started takes just 3 commands:
# Clone the repository
git clone https://github.com/ShonP/system-design-patterns.git
cd system-design-patterns
# Pick a pattern (e.g., real-time-updates)
cd patterns/real-time-updates
# Start infrastructure and open notebooks
docker compose up -d
pip install -r requirements.txt
jupyter notebook notebooks/
Prerequisites: Python 3.10+, Docker & Docker Compose, uv (recommended) or pip
Learning Path
I recommend going through the patterns in this order:
- Real-Time Updates - Foundation concepts (HTTP, WebSockets)
- Dealing with Contention - Critical for any multi-user system
- Scaling Reads - Most common scaling problem
- Scaling Writes - When reads aren't enough
- Long Running Tasks - Async processing fundamentals
- Large Blobs - Media handling patterns
- Multi-Step Processes - Advanced orchestration
Try It Yourself
Stop reading about system design. Start building it.
🚀 Get Started: github.com/ShonP/system-design-patterns
Each notebook builds on the previous one, so you develop deep understanding instead of surface-level familiarity. Break things. Fix them. That's how real learning happens.