Module 8: Project — Design Enlace End to End
1. Module introduction: the journey back
Description
In module 1 you opened a map. You stood at the entrance of the guide, looked at the poorest possible prompt —"design a URL shortener"— and saw, in the distance, the eight modules as stations of a journey: understand, estimate, model, cache, scale, distribute, make reliable, and finally design it all together. Back then the map was a promise: names of places you had not yet set foot on. Now you have set foot on all of them. This module is the journey back: you take the same map, but this time you walk it whole from beginning to end, with your legs already trained, and at the end you hold in your hand not a promise but a complete design of Enlace —distributed, defensible, with numbers—. You are not going to learn any new tool. You are going to do something harder and more valuable: put together the seven you already have into a single coherent artifact.
The capstone is not a surprise exam. It is the moment when the pieces stop being loose lessons and become a method you can execute from memory. You are going to go through, once again, the 4-step framework of module 1 —requirements → estimation → high-level design → deep dive— but now applying it in one flow, feeling how each step feeds the next: the requirements produce the numbers, the numbers draw the boxes, and the boxes are deep-dived exactly where the number pinches. When you finish the module you will deliver four concrete things —the design, the diagram, the capacity table and the list of tradeoffs— which are, exactly, what an engineer puts on the table in an architecture review or in a system design interview.
Connection to the module: this lesson is the map of the capstone, just as lesson 1 of module 1 was the map of the guide. Here you install two things: the structure of the deliverable (what you produce and in what order) and the summary of the eight modules as a single arc, so that you see the forest before walking again among the trees. Lessons 2 to 7 go through the design step by step —one per stretch of the framework—, and lesson 8 is the final project with its prompt, its rubric and its reference solution. If module 1 taught you not to freeze before the blank page, this one teaches you to fill it entirely with a design that withstands questions.
The apprentice who already walked the workshop
Think of it this way. A carpenter's apprentice spends months learning tools separately: one day the saw, another the plane, another how to assemble a dovetail joint, another how to sand and varnish. Each day they master a technique, but each technique lives alone, in its corner of the workshop. And then, one day, the master teaches them nothing new: he puts a board of wood in front of them and says "make me a chair". It is not one more lesson. It is all the lessons at once. The apprentice has to decide which wood, measure, cut with the saw, smooth with the plane, assemble with the joints they learned, and varnish at the end —in order, because you cannot varnish before assembling nor cut without measuring—. The chair does not teach them a new technique; it teaches them that the techniques were, all of them, parts of a single thing.
Notice what that moment reveals. The apprentice who only knew loose techniques could feel competent —"I know how to use the saw"— and still be paralyzed before the board, because knowing how to cut is not the same as knowing when to cut and what to cut. The chair forces them to put the techniques in sequence, to see how an early decision (what thickness of wood) conditions a late one (which joint holds), and to defend why they chose this leg and not another. That is where a bunch of techniques becomes craft: not the corner where each tool lives alone, but the table where they all collaborate to produce something that stands.
Designing Enlace end to end is that chair. Each module was a tool: estimation was the saw, the data model the plane, the cache the varnish. You know how to use them separately —you proved it in each mini-project—. The capstone puts the board in front of you and says "design all of Enlace", and your job is to put them in sequence —requirements, estimation, design, deep dive— to produce a complete system that withstands the questions. There is no new technique. There is something harder: the discipline of putting them together in order and defending each cut with a number.
It is worth spelling it out, because it is the idea that governs the module:
The capstone does not add tools: it puts together the ones you already have. Designing a system end to end is going through the 4-step framework in one flow —requirements, estimation, high-level design, deep dive— producing a design where each component is justified by a number, and each number comes from the estimation. Knowing the pieces is half the competence; knowing how to assemble them in order and defend them is the other half.
The eight modules, as a single arc
Before walking the map stretch by stretch again (lessons 2–7), it is worth seeing it whole at a glance, because the capstone only makes sense if you see how each module passes the baton to the next. They are not eight independent topics; they are eight stretches of a single journey, and each one starts where the previous one left a crack.
| Module | What it installed | The number that pushed it to the next |
|---|---|---|
| 1. How to approach | Understand before drawing; the 4-step framework; Enlace in a single box | The single box is a single point of failure and does not know how much it holds → you have to estimate |
| 2. Estimation | The napkin math: ~40 writes/s, ~4,000 reads/s, 6 TB, 62⁷ | 4,000 reads/s on a DB → you have to model and cache |
| 3. Data model and IDs | The Link record; the short_code with base62; 62⁷ ≈ 3.52 × 10¹² is more than enough | The record exists, but reading it 4,000 times/s saturates → cache |
| 4. Cache | Cache-aside; hit ratio 0.90 → 5.90 ms; working set ~333 MB | Even with a cache, 386 reads/s + 6 TB do not fit on one machine → scale the DB |
| 5. Scale the DB | Replicas (primary/replica, lag); sharding; consistent hashing (13.1% vs 88.9%) | Several DBs behind a single server → you have to scale the compute |
| 6. Load balancing and stateless | Load balancer (round-robin, least-connections, by hash); stateless services; health checks | Many machines that can go down → you have to reason about reliability |
| 7. Reliability and consistency | Redundancy; single points of failure; CAP/PACELC; eventual vs strong; SLA/SLO | All the pieces exist loose → you have to put them together in a design |
| 8. Project | Put the seven together into a complete, defensible design with numbers | — |
Read it as a single long sentence: you understand the problem and draw it simple (M1), but you do not know its scale, so you estimate it (M2); with the scale clear you model its data (M3), but reading them 4,000 times per second saturates, so you cache (M4); the cache does not absorb the 6 TB nor the residual load, so you scale the database (M5); several databases behind a single server move the bottleneck to the compute, so you load-balance over stateless services (M6); and once you have many machines that can fail, you reason about reliability and consistency (M7). Each stretch is born from a crack the previous one left exposed —exactly the four cracks you drew in the single box of module 1—. The capstone (M8) picks up the seven answers and orders them into a design.
That chaining is what you are going to reproduce in the deliverable. You are not going to list "I put a cache" as an isolated decision; you are going to show that the cache is born from the 4,000 reads/s of step 2, that the replicas are born from the 386/s residual the cache does not absorb, that the sharding is born from the 6 TB. A good design is not a list of components; it is a chain of justifications where each link holds up the next.
What you are going to deliver (and in what order)
The capstone produces four artifacts, and not in any order: in the order of the 4-step framework, because each one needs the previous. This is the map of the deliverable, and also the map of lessons 2 to 8.
1. The requirements (step 1 → lesson 2). The list of functional ones (shorten, resolve, 404), non-functional with a number (~40 writes/s, ~4,000 reads/s, latency <100 ms, availability 99.9%, eventual consistency) and the scope table (what enters the v1, what is deferred). It is the foundation: without requirements, there is nothing to estimate.
2. The capacity table (step 2 → lesson 3). The four capacity numbers, executed in Python, not quoted: QPS, storage at 5 years, bandwidth, working set memory. Each row with its calculation and its conclusion. It is the step that turns requirements into design signals.
3. The high-level design and its diagram (step 3 → lesson 4). The mermaid diagram of the complete distributed architecture —client, load balancer, stateless servers, cache, primary and sharded replicas— where each box is justified by a number from step 2. It is the first drawing, and the simplest one that meets the requirements at the estimated scale.
4. The deep dive and the tradeoffs (step 4 → lessons 5, 6, 7). The internal detail of the components the numbers marked as critical: the write path (ID generation), the read path (cache), the scaling of data (replicas/sharding) and of compute (load balancing), and —the finishing touch— the list of chosen and justified tradeoffs, starting with the consistency model. It is where the design proves that it understood the problem, not just that it drew boxes.
Lesson 8 puts the four together into the final deliverable, with its prompt, its evaluation rubric and a complete reference solution you can compare with yours. Notice the shape: the deliverable is the 4-step framework made a document. If you know how to go through the framework, you know how to produce the deliverable.
A note on the discipline of the capstone
Before starting, three warnings that separate a well-made capstone from one that only looks complete. You will recognize them: they are the same disciplines of module 1, now applied to the whole design.
First: do not draw before estimating. The temptation, now that you know cache, replicas and sharding, is to start lesson 4 (the diagram) with everything placed at once —"I put a load balancer, three servers, cache, eight shards"— without having run the numbers. It is the mistake of the colleague in module 1 who drew eight shards without calculating anything. In the capstone, each box of the diagram must be able to point to the number from step 2 that requires it. If you cannot, the box is superfluous (or missing).
Second: each number is computed, not quoted. It is the hard rule of the whole guide. In the deliverable, the capacity table is executed —you run the Python and paste the output—, not copied from memory. If your table says "4,000 reads/s" because you remember it, and not because 100M / (30·24·3600) · 100 gave you 3,858, you did not do step 2; you faked it. The capstone worth having is the one that reproduces the checksum.
Third: the tradeoffs are justified with the numbers, not with opinions. "I chose eventual consistency" is not a design decision; it is a preference. "I chose eventual consistency because Enlace's data is almost immutable, a freshly created short_code tolerates a fleeting 404 of milliseconds while the replica catches up, and that tolerance buys me read replicas that absorb the 4,000 reads/s" —that is a design decision, because it is tied to a number and to a consequence—. Every tradeoff in the deliverable carries its "because" with a figure.
Common mistakes
Treating the capstone as an opportunity to add new technology. What happens: someone, upon reaching the final project, decides to "show off" by throwing in message queues, a search engine, microservices and event sourcing —things neither the guide taught nor Enlace's numbers require—. The design bloats with impressive and unjustified components. Why it happens: "complete design" is confused with "complex design", and the capstone feels like the moment to prove you know a lot. How to spot it: if your Enlace design has a piece you cannot tie to an anchor number, or that belongs to a sibling guide (queues → event-driven, circuit breaker → resilience), you threw it in unnecessarily. How to fix it: the capstone puts together what the guide taught and the numbers require, no more and no less. A defensible Enlace design fits in a cache, a primary with sharded replicas, a load balancer and stateless servers. The sophistication is in justifying, not in accumulating.
Producing the design without the chain of justifications. What happens: someone delivers a pretty diagram with all the correct boxes —load balancer, cache, replicas, shards— but when you ask them "why three replicas and not one?" or "why shard by short_code and not by date?", they do not have the calculation behind it. The design is correct by chance, copied from a pattern, not derived from Enlace's numbers. Why it happens: it is easier to memorize the canonical shortener architecture than to reconstruct why it is that one. How to spot it: if your design would not change when you change the numbers of the prompt (for example, the intranet Enlace at 0.6 reads/s), you did not derive it, you recited it. How to fix it: for each box and each number of the design, write the line "this is here because step 2 gave X". That line is the difference between designing and copying.
Skipping step 1 because "you already know Enlace". What happens: since you have spent eight modules with Enlace, the temptation is to start the capstone directly at the diagram, taking the requirements for granted. But step 1 is not just remembering what Enlace does; it is explicitly declaring the non-functional requirements with a number and the scope table, because they are the input of step 2 and the justification of everything else. Why it happens: familiarity with the case makes step 1 feel like a formality. How to spot it: if your deliverable does not have an explicit list of non-functional requirements with their figures, you skipped the foundation. How to fix it: write step 1 completely even if "you already know it". In a real interview, starting with the requirements —even the obvious ones— is the signal that you design with method; skipping them is the opposite signal.
Exercises
Exercise 1 — Reconstruct the chain of justifications. Without looking at the table above, write the chain that connects the eight modules, starting with "I understand the problem (M1)" and ending in "I put it all together (M8)". Each link must name the number or the crack that pushes to the next module. The goal is that you can tell the entire guide as a single causal story.
See solution
A valid reconstruction:
- M1 (approach): I understand Enlace and draw it in a single box. Crack: I do not know how much it holds and it is a single point of failure.
- M2 (estimate): I compute the scale. Number: ~4,000 reads/s and 6 TB. Crack: 4,000 reads/s on a single DB saturates it.
- M3 (model): I define the
Linkrecord and generate theshort_code(62⁷ is enough). Crack: the record exists, but reading it 4,000 times/s still saturates. - M4 (cache): I put in a cache; hit ratio 0.90 → 5.90 ms. Residual number: 386 reads/s still reach the DB, plus the 6 TB. Crack: that does not fit on one machine.
- M5 (scale DB): replicas for the reads, sharding for the data, consistent hashing to grow without a storm. Crack: several DBs behind a single server move the bottleneck to the compute.
- M6 (load balance): load balancer + stateless servers. Crack: many machines that can go down.
- M7 (reliability): redundancy, basic failover, eventual consistency (which Enlace tolerates). Crack: everything exists loose.
- M8 (put together): I order the seven answers into a defensible design.
Notice that no link says "because big systems have it". Each one names a concrete number or crack. That is the story the capstone tells with a diagram and a table.
Exercise 2 — Classify each deliverable in its framework step. The capstone produces these artifacts, out of order. Assign each one to the step of the 4-step framework that generates it (1: requirements, 2: estimation, 3: high-level design, 4: deep dive): (a) the mermaid diagram of the architecture; (b) the table that says "~333 MB of working set"; (c) the list "eventual consistency because the data is almost immutable"; (d) "out of the v1: analytics and custom URLs"; (e) the detail of how shorten generates the short_code with counter + base62.
See solution
- (a) Architecture diagram → Step 3 (high-level design). Drawing the boxes and arrows is step 3.
- (b) "~333 MB of working set" → Step 2 (estimation). It is a capacity number (the working set memory).
- (c) "eventual consistency because…" → Step 4 (deep dive). It is a tradeoff of a critical component, with its justification; tradeoffs live in the deep dive.
- (d) "out of the v1: analytics…" → Step 1 (requirements). It is the scope table, part of setting requirements.
- (e) the detail of
short_codegeneration → Step 4 (deep dive). It is the internal design of a critical component (the write path).
The lesson: the deliverable is the 4-step framework made a document. Each artifact belongs to a step, and recognizing which one tells you whether your deliverable is complete —it is missing step 1 if it has no scope table, it is missing step 2 if it has no executed numbers, etc.—.
Exercise 3 — Spot the bloated design. A colleague presents their Enlace capstone with this architecture: load balancer, six microservices (one for shorten, one for resolve, one for analytics, one for authentication, one for rate-limiting, one for notifications), a Kafka message queue between all of them, event sourcing for the Link record, an Elasticsearch search engine, two cache levels and a database sharded across sixteen nodes. What is wrong with this design, which components are superfluous (and why), and which sibling guide claims the topics it threw in unnecessarily?
See solution
The design is bloated: it added complexity that neither Enlace's numbers require nor this guide teaches. Let us review with the anchor numbers in hand:
- Six microservices: the numbers do not justify them. Enlace has two operations (
shorten,resolve) over ~40 writes/s and ~4,000 reads/s; that is served by a stateless replicated service, not six microservices. Authentication, rate-limiting and notifications are out of scope (step 1: the v1 defers all of that). And the monolith-vs-microservices debate belongs toarchitectural-styles-and-boundaries-guide, not this one. - Kafka + event sourcing: a message queue and event sourcing are tools of
event-driven-architecture-guide. Click analytics could go through a queue (we mentioned it as a border in module 4), but we do not design it here, and certainly theLinkrecord does not need event sourcing —it is an almost immutable 1 KB mapping—. - Elasticsearch: Enlace looks up by primary key (
short_code), a lookup by index that any database does in logarithmic time. There is no free-text search in Enlace; a search engine is a component with no number asking for it. - Sixteen shards: with 6 TB, a handful of shards is enough (the capstone sizes it). Sixteen is a number pulled out of thin air, not derived from the ~750 GB per shard the arithmetic suggests.
The lesson: the capstone puts together what the guide taught and the numbers require. A defensible Enlace design is humble —load balancer, stateless servers, cache, primary with replicas sharded by consistent hashing— and each piece has its number. Throwing in Kafka, Elasticsearch and event sourcing is not designing better; it is failing to understand that the sophistication is in justifying, not in accumulating. And several of those pieces are not even from this guide: they are from the siblings, and throwing them in here is crossing a border the ecosystem draws on purpose.
Summary and next step
In this lesson you installed the framework of the capstone: module 8 does not add tools, it puts together the seven of the previous modules into a complete and defensible design of Enlace, going through the 4-step framework in one flow. Like the apprentice asked for a chair, you do not learn a new technique; you learn to assemble in order the ones you already have and to defend each cut with a number.
You saw the eight modules as a single causal arc —each stretch is born from the crack the previous one left, the same four cracks of the single box of module 1— and you met the four artifacts you are going to deliver: the requirements (step 1), the executed capacity table (step 2), the high-level design with its diagram (step 3), and the deep dive with the list of tradeoffs (step 4). And you set the discipline of the capstone: do not draw before estimating, compute each number instead of quoting it, and justify each tradeoff with a figure and a consequence.
Before moving on you should be able to: tell the entire guide as a causal chain of eight links; name the four artifacts of the deliverable and which step of the framework each one belongs to; and recognize a bloated design (the one that adds components with no number to justify them or that belong to another guide).
What comes next is starting the journey back through the first stretch. In lesson 2 you execute the complete step 1 for Enlace: the functional requirements, the non-functional ones with a number, and the scope table —the foundation from which everything else flows—. Even though "you already know Enlace", you are going to declare them explicitly, because they are the input of step 2 and the justification of each box you will draw afterward. The design begins, as always, with understanding.
Resources
- System Design Primer — "How to approach a system design interview question" — the checklist of how a complete end-to-end design is walked in an interview, which is exactly what this capstone does. Compare it with our 4-step framework: it is the same backbone, and its star example is, not by chance, a URL shortener (
pastebin/bit.ly). - Designing Data-Intensive Applications, by Martin Kleppmann — official site — the reference book of the craft (we have cited it as "DDIA" the whole guide). For the capstone, its Chapter 1 ("Reliable, Scalable, and Maintainable Applications") is the conceptual framework of the entire deliverable: the three non-functional pillars your design must satisfy and know how to defend.
- System Design Interview – An Insider's Guide, by Alex Xu — chapter "Design a URL Shortener" — the canonical treatment of the same Enlace case in the interview literature, with the same structure of requirements → estimation → design → deep dive. Useful as a second voice to contrast your reference design with another defensible path.