System design basics for freshers: a beginner framework with examples
System design basics for freshers: a 7-step framework, 5 core building blocks and a URL shortener designed with a tested estimate of 3858 reads per second.
System design is the practice of choosing and connecting the components of a software system, such as servers, databases, caches and queues, so that it meets stated requirements for load, speed and reliability. A beginner framework has seven steps: requirements, estimation, API, data model, high-level design, deep dive and trade-offs. The worked example below applies all seven to a URL shortener, with tested Python code.
Last updated: 11 November 2026.
What is system design, and what do freshers actually get asked?
ByteByteGo's System Design Interview course describes the questions as asking candidates to design an architecture for a software system, such as a news feed, a search engine or a chat system, in an open-ended and loosely specified way. AWS frames the judgement through six pillars of its Well-Architected Framework: operational excellence, security, reliability, performance efficiency, cost optimization and sustainability.
Neither Amazon's nor Microsoft's careers pages state whether freshers get a system design round. Amazon's page on software development interview topics says most technical interviews include coding and system design whiteboarding, and it lists object-oriented design, databases and distributed computing among the topics. The same page puts its system design preparation video under a prompt for roles that need at least two years of experience. Amazon's online assessment for full-time student and graduate roles lists a coding assessment, a workstyles assessment and a work simulation, with no design step.
Microsoft's technical interviewing page names resiliency, high availability, auto-scaling, replication, CAP theory and partitioning as possible system design topics in a short 45-minute round, and does not say which levels get them. A fresher should prepare the fundamentals below and ask the recruiter which rounds apply.
What is a repeatable framework for a system design answer?
A repeatable answer moves from requirements to trade-offs in a fixed order, so no step is skipped under time pressure. ByteByteGo's System Design Interview course describes four steps in its chapter on a framework for system design interviews: understand the problem and establish design scope, propose a high-level design and get buy-in, design deep dive, and wrap up. The seven steps below expand those four and are a common convention, not a standard.
| Step | Question it answers | Output for a URL shortener |
|---|---|---|
| 1. Requirements | What must the system do, and how well? | Create a short link, redirect fast, keep links stable |
| 2. Estimation | How much traffic and storage? | 38.6 writes and 3858 reads per second, 3.0 TB over five years |
| 3. API | What does a client call? | One call to create, one to redirect |
| 4. Data model | What is stored, under which key? | Short code mapped to the long URL |
| 5. High-level design | Which components connect? | Load balancer, application servers, cache, database |
| 6. Deep dive | What is the hardest part? | Generating unique short codes |
| 7. Trade-offs | What breaks, and what was given up? | Cache staleness, redirect caching, consistency |
The numbers in the second row come from the calculation further down, which rests on invented inputs.
What building blocks do most designs use?
Five blocks recur in beginner designs, and each has a precise definition worth knowing.
A load balancer spreads incoming requests across several servers. According to the AWS Elastic Load Balancing documentation, it distributes traffic across multiple targets in one or more Availability Zones, monitors their health and routes traffic only to the healthy ones, which raises availability and fault tolerance.
A cache is a fast storage layer that holds a subset of data so repeat requests skip the slower primary store. AWS describes it as typically held in RAM, trading capacity for speed. Redis is an in-memory data structure store whose documentation says the name stands for Remote Dictionary Server and which keeps values under keys with commands such as SET and GET.
A database stores the system's durable records. Relational databases enforce structure through constraints such as primary and foreign keys, which PostgreSQL's manual says maintain referential integrity between tables. AWS describes NoSQL databases as designed for specific data models, with flexible schemas that scale easily. The SQL interview questions post covers keys and indexes with runnable queries, and the post on types of NoSQL databases lists the NoSQL families.
A message queue decouples the part of a system that creates work from the part that does it. Amazon SQS is described by AWS as a hosted queue for integrating and decoupling distributed components, with at-least-once delivery on standard queues. Apache Kafka is an event streaming platform that publishes, stores and processes streams of events, and keeps events with the same key in order within a partition.
A content delivery network (CDN) is a network of servers that stores copies of content closer to users, with the primary purpose, according to AWS, of reducing latency.
How do scaling and trade-offs work?
Scaling means adding capacity, and the two directions differ. Microsoft's Azure Well-Architected guidance says vertical scaling increases the capacity of one resource, such as a larger server, while horizontal scaling adds instances to spread the workload and suits work that divides into independent parts. Splitting data follows the same logic: the Azure Architecture Center's sharding pattern divides a data store into horizontal partitions that share a schema but hold different rows, and scales out by adding shards. The microservices vs monolith post covers the equivalent choice for application code.
Every block adds a trade-off. A cache can serve stale data, because the cache-aside pattern invalidates the cached entry on a write and repopulates it on the next read, leaving a window where a reader sees an old value. Consistency has a formal limit: Gilbert and Lynch proved in 2002, in the asynchronous network model, that a web service cannot provide consistency, availability and partition tolerance together, which is the basis of the CAP theorem. In Amazon DynamoDB, reads are eventually consistent by default and a strongly consistent read is an option.
The table turns these facts into a choice guide for the database decision.
| Need | Lean towards | Reason on record |
|---|---|---|
| Rows that must always point to real parent rows | Relational database | A foreign key keeps tables referentially consistent |
| A specific data model with a flexible schema | NoSQL database | AWS describes flexible schemas built for specific models |
| A read that must reflect the latest write | A store with a strong-read option | DynamoDB offers strongly consistent reads, but eventual is the default |
| Very large data on one store | Sharding, in either family | Shards add storage nodes and split the rows |
Worked example: how do you design a URL shortener?
A URL shortener turns a long address into a short code and redirects visitors who open the code. It is a standard practice problem: ByteByteGo's course, for one, gives it a chapter. The example follows the seven steps, and every number below is a hypothetical assumption, not data about a real service.
What are the requirements and the API?
The functional requirements are to create a short link for a long URL and to redirect a visit on the short code to the long URL. The quality requirements are fast redirects, links that never change and a short code. A REST-style API needs two calls: POST /links with the long URL in the body, returning a code, and GET /{code}, returning a redirect. The REST API explained post covers methods and status codes in more depth.
How do you estimate load and storage?
Assume 100 million new links a month, 100 redirects per new link, 500 bytes per record and five years of retention. The script turns those into rates and a code length. The estimate is plain arithmetic; how an algorithm's cost grows with input size, such as scanning every row against searching an index, is the subject of the Big O notation post.
new_links_per_month = 100_000_000 # assumption
reads_per_write = 100 # assumption: 100 redirects per new link
bytes_per_record = 500 # assumption: code, long URL and metadata
years = 5 # assumption: retention
seconds_per_month = 30 * 24 * 3600
writes_per_sec = new_links_per_month / seconds_per_month
reads_per_sec = writes_per_sec * reads_per_write
records = new_links_per_month * 12 * years
storage_tb = records * bytes_per_record / 1e12
length = 1
while 62 ** length < records:
length += 1
print(f"writes per second: {writes_per_sec:.1f}")
print(f"reads per second : {reads_per_sec:.0f}")
print(f"records : {records:,}")
print(f"storage (TB) : {storage_tb:.1f}")
print(f"62**6 = {62**6:,}; 62**7 = {62**7:,}; shortest code length: {length}")writes per second: 38.6
reads per second : 3858
records : 6,000,000,000
storage (TB) : 3.0
62**6 = 56,800,235,584; 62**7 = 3,521,614,606,208; shortest code length: 6The ratio matters more than any single number. Redirects outnumber creations 100 to 1, so reads dominate and a cache pays off, while writes stay modest at under 40 a second.
How do you generate short codes?
The simplest scheme gives each new link a counter value and writes it in base 62, using the digits and letters. RFC 3986 lists letters, digits and a few punctuation marks as unreserved URL characters, so a base62 code needs no percent-encoding. Counter-based codes never collide, but they are sequential and so guessable, and a single counter becomes a bottleneck at scale. Random codes with a uniqueness check, or truncated hashes with a collision check, trade that for retries.
import string
ALPHABET = string.digits + string.ascii_letters # 62 symbols, all RFC 3986 unreserved
BASE = len(ALPHABET)
def encode(n: int) -> str:
if n == 0:
return ALPHABET[0]
out = []
while n:
n, r = divmod(n, BASE)
out.append(ALPHABET[r])
return "".join(reversed(out))
def decode(code: str) -> int:
n = 0
for ch in code:
n = n * BASE + ALPHABET.index(ch)
return n
for i in (0, 61, 62, 125, 1_000_000, 6_000_000_000):
print(i, "->", encode(i), "->", decode(encode(i)))
assert all(decode(encode(i)) == i for i in range(100_000))
print("round trip ok for 0..99999;", len(encode(62**6 - 1)), "chars at 62**6 - 1")0 -> 0 -> 0
61 -> Z -> 61
62 -> 10 -> 62
125 -> 21 -> 125
1000000 -> 4c92 -> 1000000
6000000000 -> 6y3o5y -> 6000000000
round trip ok for 0..99999; 6 chars at 62**6 - 1Six characters cover 56,800,235,584 codes, more than the 6,000,000,000 records estimated, so a code stays six characters long, and seven characters would cover 3,521,614,606,208.
How do the cache and the redirect rule work?
The cache sits in front of the database and holds the hottest codes. This test puts Python's functools.lru_cache, which keeps the most recent results in process memory, in front of a dictionary that stands in for the database.
from functools import lru_cache
DB = {"aB3": "https://example.com/a", "xY9": "https://example.com/b", "q1Z": "https://example.com/c"}
db_reads = 0
@lru_cache(maxsize=2)
def lookup(code):
global db_reads
db_reads += 1 # a cache miss costs one database read
return DB[code]
requests = ["aB3", "aB3", "aB3", "xY9", "aB3", "q1Z", "aB3", "aB3"]
for code in requests:
lookup(code)
print(lookup.cache_info())
print("requests:", len(requests), "database reads:", db_reads)CacheInfo(hits=5, misses=3, maxsize=2, currsize=2)
requests: 8 database reads: 3Eight requests caused three database reads, because the popular code stayed cached. A per-process cache is private to each application instance, and the Azure cache-aside guidance warns that such copies can become inconsistent, so the guidance suggests considering a shared cache, such as Redis.
The redirect status code is a deliberate trade-off. RFC 9110 marks 301 (Moved Permanently) as heuristically cacheable and treats 302 (Found) as a temporary redirect that is not. A cacheable 301 lets browsers and caches skip the shortener on repeat visits, which reduces load but can hide those visits from click counts, so a service that must count every click may prefer 302 or 307.
What are the limits of a beginner framework?
A framework gives structure, not answers. The seven steps are a convention, interviewers may reorder them, and a four-step version, as in ByteByteGo's course, is equally valid. The estimate above rests on invented inputs: change the redirects per link and the storage and read rates change in proportion. The CAP result is a formal statement about three specific properties, and the practical choice between databases depends on the workload.
Interview rounds also differ by employer and level, as the Amazon and Microsoft pages show, so no framework replaces asking the recruiter what the round covers.
Where does system design fit in the FDE Cohort?
The Forward Deployed Engineer (FDE) Cohort is a Leap by Masai programme for engineers with hands-on technical experience, run as an in-person start in Goa, an online build phase and an in-person hackathon in Bangalore for qualifying participants, covering production Python, APIs, cloud deployment, LLMs, retrieval, agents, security and client engagement. Its curriculum lists blocks on APIs and access, client systems and cloud, and security, monitoring and cost. For a fresher it is a later step, because the page asks for hands-on technical experience.
Frequently asked questions
What is system design?
System design is the practice of choosing and connecting the components of a software system, such as servers, databases, caches and queues, so that it meets stated requirements for load, speed and reliability. In an interview it means sketching a service, estimating its traffic and storage, and explaining the trade-offs behind each component.
How should a fresher prepare for a system design interview?
Learn the five building blocks, practise one framework until the order is automatic, and work through two or three small designs such as a URL shortener with a back-of-envelope estimate. Also ask the recruiter which rounds apply, since Amazon and Microsoft publish different topic lists and neither says freshers always get a design round.
What is the difference between SQL and NoSQL in system design?
Relational (SQL) databases enforce structure through tables and constraints such as foreign keys, which keep rows consistent across tables. AWS describes NoSQL databases as built for specific data models with flexible schemas. The choice follows the data shape and the consistency a read needs: DynamoDB, for example, offers eventually consistent reads by default and strongly consistent reads as an option.
What is the difference between vertical and horizontal scaling?
Vertical scaling makes one machine bigger, for example a larger server or instance size. Horizontal scaling adds more machines and spreads the workload across them. Microsoft's Azure guidance says vertical scaling suits workloads that cannot easily be divided, while horizontal scaling suits workloads that split into parts that run independently.
Why use base62 codes in a URL shortener?
Base62 uses the digits and the uppercase and lowercase letters, 62 symbols that are all unreserved URL characters under RFC 3986, so codes need no percent-encoding. Six base62 characters give 56,800,235,584 combinations, which is enough for a hypothetical URL shortener holding 6,000,000,000 records, so the codes stay short.
Next step
Pick one design, such as a URL shortener or a notification service, and write the seven steps on one page with your own assumptions and arithmetic. The Forward Deployed Engineer (FDE) Cohort page lists the APIs, cloud and production blocks for engineers who already have hands-on technical experience.