AlgoInsight

Free lesson · Frontend System Design

The five most expensive minutes of your interview are the first five

Easy10 min readfrontendsystem-design

Watch what most people do when the interviewer says "design a photo-sharing feed." They nod, they pick up the marker, and they start drawing. A component here, an API call there, maybe a box labeled "CDN." They're producing output within thirty seconds, and it feels productive, and it is almost always the wrong move.

Here's why it's wrong, and I learned this the hard way. When you start drawing immediately, you are silently making a hundred assumptions - about who the user is, what "feed" means, what scale matters, what the constraints are - and you're making all of them invisibly. The interviewer can't see your assumptions. They just see you confidently building something that might be solving the wrong problem. And when, twenty-five minutes in, they reveal a requirement you didn't ask about ("oh, this needs to work offline"), you have to tear down half of what you built, on the clock, while looking rattled.

The fix is a framework. Not because frameworks are clever, but because under time pressure and adrenaline, your improvisation collapses and you need rails. The industry-standard rails for frontend system design are called RADIO - it comes from GreatFrontend, it's widely used, and I'm going to teach it to you straight, with credit, because pretending I invented a five-phase structure to avoid naming theirs would insult your intelligence. Then I'm going to add one thing of my own that most people skip, and that addition is, in my experience, the single clearest "this person is senior" signal you can send.

Interactive animation: RADIO's five phases in order, with the biggest share of the time - about 35% - kept for Optimizations.

RADIO, one letter at a time

RADIO is five phases you move through in order: Requirements, Architecture, Data model, Interface, Optimizations.

graph TD
    R["R - Requirements<br/>(~15%)<br/>What are we actually building?"] --> A["A - Architecture<br/>(~20%)<br/>What are the components?"]
    A --> D["D - Data Model<br/>(~15%)<br/>What state exists, where?"]
    D --> I["I - Interface / API<br/>(~15%)<br/>How do pieces talk?"]
    I --> O["O - Optimizations<br/>(~35%)<br/>Performance, a11y, resilience"]
    O -.->|loop back if a requirement<br/>was missed| R
This is a top-to-bottom flowchart of the RADIO framework's five phases, each with a rough share of your time. Requirements, about fifteen percent, answering what we're actually building. Architecture, about twenty percent, defining the components. Data model, about fifteen percent, deciding what state exists and where it lives. Interface or API, about fifteen percent, defining how the pieces communicate. Optimizations, the largest at about thirty-five percent, covering performance, accessibility, and resilience. A dotted arrow loops from Optimizations back to Requirements, showing you should revisit requirements if you discover you missed one.

R - Requirements: the phase everyone rushes

Interactive animation: Functional requirements say what the feed does; non-functional ones - devices, network, accessibility - are where rounds are won.

This is where you turn a vague prompt into a bounded problem. You split it into two buckets.

Functional requirements are what the thing does. For a feed: it displays posts, supports infinite scroll, lets you like and comment, refreshes for new content. You pin these down by asking questions, not by assuming.

Non-functional requirements are the qualities it must have. This is where frontend rounds are won, because these are the constraints that drive every later decision: What devices? (Mobile-first changes everything.) What network conditions? (If 3G matters, you're designing for offline-tolerance and tiny payloads.) Accessibility requirements? Internationalization? Performance targets - is there a first-paint budget?

Tip: Ask about scope explicitly and write the answers down in a corner of the board. "So: mobile-first, global audience including slow networks, must be keyboard-accessible, infinite scroll, no offline support needed for v1." That one sentence, said back to the interviewer, does three things - confirms you understood, locks the scope so you can't be ambushed later, and demonstrates you know which questions matter.

The mistake here isn't asking too few questions - it's asking generic ones. "How many users?" is a backend reflex and it lands flat in a frontend round. The questions that signal frontend seniority are about the user's conditions: device, network, locale, accessibility, the performance bar.

A - Architecture: the component decomposition

Now you draw - but you draw components and their relationships, not implementation. For a feed you might have: a feed container, a post component, a post-list (virtualized), a composer, a network/data layer, a client-side store, and a cache. You show how data flows between them. You're answering: what are the responsibilities, and who owns what?

The senior move in this phase is to separate concerns cleanly - to show that your data-fetching logic doesn't live tangled inside your view components, that there's a layer responsible for talking to the server and a layer responsible for rendering. Interviewers read that separation as "this person has maintained a real codebase."

D - Data Model: what state exists and where it lives

Frontend has its own data modeling, and it's not the same as backend schema design. Here you're deciding the shape of client-side state: What's in the store? Is the data normalized (a flat dictionary of posts by ID) or nested? What's server state versus UI state versus URL state? Where does a piece of data live - component-local, a global store, the URL, the cache, persistent storage?

This phase is short but it catches people, because they've never thought of client state as something to model. We'll go deep on normalization and state location in Module 3; for now, in the round, sketch the store shape and say why.

I - Interface / API: the contract between client and server

Interactive animation: Two contracts, not one - the network contract between client and server, and the component contract between components.

What do the API calls look like? What's the request, what's the response, what's the pagination strategy (offset vs cursor - and for an infinite feed, you want cursor, and you should say why). What does the component API look like - if you're designing a reusable post component, what props does it take? This phase has two faces: the network interface (client ↔ server) and the component interface (component ↔ component).

O - Optimizations: where the round is actually won

This is the biggest slice of your time and the phase that separates a "fine" answer from a "hire" answer. Everything that makes frontend hard lives here: performance (lazy loading, code splitting, image optimization, rendering strategy), accessibility (keyboard nav, ARIA, focus management, contrast), network resilience (caching, retries, optimistic updates, offline tolerance), and perceived performance (skeletons, optimistic UI, prefetching).

You will never cover all of it in the time you have. Which is the perfect place to introduce the thing I add to RADIO.

My addition: name the gaps

Interactive animation: Junior, mid and senior signals: covering everything shallowly, omitting things silently, or going deep and naming what is left out.

Here is the pattern I see kill otherwise-strong candidates. They get to Optimizations, they have eight minutes left, and they try to cover everything - rushing through accessibility, performance, caching, and resilience in shallow, breathless bullet points. The result reads as panic. They'd have been better served going deep on two and explicitly naming the rest as out of scope.

Because nobody named the gaps for me when I was learning - interviewers just said "not quite ready" without telling me which foundational thing I'd skipped - I became almost obsessive about doing the opposite: stating, out loud, exactly what I am not covering and why. I call it naming the gaps, and it works for a reason that took me years to understand.

When you say "I'm going to go deep on caching and accessibility because those drive the most user impact here; I'm consciously not detailing the analytics or the i18n strategy, though in real work I'd handle them - happy to go there if you'd like," you have just demonstrated the single rarest skill in the room: knowing the boundaries of your own answer. A junior engineer doesn't know what they're leaving out. A mid-level engineer leaves things out silently and hopes nobody notices. A senior engineer leaves things out on purpose and says so. Naming the gaps is how you signal that level without saying "I'm senior."

graph LR
    subgraph Junior["Junior signal"]
        J["Tries to cover everything<br/>Runs out of time<br/>Shallow on all of it"]
    end
    subgraph Mid["Mid signal"]
        M["Covers some things<br/>Omits silently<br/>Hopes it's not noticed"]
    end
    subgraph Senior["Senior signal"]
        S["Goes deep on what matters<br/>Names what's omitted<br/>Explains the choice"]
    end
    Junior --> Mid --> Senior
This diagram contrasts three levels of seniority by how they handle scope in the optimizations phase. The junior signal: trying to cover everything, running out of time, and staying shallow on all of it. The mid-level signal: covering some things but omitting others silently and hoping it isn't noticed. The senior signal: going deep on what matters most, explicitly naming what's being omitted, and explaining the choice. The arrow runs from junior through mid to senior, showing naming the gaps as the marker of the most senior behavior.

Important: Naming the gaps is not an excuse to skip the hard parts. It only works when the things you do cover are genuinely deep. "I'll skip everything except the layout" is not naming a gap - it's dodging the question. The move is: go genuinely deep on two high-impact areas, then name the rest as deliberate scope decisions.

Putting RADIO to work: a 30-second mental dry run

Let me show you the shape of a RADIO answer at high speed, so the phases feel concrete before we spend a whole lesson on the worked example. Prompt: "Design a typeahead search."

That's a complete, senior-shaped answer skeleton in under a minute of talking, and you can see exactly where the depth goes and where the gaps are named. The next two lessons fill in the two things this skeleton assumes you can do: spend your 45 minutes wisely, and then actually execute this on the autocomplete problem end to end.

Interview: Announce the framework at the start: "I'll work through this with a structure - requirements first, then architecture, data model, the API and component interfaces, and I'll spend most of my time on optimizations." Saying it does two things: it tells the interviewer you have a method (so they can follow and won't interrupt to redirect you), and it pre-commits you to spending real time on requirements before you draw, which is the discipline that's hardest under adrenaline.

How RADIO actually breaks

A framework is only useful if you know its failure modes, so let me show you the specific way each phase goes wrong in real rounds. I've done most of these myself.

Requirements breaks by being too generic. People ask questions, which feels right, but the questions are reflexive backend ones - "how many users, what's the QPS" - that don't change a frontend design. The phase fails not from too few questions but from questions that don't bind anything. The fix is to ask only questions whose answers fork your design: device, network, accessibility, interaction model, data location.

Architecture breaks by being implementation instead of structure. People start naming React hooks and CSS frameworks. The interviewer doesn't care whether you use Redux or Zustand yet - they want to see responsibilities and boundaries. The phase fails when you describe how you'd code it instead of what the parts are and who owns what. The fix is to draw labeled responsibilities and data flow, and defer library choices to a sentence each in Optimizations.

Data Model breaks by being skipped. This is the most-deleted phase under time pressure, because people don't think of client state as something to design. So they jump from architecture straight to the API, and they miss the chance to show they understand server-state versus UI-state versus URL-state, normalization, and where each piece of data should live. The fix is to spend even two minutes here naming the store shape out loud - it's cheap and it's a strong signal because so few candidates do it.

Interface breaks by only covering one of its two faces. People define the network API and forget the component API, or vice versa. For a reusable component the props contract is half the question. The fix is to consciously address both: the client-server contract and the component-to-component contract.

Optimizations breaks by breadth-panic. Covered already, but it's worth restating because it's the most common single failure: with time running low, people sprint through every optimization shallowly instead of going deep on two and naming the rest. The fix is the gaps overlay.

graph TD
    R2[Requirements] -->|breaks when| RB[too generic / backend reflexes]
    A2[Architecture] -->|breaks when| AB[implementation, not structure]
    D2[Data Model] -->|breaks when| DB[skipped entirely]
    I2[Interface] -->|breaks when| IB[only one of its two faces]
    O2[Optimizations] -->|breaks when| OB[breadth-panic, all shallow]
This diagram pairs each RADIO phase with its characteristic failure. Requirements breaks when questions are too generic or fall back on backend reflexes. Architecture breaks when you describe implementation instead of structure. Data Model breaks when it's skipped entirely. Interface breaks when you cover only one of its two faces, the network API or the component API but not both. Optimizations breaks under breadth-panic, sprinting through everything shallowly instead of going deep on a few.

Note: Notice that three of the five failures are about discipline, not knowledge - generic questions, jumping to implementation, breadth-panic. That's the encouraging part. You don't need to know more to fix them; you need rails and a clock, which is exactly what the framework and the next lesson give you.

What you should carry out of this lesson

RADIO gives you rails: Requirements, Architecture, Data model, Interface, Optimizations, in that order, with the bulk of your time in the last phase. Use it not because frameworks are impressive but because adrenaline destroys improvisation, and rails hold when your nerves don't.

And layer naming the gaps on top of it. The interviewer is not looking for the engineer who covers everything - that engineer doesn't exist, and pretending to be them reads as panic. They're looking for the engineer who knows which things matter most for these requirements, goes deep on those, and is honest and deliberate about the rest. That's a real senior, and it's a posture you can practice into being well before you actually are one.

The framework tells you what to do in what order. It does not, on its own, tell you how to fit all five phases into the brutal 45-minute clock without rabbit-holing in Requirements and never reaching Optimizations. That's a separate skill, and it's where most well-prepared candidates still fall apart. Next lesson: the time budget, the failure modes, and how to recover when you're behind.

Back to Frontend System Design