How I used Grokking System Design to prepare my first interview

How I used Grokking System Design to prepare my first interview

Grokking System Design taught me to clarify workloads and reliability targets before naming components, estimate with explicit assumptions, follow RESHADED, and practice trade-offs with AI mock interviews.

6 mins read
Nov 10, 2026
Share

A “design Twitter” prompt made me close my notebook before I drew a single box. I had built CRUD applications, but each prompt felt like a private test of genius. That assumption made preparation feel too large to begin.

I used Grokking Modern System Design Interview from Educative to get past that. This post covers the parts that helped most, from fundamentals and back-of-the-envelope calculations to building blocks, an answer structure, and AI mock interviews.

System Design fundamentals and abstractions#

I started with the course’s fundamentals and abstractions. They forced me to ask a question I had been avoiding. What workload am I serving? I stopped collecting diagrams and began sorting prompts through choices such as horizontal scaling, load balancing, caching, sharding, replication, and consistency.

I asked about the read-to-write ratio, availability target, and 99th-percentile (P99) latency before naming components. A read-heavy redirect path may need replicas and a cache, while a write-heavy ingest path may need a queue and partitioned writes.

The same first questions sort two prompts into different designs
The same first questions sort two prompts into different designs

The figure shows a read-heavy path and a write-heavy path leading to different building blocks.

Neither choice is universal, which was the point I had repeatedly missed.

P99 changed my questions during practice. Average traffic helps estimate capacity, while P99 exposes tail behavior that averages hide, including cache misses, overloaded replicas, and hot partitions.

The AWS reliability guidance helped me connect reliability claims to failure handling and recovery, so redundancy always came with a recovery plan.

Quick check: Pick any component in your last design and name the measurable reason it is there.

Early on, I started by drawing services. Later, I spent the first few minutes clarifying read volume, write volume, and the availability target. Estimates then forced me to defend each choice.

Back-of-the-envelope calculations#

Using the method from the course’s resource estimation examples, I made my first useful estimate, for a URL shortener handling 100 million redirects daily. Dividing by 86,400 gave roughly 1,157 average reads per second.

For a first-pass interview estimate, I assumed a 10x burst during a short evening window, or about 11,600 peak redirects per second. I would validate that multiplier with request logs or a traffic model.

From daily redirects to peak load, storage, and the hot-key risk
From daily redirects to peak load, storage, and the hot-key risk

The figure traces the estimate from daily traffic to peak load and storage, and marks the hot key as the risk that averages hide.

Those numbers did not select a database for me. They narrowed the questions. Can storage serve peak reads? Can cache hits meet P99? Can one key become disproportionately popular?

For storage, I assumed a ten-to-one read-to-write ratio, which meant about 10 million new links daily. At 500 bytes per logical record, that came to about five gigabytes per day before replication.

Three years approached 5.5 terabytes of logical primary data, before separate factors for indexes, replication, backups, and compaction. The exact result mattered less than stating which assumptions I would revise after receiving requirements or collecting production measurements.

Practical tip: I stated my assumptions aloud before doing the arithmetic. That made gaps visible and gave my interviewer a way to correct the model.

It’s tempting to jump straight to Redis and sharding without naming the constraint. A hot key can damage P99 while average queries per second (QPS) looks safe.

The distributed cache lesson lists hot keys among the limits of its first design. Because that case dominated the tail, I prioritized request coalescing and per-key rate limiting before adding more database shards.

Building blocks like load balancers and caches#

Definitions were never my problem. I added load balancers and caches because I had seen them in diagrams, then struggled to explain why they were there. Practicing the URL shortener changed that, because each component had to answer a specific constraint.

The cache came first. Redirects are read-heavy, and adding application servers doesn’t relieve a database read bottleneck. I used cache-aside. The service reads the cache, loads a miss from storage, and writes the result back.

The cache-aside read path, with invalidation and single-flight loading
The cache-aside read path, with invalidation and single-flight loading

The figure follows one redirect through the cache and shows where invalidation and hot-key protection fit.

Editing or deleting a link needs invalidation, or stale redirects survive until the time-to-live (TTL) expires. For a hot key, single-flight loading stops many requests from rebuilding the same entry at once within each process.

The load balancer came second. My first design had one load balancer in front of the app servers, which made it the single point of failure for every redirect. A 99.99% availability target ruled that out.

Adding a second load balancer in an active-passive pair, with health checks and a shared virtual IP address, changed the answer. The cost was a failover delay to measure and one more component to monitor.

Watch out: A standby load balancer helps only if failover has been tested. I treat an untested standby as a gap in the design.

Each building block now has to name the problem it solves before it goes on the whiteboard.

RESHADED approach#

I learned Educative’s 45-minute answer structure, RESHADED, from the course, and it gave me a written route through each interview in place of another architecture to memorize.

It stopped me from spending the first 20 minutes on service names before agreeing on requirements. Skipping requirements leads to overengineering, because the reasons get invented afterward.

How the URL shortener answer unfolded
How the URL shortener answer unfolded

The figure follows the answer from the first questions to the part that made the design unique.

I started with functional and non-functional requirements. Then I asked about traffic, availability targets, and acceptable staleness.

Asking whether 99.9% or 99.99% availability mattered changed the design. Those targets allow roughly 43 minutes or 4.3 minutes of monthly downtime, respectively, which affects redundancy, deployment strategy, monitoring, and incident response.

For a URL shortener, POST /links could create a record and GET /{shortCode} could perform the redirect. The schema needed a uniqueness constraint on shortCode, plus an owner, destination, expiration time, and redirect status. Writing this down exposed decisions that a box labeled “database” hid.

Quick check: Before you name a service, state the requirement it serves.

Evaluation made me justify how the design met each requirement and name its trade-offs, including what would fail first, such as replica lag or a cache outage. The distinctive component step pushed me to name the challenge unique to the problem.

For a URL shortener, that was generating unique short codes at scale.

AI mock interviews#

AI mock interviews caught a habit that reading hid. Each session ran about 45 minutes and moved through clarifying requirements, high-level design, API and data model, and detailed design.

The questions got harder as the session went on, and the AI interviewer pushed me to defend trade-offs. The course also has mock interviews for specific design problems, such as a distributed cache and a newsfeed, so practice can follow many of the design lessons.

Feedback came as a rating from Unsatisfactory to Excellent, with notes on what I handled well and where I fell short.

This kind of feedback tends to flag naming technologies such as Redis, Kafka, and sharding without tying them to an agreed requirement. Reviewing my answers afterward also showed where I skipped trade-offs or promised failover without spare capacity.

Practical tip: Treat each mock like a real interview. I kept to the time limit and wrote one review note per session listing what I left out.

The concrete improvement was that I could explain a trade-off, an API, and a failure mode in the same session, and service names only supported those explanations.

For the next design problem, I use three steps. I clarify the workload and reliability requirements, estimate traffic and storage with explicit assumptions, and find the first bottleneck and failure mode before naming technologies. That process won’t guarantee an offer. It does give me a clear way to show my reasoning.


Written By:
Code Kai