Docker Sandboxes & Production Playgrounds
System design is not real until you watch a database crash or a message partition rebalance under load. Run these 75 standalone labs across 6 difficulty tiers on your own machine with Docker Compose and kind, inject chaos, and inspect exact terminal logs and latency spikes.
01 /How to run these labs
Every lab in this track is self-contained. You do not need cloud credits. You only need Docker Desktop running on your machine.
1. Spin up with one command
Each lab includes a docker-compose.yml or kind cluster config. Host ports map to isolated ranges (15432, 16405, 18080, 18100, 18300, 19092) to avoid collisions with local services.
2. Trigger real failure modes
Pause a replica to accumulate replication lag, kill a consumer to force a group rebalance, or fire 25 concurrent workers at one row.
3. Verify state with scripts
Execute automated bash or PowerShell test suites that measure latency percentiles, verify atomicity, and test recovery.
New to Docker, or 1 to 3 years in? Start at Lab 00 (free). If you can run docker compose up, you are ready. Every lab has Bash and PowerShell scripts.
4 or more years and preparing for senior interviews? Jump to Lab 28 (PostgreSQL MVCC bloat), Lab 38 (Kafka rebalancing when a consumer dies) or Lab 50 (lock fencing tokens).
01 /Keep These Open While You Work
New to Docker, SQL, Redis or the terminal? Start with these short guides. They are free, and each lab links back to them. If a lab does not start, begin with the troubleshooting guide.
Docker and Compose Cheat Sheet
Every command the labs use, what each flag means, and the dangerous ones to think twice about.
Terminal Survival Kit
cd, ls, cat, pipes, environment variables, quotes. Bash and PowerShell side by side.
SQL and psql Cheat Sheet
The SQL and psql commands the database labs use, in plain words.
Redis and Lua Cheat Sheet
Redis commands by data type, plus the Lua pieces used in scripts.
HTTP and curl Cheat Sheet
Status codes, headers, Cache-Control and the curl flags the labs use.
02 /Start Here: Core Fundamentals (Labs 00 to 08)
Foundational environments for engineers new to containerization or SQL transaction internals. Docker Compose lifecycle mechanics, HTTP/DNS caching headers, and relational transaction isolation anomalies.
Docker Basics: Images, Containers, Ports & Volumes
Start here if you have never used Docker. Learn what an image and a container are, build your own image, run it, open a port, read its logs, step inside it, and see why a volume keeps your data when a container is deleted.
Docker Compose Basics: Two Containers, One File
Read a docker-compose.yml line by line, start a web app and Redis with one command, see how containers find each other by service name, break the name on purpose, and learn exactly what down and down -v delete.
Docker Compose in Practice: Healthchecks, Restarts & Volumes
Go beyond up and down. Check that a service is really ready (healthchecks), watch Docker restart a container that crashes, prove that a volume keeps your data across restarts, and learn what down and down -v each delete.
HTTP Caching Headers & DNS Resolution Mechanics
Inspect HTTP protocol exchanges with curl -v. Master status codes, Cache-Control directives, ETag validation, 304 Not Modified handshakes, TCP keep-alive, and DNS lookup caching with dig.
SQL Basics with PostgreSQL: Tables, Queries & Joins
Learn the SQL every later lab assumes. Create tables, insert and query rows from a kirana store, filter, sort, count, group, join two tables, see what a primary key and a foreign key stop, and peek at what an index does with EXPLAIN.
SQL Transaction Isolation Levels & Concurrency Anomalies
Demystify transaction phenomena with concurrent PostgreSQL sessions. Compare READ COMMITTED vs REPEATABLE READ vs SERIALIZABLE, and reproduce dirty reads, lost updates, and phantom reads under load.
Redis Basics: Every Command You Need Before Any Redis Lab
A guided tour of Redis with redis-cli: strings, counters, expiry, lists, hashes, sets and sorted sets, key naming, KEYS vs SCAN, and why one command is atomic. Everything the cache, rate limiter, queue and lock labs use, explained before you need it.
Lua in Redis: Atomic Scripts Explained from Zero
What is Lua, why does Redis run it, and how do you read a script? Learn the 10 pieces of Lua you need, watch a coupon get oversold when a check and a write are two commands, fix it with a script, and see what a slow script does to everyone else.
Race Conditions & Locks: Your First Concurrency Bug
Make a race condition happen on purpose with a seat counter, fix it with a lock, then see why a lock inside one program does not protect two programs. This is the idea behind every database lock, Redis lock and fencing token that follows.
03 /Building Blocks (Labs 03 to 12)
The essential building blocks every backend engineer must master before designing distributed clusters. Little's Law, load balancing algorithms, retries with backoff, edge cache control, cache-aside lifecycle, database indexing, keyset pagination, competing consumers, API gateways, and URL shortener engines.
Latency, Percentiles & The Saturation Knee (k6 & Python)
Master p50, p95, and p99 latency percentiles, Little's Law, and the saturation knee. Measure why average latency lies, how microservice fan-out turns p99 into the user's p50, and how queueing delay causes tail latency to explode past the saturation point.
Nginx Basics: Serve Files, Proxy to an App, Read the Logs, Reload Safely
Read an nginx config for the first time. Serve a page, forward /api to a backend with proxy_pass, read the access and error logs, see what a typo and a dead backend do, and reload the config without dropping a request.
Nginx Load Balancer: Round-Robin, Least-Connections & Failover
Balance HTTP traffic across 3 backend nodes. See round-robin deal requests evenly, watch one slow node drag it down while least_conn routes around it, stop a node and see no request fail (passive health only, and what it costs), bring it back, and weight a bigger server.
Timeouts, Retries, Exponential Backoff & Toxiproxy
Inject real network delay with Shopify Toxiproxy. See why no timeout holds every caller, how a retry rescues a blip, how naive retries multiply an outage by four, and how backoff, full jitter and a retry budget stop it.
Edge Reverse Proxy & CDN Cache-Control
Configure Nginx as a reverse proxy edge cache. Master surrogate keys, stale-while-revalidate background refreshes, targeted cache purges, and cookie-based cache leakage prevention.
Database Indexing, Query Optimization & Slow Query Profiling
Read the plan Postgres chose, with EXPLAIN (ANALYZE, BUFFERS), on 100,000 orders. Add an index and see it skip the table, remove a sort with column order, answer from the index alone and see what an UPDATE does to that, shrink an index with a partial index, and measure the write price of four extra indexes.
Pagination at Scale: LIMIT/OFFSET vs Keyset Cursor
Profile why deep LIMIT/OFFSET pagination degrades to O(N) full index scans. Implement deterministic keyset cursor pagination to maintain O(1) constant-time query latency across millions of rows.
Queue Basics: Your First Queue, Acknowledgements and Duplicate Messages
Build a queue from a Redis list. See producers and consumers share work, lose a message when a worker crashes, fix it with an acknowledgement step, and meet the price of the fix: the same message can arrive twice.
RabbitMQ Competing Consumers Queue, Prefetch QoS & Dead Letter Exchanges
Share a queue between two workers, then break it. Kill a worker mid-job and see RabbitMQ redeliver to the other, reject a bad message into the dead-letter queue, restart the broker with nothing lost, and see why a prefetch limit stops one heavy job from holding up the quick ones.
JWT and Auth Basics: Tokens, Signatures, 401 vs 403
What is a token? Log in, get a JWT, read what is inside it, and see why the payload is not secret but cannot be changed. Tamper with it, expire it, forge one with alg none, and see 401 and 403 for the right reasons.
API Gateway: Edge JWT Authentication, Routing & Distributed Rate Limiting
Put one gate in front of two services. Check the JWT, count requests in Redis (429 and Retry-After), route to the right service and hide internal headers. See what the gateway cannot do (authorization), then stop a service and freeze a service and watch a bulkhead keep the other one fast.
Full-Stack URL Shortener Sandbox, Base62 & Write-Back Analytics
Build the core of a Bitly-style service. Turn a database id into a Base62 code, read it cold and warm, choose between a 301 and a 302, refuse bad input, create many codes at once, and count clicks in Redis while a Postgres row lock holds up a direct write.
04 /Data & Scale (Labs 13 to 26)
Patterns designed to withstand high data volume, replication lag, sharding, deadlocks, MVCC storage bloat, connection pool exhaustion, cache stampedes, probabilistic counting, rate limiting, and near-real-time search indexing.
Real-Time Leaderboard with Redis Sorted Sets
Build a sub-millisecond ranking engine with Redis Sorted Sets (ZADD, ZREVRANGE, ZREVRANK). Analyze skip-list memory scaling and prevent big-key latency spikes under millions of scores.
PostgreSQL Streaming Replication Lag and Read-Your-Own-Writes
Write profile updates to the primary on port 15432, pause the replica on port 15433, and observe how replication lag produces stale reads. Then test monotonic read token routing.
PostgreSQL Synchronous vs Asynchronous Replication Tradeoffs
Freeze a replica on purpose. See an async commit finish at once, a sync commit wait in SyncRep (and stay invisible to other sessions), the commit finish when the replica returns, one transaction skip the wait with SET LOCAL, and the measured latency cost of waiting. PACELC in practice.
Consistent Hashing Ring with Virtual Nodes
Add a server to a cache cluster and watch your keys. With hash % N about 77 percent move and the real hit rate falls to 23 percent. With a consistent hash ring about 26 percent move and 74 percent of reads still hit. See why virtual nodes matter, and what a dead server costs.
Database Horizontal Sharding & Online Resharding
Split an orders table across three Postgres shards. See a hash spread small tenants evenly and one giant tenant overload a shard, run a query that must ask every shard, and move a tenant first the careless way (one order lost) and then the careful way with a live writer: dual write, backfill, reconcile, cutover.
Relational Database Deadlocks & Lock Ordering Anomalies
Make two transfers in opposite directions deadlock on purpose. Read the real 40P01 error, see which work is rolled back, count deadlocks in pg_stat_database, then fix it two ways: lock rows in a fixed order and retry when you lose.
PostgreSQL MVCC Dead Tuple Bloat & Long-Running Transaction Freezing
Pin the oldest snapshot with a long transaction and update 1,000 rows 25 times. VACUUM reports 25,000 versions dead but not removable and the table swells 18 times. Release the pin, see VACUUM reuse the space, VACUUM FULL return the disk, and test which timeout would have stopped it.
Cache Stampede, Mutex Locks & Single-Flight Request Coalescing
Expire a popular cache entry and send 40 clients at it. Count real database queries: 40 with no protection, 1 with single-flight in one server, 3 when you have three servers, and 1 again with a SET NX PX lock in Redis shared by all servers.
Bloom Filter Cache Penetration Shield
Send 500 lookups for products that do not exist at a cached catalogue. Without protection every one reaches Postgres. With a Redis-backed Bloom filter in front none do. Then shrink the filter and measure its false positives against the formula, and check that no real product is ever refused.
HyperLogLog Unique Visitor Cardinality Estimation
Count 100,000 unique viewers with a Redis set and with a HyperLogLog. See 5.3 MB against 14 KB, measure the error over ten counters, merge two days without double counting returning viewers, and see what a HyperLogLog cannot do.
Distributed Token Bucket Rate Limiter with Redis Lua
Run four rate limiting algorithms as Lua scripts in Redis under 25 concurrent clients. See a two-step limiter leak, a fixed window double its rate at the edge, a sliding window, token bucket and leaky bucket behave differently, and a frozen Redis turned into a quick fail-open or fail-closed decision.
UUIDv4 vs UUIDv7: B-Tree Index Fragmentation & WAL Bloat
Watch 60,000 random UUIDv4 keys fracture your B-Tree index into half-empty leaf pages and flood the Write-Ahead Log. Switch to monotonic UUIDv7 keys to pack pages to 90% density, reclaim 21% of index memory, and eliminate page splits.
Spatial Proximity & Dispatch: Redis GEO vs PostgreSQL PostGIS
Dispatch nearby delivery partners across Bengaluru. Compare Redis GEO in-memory Geohash sorted sets with PostgreSQL PostGIS GiST spatial indexing, prove boundary accuracy with an exclusion band, audit execution plans, and measure GPS update churn.
GraphQL Under Pressure: N+1 Database Explosion & Query Depth Attack Defense
Why does GraphQL make it trivially easy for clients to accidentally bring down your database? Reproduce the classic N+1 query explosion where 1 frontend request triggers 101 SQL queries, fix it with DataLoader batching (1+N to 3 queries), and defend against malicious recursive query bombs using AST depth limiting.
Direct S3 Uploads: Cryptographic Presigned URLs & Resilient Multipart Transfers
Stop routing heavy file uploads through application servers. Generate cryptographically signed S3 presigned URLs (SigV4) for direct-to-storage uploads with zero server bandwidth, and execute resilient multipart chunk uploads that recover from network packet drops without restarting.
Database Scaling: pgBouncer Session vs Transaction Pooling Modes
PostgreSQL forks an OS process per connection, exhausting RAM and context switching above a few hundred clients. Reproduce session pool starvation when 10 idle clients hold connections hostage, scale to 100 concurrent clients across only 5 physical database connections with transaction pooling, and solve session variable state leakage using SET LOCAL.
Distributed Caching: Two-Tier L1/L2 Cache Invalidation & Consistency
Why do high-throughput architectures add an in-process RAM cache (L1) in front of Redis (L2)? Measure sub-millisecond in-memory read latencies, reproduce silent cache drift where Node 2 serves stale prices after Node 1 updates, and broadcast real-time cache evictions across the cluster using Redis Pub/Sub with version fencing.
05 /Reliability & Messaging (Labs 27 to 38)
Event streaming ladders, partition rebalances, dead-letter queues, key skew, transactional outbox, idempotency keys, circuit breakers, backpressure, distributed sagas, distributed tracing, and canary deployments.
Kafka Fundamentals in KRaft Mode: Partitions, Consumer Groups & Offset Replay
Start a real Kafka broker in KRaft mode and prove four things: a key picks the partition (checked against a local copy of the Kafka hash), order holds inside a partition, a fourth consumer in a three-partition group sits idle, and a group can replay the whole log.
Kafka Consumer Groups, Offset Commit Semantics & Lag Monitoring
See that each consumer group keeps its own position in the same topic. Crash a consumer after saving its position and see duplicates, crash before and see loss, then move a group with reset-offsets and watch it go from Stable to Empty.
Kafka Consumer Group Partition Rebalancing and Pod Eviction
Kill a Kafka consumer with no goodbye and time how long its partition sits unread. See a second consumer join and the partitions split, the session timeout delay, the survivor catching up, and a count that shows no order was lost.
Kafka Dead Letter Queue & Poison Pill Isolation
Get one bad message to block a Kafka partition, then fix it: retry temporary failures with a limit, set aside the message that can never work in a dead-letter topic with the reason, keep the line moving, and replay it after a fix.
Kafka Hot-Key Partition Skew & Salting Mitigation
Measure what one hot key does to a Kafka topic: predict the partition sizes with a local hash, check them on a real topic, then try salting the key. See that three salts can still be uneven, and that salting costs the ordering of that key.
API Idempotency Key Engine & Distributed Locking
Build a payment endpoint that is safe to retry. Retry after a lost response, double click, reuse a key with a different body, crash after the money moved and before the work, empty Redis, and get a decline. The database holds the truth in the same transaction as the charge.
Circuit Breaker & Thread Bulkhead Isolation
Fail a payment partner then slow it, and measure what reaches it. Without protection every call lands on a partner that is already struggling. A circuit breaker keeps most calls in your service. A bulkhead keeps the partner at three in flight however many callers there are.
Backpressure, Bounded Queues & Priority Load Shedding
Send 400 requests a second to a service that can do 160. With no limit the queue passes 100 jobs and most callers give up before their answer arrives. A bounded queue gives more timely answers, dropping stale jobs saves wasted work, and priority shedding keeps checkout served while background is refused first.
Logs, Metrics and Traces: Three Ways to Find What Is Slow
One tiny two-service shop, three kinds of evidence. Find a slow request with logs and see why it is hard, spot the problem with a metric and see what it cannot tell you, then find the exact slow step with a trace.
Zero-Latency Feature Flag Engine: Server-Sent Events (SSE) & Local Memory
Eliminate network latency from feature flag checks. Stream rule updates over Server-Sent Events into local process memory, prove zero network calls during flag evaluation, inject network partitions with Toxiproxy to observe kill switch misses, and recover with heartbeat half-open socket detection.
gRPC Load Balancing: L4 Connection Pinning vs L7 Stream Multiplexing
Why does standard L4 TCP load balancing send 100 percent of gRPC traffic to a single container? See HTTP/2 connection reuse pin all RPC calls to one backend instance, then switch to an L7 proxy that unpacks HTTP/2 frames and distributes individual streams evenly.
06 /Architect & Chaos (Labs 39 to 49)
Architect-level distributed consensus, zero-downtime schema evolution, distributed locking fencing, Redis Sentinel quorum failover, Raft leader election, Cassandra quorum reads, CDC WAL extraction, Tatkal concurrency locks, multi-region disaster recovery, UPI payment capstone, and chaos engineering drills.
Zero-Downtime Database Schema Migrations: The Expand/Contract Pattern
Rename and migrate columns on live production databases with zero table locks. Master the 5-phase Expand/Contract pattern: add nullable column, dual-write trigger, backfill batching, app switchover, and contract cleanup.
Distributed Lock Fencing Tokens & Lease Expiration
Break naive distributed locking with simulated GC pauses. See how an expired lease lets a zombie worker overwrite valid storage data, and implement monotonic fencing tokens to enforce strict server-side write rejection.
Redis Sentinel Quorum Failover and Split-Brain Prevention
Deploy a 3-node Redis Sentinel quorum cluster. Isolate the primary in an asymmetric network partition, observe +sdown to +odown transition, watch epoch consensus elect a new replica, and prevent split-brain writes with min-replicas-to-write.
Raft Consensus Algorithm: Leader Election & Log Replication
Observe Raft distributed consensus in an etcd cluster. Trigger split-vote elections, isolate leader network partitions, observe quorum heartbeats, and verify log commit consistency across term increments.
Tunable Consistency: Quorum Reads, Writes & Read Repair (Cassandra Style)
Explore Dynamo/Cassandra style tunable consistency in a Python simulation: Replication Factor N=3, Write Quorum W=2, Read Quorum R=2. See how R + W > N ensures read freshness for acknowledged writes, why quorum is not linearizable, and how read repair heals stale replicas.
Change Data Capture (CDC) with PostgreSQL WAL Logical Decoding
Extract real-time database mutations from PostgreSQL WAL with test_decoding logical replication slots. Stream INSERT, UPDATE, and DELETE operations as structured JSON change events without database polling overhead.
CQRS Architecture & Read Model Projections
Separate read and write paths with Command Query Responsibility Segregation (CQRS). Stream domain events from normalized PostgreSQL write stores into denormalized Redis/Elasticsearch read projections.
Tatkal / BookMyShow High-Concurrency Seat Hold Race
Simulate the 10:00 AM Tatkal rush on the Mumbai Rajdhani. Fire 25 workers at one berth, six ways: the overselling bug, a guarded UPDATE, SELECT ... FOR UPDATE, an optimistic version check, a lock held across a payment call that starves unrelated requests, and a hot row no lock can speed up.
Multi-Region Active-Passive Failover & Cross-Region Lag
Simulate two cloud regions with two independent Postgres databases and a 60ms delay. Drill disaster recovery RPO/RTO when the primary region experiences an outage, and measure data loss under simulated application-level cross-region lag.
UPI Payment System Capstone: Idempotency, Outbox, Sagas & Reconciliations
Assemble the complete Swiggy/UPI payment architecture: edge idempotency token check, database transactional outbox, asynchronous NPCI payment bank gateway polling, distributed saga rollbacks, and midnight ledger reconciliation.
Production Chaos Game Day: Failure Injection & Incident Recovery
Put on your SRE on-call hat for a simulated production outage. Script random chaos events: kill leader pods, drop 20% of network packets, saturate connection pools, and diagnose root causes from live Prometheus metrics.
07 /Orchestrate: Kubernetes on Your Laptop (Labs 60 to 65)
Multi-node Kubernetes clusters inside Docker using kind. Self-healing pod lifecycles, service discovery and NodePort load balancing, probe-driven zero-downtime rollouts, Horizontal Pod Autoscaling under Tatkal rush load, and node failure survival.
Your First Cluster: Pods, Deployments, Self-Healing
Deploy a 3-replica Tatkal API on a 3-node kind cluster, delete a pod under traffic, and watch Kubernetes replace it within seconds while surviving replicas keep serving requests on 127.0.0.1:18300.
Services and Load Balancing
Expose a dynamic set of pods behind a stable ClusterIP and NodePort Service. Inspect endpoints as pods scale from 3 to 5, and measure random connection load balancing across replicas.
Readiness, Liveness and Startup Probes
Configure readiness, liveness and startup probes on one app. Simulate traffic drop when a pod becomes unready, trigger container restart on health failure, and avoid startup restart storms.
Rolling Updates, Rollbacks and Graceful Shutdown
Upgrade an application with maxUnavailable=0 and maxSurge=1 with zero failed requests under load. Push a broken release that crashes on start, verify rollout stalls safely, and undo the rollout.