Build the mental model
Every system-design decision throughout this course reduces to the same three questions, and reviewing a decision after the fact means answering them explicitly rather than trusting the original choice. First: what does this choice cost — in complexity, latency, durability, operational burden, or money? Second: what does it buy — usually simplicity, speed of shipping, or lower cost at low scale? Third, and most often skipped: at what point does the answer flip — what request volume, data size, or uptime requirement makes the cheap choice actively wrong? An in-memory dict is free and fast until a process restart erases every short link ever created; an auto-incrementing counter is trivial until multiple servers need to hand out codes without colliding; no cache is simplest until one viral link accounts for 40% of read traffic; a single server is cheapest until it becomes the one thing that takes the whole product down. The discipline is naming the crossover point, not just picking a side.
Connect it to a real scenario
Imagine reviewing Tutorial Platform's own 'share this lesson' short-link feature, built using the same URL shortener project from this course. The original engineer chose an in-memory dict, an auto-incrementing counter, no cache, and a single server — reasonable when the feature launched with a few hundred links a day. Your job as reviewer isn't to declare the choices wrong; it's to check whether Tutorial Platform's current traffic has crossed the scale where each trade-off flips, and to recommend which decisions still hold and which now need revisiting before the feature breaks in production.
Try the working example
# Scenario 1: storage - in-memory dict vs a real database
# Tutorial Platform's URL shortener started with:
# short_to_long = {} # short_code -> original_url, held in process memory
# It handles 200 short links/day, all created and read within the same
# process lifetime. No restarts have happened in production yet.
# Scenario 2: short code generation - auto-incrementing counter vs hash-based codes
# counter = 0
# def make_short_code():
# global counter
# counter += 1
# return base62_encode(counter)
# Runs on a single web server. Traffic has grown to 50,000 new links/day
# and the team is discussing adding a second server for redundancy.
# Scenario 3: caching - no cache vs a read cache for hot short codes
# def resolve(short_code):
# return short_to_long[short_code] # every redirect hits the dict/DB directly
# One influencer's shared link now accounts for ~40% of all redirect
# traffic in a single afternoon.
# Scenario 4: single server vs load balancing/replication
# The entire service - API, storage, code generation - runs on one EC2
# instance. It has handled all traffic since launch with 99.9% uptime,
# but the last outage (a routine OS patch reboot) took the whole
# shortener down for 6 minutes, breaking every shared link site-wide.There's no single right answer per decision — the audit is correct when each conclusion names a concrete crossover condition: the in-memory dict is fine only until a restart or multi-server need appears; the counter is fine until codes must be generated across multiple servers without collisions; no cache is fine until one link dominates read traffic; a single server is fine until an outage's cost exceeds the cost of adding redundancy — and Tutorial Platform's current scenarios (50,000 links/day, a 40%-traffic viral link, a production outage) show each crossover has already been passed.5-minute try-it
For each of the four scenarios in the code above, write a short audit note with three parts: (1) what the current choice costs Tutorial Platform right now, (2) what it bought when the feature was simpler, and (3) whether the stated traffic/scale numbers mean the trade-off has already flipped — and if so, name the specific replacement (e.g. a database, hash-based codes, a read cache, or a load balancer) you'd recommend.
One important caution
Declaring the in-memory dict or single server 'wrong from the start' as a blanket rule — this ignores that these were the correct choice for the scale the feature actually launched at, and 'always use a database/load balancer' is cargo-culted best practice, not analysis.
Recommending a fix (cache, database, replication) without pointing to the specific traffic number that justifies it — a trade-off audit that doesn't name the crossover condition is just a preference, and gives no way to tell if the same fix is still right after traffic changes again.
Wikipedia — Non-functional requirement — System Design