Capstone: Designing a System at Scale
Distributed Systems & Scalability
Chapter 10 · Capstone: Designing a System at Scale
One continuous worked project: a URL shortener, assembling every verified pattern from Chapters 1–9 into a single running system — sharded storage, a cache-aside redirect path, an async click-tracking queue, rate-limited creation, and a circuit breaker protecting the critical path from a broken analytics pipeline. Every number below comes from actually running the assembled system, not from restating each chapter's own earlier findings.
Assembling the System
Running the System End to End
create_short_url('https://example.com/a-very-long-article-url') returns short code 'c69915', and store.get('c69915') correctly returns the original long URL — the sharded lookup (Chapter 4's own hash-based routing) found the exact same shard it was written to.
redirect_service.store_lookups at exactly 1 — every redirect after the first was served entirely from cache, matching Chapter 3's own verified cache-aside shape at a different scale.
click_queue.events correctly holds 21 pending events — none of them processed yet, because redirect() only ever calls publish(), never a handler directly. Processing the queue afterward correctly produces click_counts == {'c69915': 21} — every single click accounted for, on its own schedule, exactly matching Chapter 6's own decoupling finding.
create_short_url() against a token bucket with capacity 5: the first 5 succeed, the remaining 3 correctly raise RuntimeError('Rate limit exceeded') — ['created', 'created', 'created', 'created', 'created', 'rate-limited', 'rate-limited', 'rate-limited'], matching Chapter 7's own token-bucket burst-then-throttle shape exactly.
2) and feeding it a handler that always raises ConnectionError: processing 10 queued clicks produces ['failed-full-cost', 'failed-full-cost', 'failed-fast', 'failed-fast', ...] — the circuit opens after 2 real failures, exactly matching Chapter 9's own verified breaker behavior. Meanwhile, calling redirect() 10 more times during this same broken-analytics period: every single one succeeds correctly, and redirect_service.store_lookups stays at 1 — completely untouched. The core redirect functionality never even knows the analytics pipeline exists.
The Rest of the System, Reasoned About Rather Than Re-Verified
Three more chapters shape this same system's real deployment, without needing fresh code to demonstrate here — each one's own mechanism was already verified in its own chapter, applied directly:
| Chapter | How it applies to this exact system |
|---|---|
| Chapter 2 — Load Balancing | Multiple UrlShortener instances behind Least Connections, exactly as verified — redirect traffic vastly outweighs creation traffic in a real URL shortener, so read-heavy load balancing matters most here |
| Chapter 5 — CAP Theorem | Short-code creation should be CP: two clients racing to create a code for the same long URL must never produce two different codes for it, the identical risk Chapter 5 verified for AP-style writes. Redirects, by contrast, can safely be AP — a slightly stale cache entry (Chapter 3) is a tolerable cost for availability, not a hash collision risk |
| Chapter 8 — API Gateway & Service Discovery | A gateway would front create_short_url() and redirect() as separate routes, using discovery to find whichever shard/replica currently holds a given short code — exactly the registry pattern Chapter 8 verified surviving a redeploy |
What This Course Doesn't Cover
This course stayed at the level of verifiable, single-process simulations of each pattern's own core mechanism — it did not cover actually deploying multiple real processes or machines, configuring a real load balancer or message broker, or the operational work of running any of this in production. Software Architecture Fundamentals Chapter 10's own scope note named this course as the next step after getting a system's own shape right; this course, in turn, hands off to actually operating one — Technical Support's own perfdiag1/incident1/netdiag1 courses cover diagnosing a system like this one once it's live and something goes wrong.
Hands-On Exercises
Create two more short URLs through this chapter's own UrlShortener, then redirect all three short codes a mixed number of times (e.g., 5, 3, and 10 redirects respectively). Verify store_lookups is exactly 3 (one genuine miss per distinct code), not 1 and not 18.
Using this chapter's own rate-limited create_short_url(), wait long enough for the token bucket to refill 2 tokens (at 1/sec, this chapter's own configured rate), then attempt 2 more creations. Verify both succeed, confirming the limiter recovers correctly rather than staying permanently exhausted.
Using this chapter's own verified resilience finding, explain specifically WHY redirect()'s own code never needed a try/except around anything analytics-related, when Chapter 9's own graceful-degradation example needed an explicit try/except around a failing dependency. What's structurally different about how this capstone wired click tracking?
Chapter 10 Quick Reference — and Course Quick Reference
- This capstone: a URL shortener assembling Chapters 3, 4, 6, 7, and 9 into one running system — verified: 1 real store lookup across 21 redirects, 21 click events fully decoupled and correctly counted, 5 of 8 rapid creations allowed, and redirects proven immune to a fully broken, circuit-breaker-wrapped analytics pipeline
- Course arc: Ch.1 (why systems need to scale, measured) → Ch.2 (load balancing) → Ch.3 (caching) → Ch.4 (database scaling) → Ch.5 (CAP theorem) → Ch.6 (message queues) → Ch.7 (rate limiting) → Ch.8 (API gateways & discovery) → Ch.9 (resilience patterns) → Ch.10 (assembling it all)
- Where this leads: Technical Support's own diagnostic courses (
perfdiag1,incident1,netdiag1) — this course builds the system; those courses diagnose it once it's live