Week 7 Checkpoint: Design & Build a URL Shortener
- Recall the week's core ideas from memory: TLS, auth, layering, statelessness, caching, the design method
- Produce a one-page design doc (capacity, API, schema, cache strategy) before writing code
- Build a working URL shortener: FastAPI + SQLite + cache-aside + tests
- Write the trade-offs section the way you would answer it in an interview
| Closed-book recall drills over Days 43β48 | 25 min |
| Design doc sprint (timed, paper first) | 20 min |
| Build: URL shortener with tests | 50 min |
| Interview answer rehearsal (out loud) | 10 min |
| Cumulative quiz + flashcard deck drill | 15 min |
Builds on: Day 43 β Networking & HTTPS Β· Day 45 β Layered service architecture Β· Day 47 β Cache-aside & invalidation Β· Day 48 β The system design method
Today nothing new walks in the door β and that is the point. This week you collected six tools: the network layer cake (Day 43), locks and badges (44), the layered kitchen (45), many kitchens (46), the pantry and ticket rail (47), and the architect's rehearsal (48). A checkpoint day forges them into one object you can point at: a URL shortener you designed on paper first and then actually built.
Why review this way? Your brain treats retrieval as a signal of importance: every fact you successfully drag out of memory β without peeking β gets its forgetting curve reset and flattened. Re-reading feels productive but leaves no such trace; that is why today starts with closed-book recall drills before any building. And why a URL shortener? Because it is the "scales practice" of system design: small enough to finish in an afternoon, real enough to need everything β an API contract, a schema with the right index, a cache with an invalidation story, and honest trade-offs. Every senior engineer has designed one; today you join them.
Interviews love the URL shortener precisely because it exposes whether you reason or recite: base62 math, read-heavy caching, and redirect semantics (301 vs 302) are all decision points with defensible alternatives. Having BUILT one β not just watched a video about one β changes how you talk about it forever; "in my implementation, cache-aside cut redirect latency 40Γ" beats any memorized diagram. This is also your first complete run of the design-then-build loop that the capstone (Day 119) and every FDE prototype (Day 166) will follow: paper first, code second, trade-offs written down.
Guided practice
Closed-book recall drills
25 minEditor closed, notes closed. Write from memory, THEN diff against the week's notes and score yourself (per item: solid / shaky / gone).
- Day 43: list the phases of one HTTPS request in order, with what each costs. Then: latency or bandwidth β which dominates small API calls, and why?
- Day 44: hashing vs encryption in two lines; why salt; why bcrypt over SHA-256; the JWT revocation pitfall and its standard mitigation.
- Day 45: draw the three layers with arrow directions; what belongs in middleware; the token-bucket rule in one line.
- Day 46: define idempotent; why timeouts are ambiguous; CAP in one honest sentence.
- Day 47: cache-aside's three steps; TTL vs explicit invalidation trade; why exactly-once delivery is a myth.
- Day 48: the seven steps in order; the seconds-per-day constant; QPS for 5M requests/day (do it in your head).
Everything scored "shaky" or "gone" β add to today's revisit list and re-read only those sections.
Design doc sprint (paper before code)
20 minUsing your Day 48 template, produce shortener_design.md in 20 timed minutes. No code yet.
- Requirements: 4 functional, 4 non-functional (state your assumed scale and read:write ratio).
- Capacity: write QPS, read QPS, storage/year at ~200 bytes/link. Conclude explicitly whether SQLite suffices and why.
- API: the three endpoints with request/response shapes; mark which are idempotent and how.
- Schema: the links table; name the index and what query it serves.
- High-level ASCII diagram: client β API β cache β DB, read and write paths drawn separately.
- Deep dive: base62 code generation β with 62β· β 3.5Γ10ΒΉΒ² codes and your scale, estimate collision probability per insert and justify check-and-retry.
- Trade-offs: three complete sentences, including your 301-vs-302 decision tied to the stats requirement.
On your own
Interview answer rehearsal
10 minSet a 7-minute timer. Out loud (really out loud), walk the shortener design as if an interviewer asked "design bit.ly" β following your doc but not reading it. Cover all seven steps; land the 301/302 trade-off and the "why SQLite is fine at this scale" argument.
Goal: no step skipped, no number invented mid-sentence, trade-offs stated in the X-over-Y-accepting-Z form. If you stall anywhere, that section of the design doc was not really yours yet β revise it after.
Build the URL shortener
Implement shortener/ in your practice repo using the Day 45 layered template: routes / service / repo, with Day 47's cache. Endpoints: POST /v1/links (validates the URL, honors Idempotency-Key, generates a 7-char base62 code with collision retry, returns the short link), GET /{code} (cache-aside lookup, increments hits, 307-redirects; 404 problem-details for unknown codes), GET /v1/links/{code}/stats (hit count + created_at). Config from env vars (DB path, cache TTL). Tests with TestClient: create-then-redirect round trip, duplicate Idempotency-Key returns the same code, unknown code β 404 shape, and a spy-repo test proving the second redirect skips the DB. Commit design doc + code together β the doc is part of the deliverable.
Common mistakes & misconceptions
- Building first, back-filling the design doc after. The order is the exercise β designing on paper forces the decisions (index, cache, status code) you would otherwise stumble into.
- Reviewing by re-reading the week's notes. Retrieval strengthens memory; recognition just feels good. Closed book first, diff second, re-read only the gaps.
- Choosing 301 redirects and then wondering why hit counts stall. Browsers cache 301s and stop visiting you. If stats matter, that requirement decides 302/307 β requirements drive design, even here.
- Generating codes from a global counter without noticing the trade: sequential codes are guessable (enumerate everyone's links) and the counter is shared state (Day 46). Random base62 + retry avoids both at your scale.
- Caching the hit counter. Counters are mutable state, not cacheable copies β cache the immutable codeβURL mapping, count in the store.
- Skipping the out-loud rehearsal because the doc exists. Interview fluency is a motor skill; the first time you SAY a design should not be in the interview.
Q1. A client makes 50 sequential HTTPS requests without connection reuse. Which cost repeats 50 times that pooling would pay once?
Q2. Your shortener must show accurate click counts. Which redirect status should GET /{code} return, and why?
Q3. Two identical POST /v1/links requests arrive with the same Idempotency-Key (a client retried a timeout). The correct behavior isβ¦
Go deeper β curated resources
- Compare your design to the canon β After building, read the System Design Primer's pastebin/shortener chapter and list two things it does differently (e.g. separate read/write services, NoSQL at larger scale) and the scale at which each would start to matter for you.
- Recall drills scored; revisit list written and weak sections re-studied
- Design doc committed before the first code commit
- All shortener tests pass, including idempotency and spy-repo cache proof
- Trade-offs section written in interview form; rehearsal completed out loud
- Cumulative quiz β₯ 2/3 (follow revisit pointers for misses)
β Back: This build is the whole week compressed: Day 48's method produced the doc, Day 45's layers shaped the code, Day 47's cache-aside sits on the hot path, Day 46's idempotency key guards creation, and Day 38's index intuition chose the primary key. Even Day 43 shows up in WHY the redirect hop is cheap.
Forward β: Phase 2 ends here. Monday (Day 50) pivots to the math phase β vectors and dot products β where the "arrows and shadows" you draw become, by Day 92, the embeddings your RAG systems search. The shortener itself returns as a reference architecture: Day 148 containerizes services shaped exactly like it.