Back to feed

What System Design Really Is: From One Server to a Photo App for Millions

The speaker shows why a single-server photo app must be redesigned from scratch on the road to millions: requirements, building blocks, end-to-end data flow, qualities, and costs. The interview round is the spoken exam of the same way of thinking.

Imported to Nodesdaily: (UTC+03:00)
Watch on YouTube — Yc8QS10payQ
Reading options

Device speech is unavailable in this browser.

Concept lens

Choose a technical term in this view to read its general definition, teaching example and use in the article.

No terms from our glossary were found in this view. The glossary does not cover every term yet.

Picture a photo-sharing app: users sign up, upload photos, follow each other, and scroll a feed of pictures from people they follow. You write the code, deploy everything on a single server, and it works perfectly; one machine comfortably serves the first few thousand users, holding all their data and photos. Then 10 million people start opening the app every day, and although the photo-upload code barely changes, the problems you must solve are completely different: where do hundreds of terabytes of user photos live, what happens when the server running the app crashes, how does the feed stay fast for a user in India when the server sits in the United States, and what happens when a popular account posts a photo and a million people try to view it at the same time. These are no longer problems solved inside a single function; they depend on how the whole system is designed and how its parts work together.

System design is the process of deciding what components a system needs, what each one is responsible for, how they communicate, and how data flows between them, so the system can meet its requirements. It operates one level above writing code: where code thinks in functions , classes , data structures , and algorithms, design thinks in servers , databases , caches , queues, storage, and the network connecting them. It also accounts for what happens when one of these components slows down or fails, and how behavior shifts as traffic and data grow.

Requirements: what it does, how well it does it

Every design starts with requirements, because a design cannot be judged until what the system must do is known. Requirements fall into two groups: functional requirements describe what the system should do, such as letting users upload photos, follow others, like posts, and view their feed in our photo app. Non-functional requirements describe how well it should do those things: the feed should load in under 200 milliseconds, the app should stay reachable even if a server fails, and uploaded photos must never be lost. Functional requirements decide which features, APIs, and components the system needs; non-functional ones shape how those components are designed, how much capacity is needed, and how failures are handled. Educative's walkthrough of functional and non-functional requirements makes the same point: according to Educative, the split is the blueprint for every later architectural decision, and a photo app for a hundred users can share every feature with one serving a hundred million while looking completely different inside.

Most large systems are built from a relatively small set of common building blocks . Clients such as mobile apps and browsers send requests, DNS translates a domain name into a server address, a load balancer spreads incoming requests across application servers, and application servers run the business logic. Databases hold structured data like users, follows, and photo metadata, while object storage holds the photos themselves; caches keep frequently read data in memory so the database is not queried every time, a CDN keeps copies of static content on servers closer to users so it arrives faster, and message queues move work that need not finish immediately into the background so the user never waits. Much of design is deciding which of these blocks are needed and how they should work together. Mehdi Akiki's building-blocks map reads each block with the same four questions: what it is, why it exists, when it shows up, and what breaks when it is misused; a cache exists because repeated reads are expensive, a queue because not all work belongs in the request path, a CDN because users are far from your servers.

End to end: a photo's journey

Watch these pieces fit together in the photo app. When a user uploads a photo, the request first travels through the load balancer to one of the application servers; the server writes metadata such as owner, caption, and timestamp to the database, then mints a presigned URL that lets the app upload the image directly to object storage. Once the upload completes, the system drops a job on a message queue for follow-up processing, and background workers pick it up to handle slower tasks like generating thumbnails or updating followers' feeds. CodeSnatch's lesson on object storage and CDNs confirms the model: according to CodeSnatch, databases are the wrong home for large unstructured files, S3-style stores offer cheap and endlessly scaling room with eleven nines of durability, and presigned URLs let the client write straight to storage.

The read path uses the same boxes differently. When another user opens the feed, the application server first checks the cache for the post list; if the data is missing, it reads from the database and stores the result in the cache for future requests. The images themselves arrive over a CDN, downloaded from a server near the user's location instead of fetched from the origin store every time. Each component earns its place: the CDN cuts latency, the queue keeps slow work out of the request path, the cache sheds database load, and object storage provides a scaling home for large files.

Qualities and trade-offs

System designs are usually judged on a familiar set of qualities: scalability , the ability to absorb more users, traffic, and data as demand grows; availability , staying reachable when users need it even as components fail; reliability , behaving correctly without losing, duplicating, or corrupting data; performance , usually measured as latency, how long a request takes, and throughput, how many requests the system handles over time; consistency , whether users and services see the same up-to-date view of the data; maintainability , how easy the system is to operate, debug, update, and extend; and finally cost , because a good design meets its requirements without spending more servers, storage, bandwidth, or engineering effort than necessary.

Improving one of these qualities usually means paying elsewhere. Adding a cache sheds database load and makes reads far faster, yet cached data can go stale and stay outdated until refreshed or expired. More replicas and redundancy can lift performance and availability, but they raise cost and make the system harder to operate. There is rarely one design that is best at everything; a large part of the craft is understanding these trade-offs , deciding which qualities matter most for your requirements, and being able to explain why one approach was chosen over another.

Start small, grow at bottlenecks, narrate in interviews

Real systems are rarely built in their final form on day one. The photo app might start with a single application server and one database, which is more than enough for the first few thousand users. As usage grows, distinct bottlenecks appear: the database overloads, image serving slows down, background work starts delaying user requests; that is when the component that solves the specific problem is added, a cache, a CDN, read replicas, or a queue. Adding all of them early mostly buys complexity, more things to debug, and higher cost without much value. Good design meets today's requirements while leaving room to scale as they grow.

Anyone working on the backend makes design decisions constantly, even on small features. Take the like button in the photo app: should the like count be cached, should the update happen synchronously in the request or be pushed to a queue and processed in the background, and what happens if traffic suddenly spikes because a celebrity post draws millions at once. Knowing design means reasoning through such choices, seeing the trade-offs, and explaining why one approach makes more sense than another.

Design also looms large in software engineering interviews. At many tech companies a system design round is standard for mid-level and senior engineers, and some firms run a simpler version for less experienced candidates. Performance there can shape the hiring level, which directly affects compensation. The format is usually open-ended: candidates get around 45 minutes to an hour to work through prompts like a URL shortener, a chat application, or a photo app like the one in this video; there is no single correct answer and nobody expects code that passes tests. Instead candidates follow a process much like the video's: clarify requirements, estimate scale, sketch a high-level design, then dive into a few areas such as the database, caching, data flow, and failure handling, explaining decisions and trade-offs as they go. TryExponent's 2026 guide notes the round is now passed on cost, failure modes, and operational judgment; InterviewLoop's seven-step framework recommends the same order of clarify, estimate, design, deep dive, and trade-offs. The shared lesson: no need to memorize common designs, because whoever understands the core blocks, the problems they solve, and the costs they introduce can reason about systems never seen before.

Visualization: nodesdaily AI

Key moments

  1. The single-server story and the scale wall
  2. Functional and non-functional requirements
  3. Blocks: balancer, cache, CDN, queue
  4. Upload and read flows end to end
  5. Interview format and how to win

AI commentary

"The speaker walks through every building block using a single photo app; the strength is concreteness, the weakness is generalizing from one example. My note: asking what each box costs, rather than memorizing boxes, is the most durable lesson here."

AI assessment

The strongest objection is this: the video teaches scale through a single story, the photo app. Real workloads produce different bottlenecks: write-heavy counters, read-heavy feeds, and consistency-hungry payment steps demand the same blocks in different balances. Generalizing from one example can turn into a reflex of pasting the cache-CDN-queue trio onto every problem.

There are gaps too: security and authorization, observability and alerting, data privacy and retention policies, deployment strategies and rollback plans barely appear. The question of in which percentile and geography targets like 200 milliseconds are measured stays open; the cost math is stated as a principle and left there.

The speaker's incentive is open: he promotes his AlgoMaster courses and newsletter. That does not make the content wrong, but it shapes the selection: the long interview section and the anti-memorization yet pro-framework message match the course's sales pitch exactly. Viewers should watch knowing this, learn the framework, and decide in their own context.

The practical takeaway is crisp: in the next backend task, write the requirements in two sentences, sketch the flow in boxes and arrows, and note the why and the cost on each box. For interview prep, the highest-return drill is rehearsing this round on three classics, the short-link service, the chat app, and the photo app, narrating cost and failure scenarios out loud each time.

Sources

6 links; no other published story cites them. Stories sharing a link do not confirm each other; a source's origin is not inferred from how often it is cited.

system design · scalability · interview · backend · architecture

Follow the topic

Before this story

A short reading order from earlier stories linked to this event by an editor.

Evidence and sources

Review permitted source passages, versions and origins.

KAYNAKLARLA OKU

Bu haberi açalım.

Hesap kontrol ediliyor…