Video guide
18:55 · 9 August 2024
Frontend System Design Interview Walkthrough: Build Google Search
Chapters 6 sections
Key concepts in this video:
- 01
1. Dig Into Requirements Before Solving
Functional requirements: an input, a search button (mandatory on mobile — hitting enter is hard there), a suggestion list.
Non-functional: who are the users? How much accessibility — a government or finance client means AA/AAA, most companies don't. Internationalization? Browser support?
Don't jump to debouncing and caching in the first minute. Mentioning solutions too early reads as assuming too much.
Functional requirementsAccessibility levelsScoping - 02
2. The Four-Step Structure
Components → state → state mutations → styling. Write it down as you go.
At the end, zoom out, screenshot the board and email it after the call. When the interviewer hangs up, every other candidate left them nothing — you left an artifact of structured thinking.
Interview structureLeaving artifacts - 03
3. Components & Essential State
Components: a reusable input (with typing listeners), a search button (label + onClick props), a suggestion list.
State: the search query, the suggestions array, and the network trio — loading, error, data. State comes from user interactions and network calls; 99% of the time, nothing else.
Component structureEssential stateLoading / error / data - 04
4. State Mutations & Debouncing
On every keystroke: update the query, fetch suggestions. Untamed, a fast typist DDoSes your own backend.
Debounce the handler: fire only after ~300ms of silence since the last keystroke. Throttling is the sibling — one call per interval regardless — better for streams, worse for typing.
Tune the interval: debounce three seconds and users think there are no suggestions at all.
DebouncingThrottlingEvent handlers - 05
5. The Suggestion Data Structure
A suggestion isn't a string. It's an object: a unique id (your stable React key — never the array index), the text, and an order field for consistent ranking.
Expect the follow-ups: why the id? why not rely on array order? Have the re-rendering answer ready.
Stable keysData modelingAPI shape - 06
6. Accessibility: The 80/20
Semantic HTML first: real input, button, ul/li — not divs with click handlers. ARIA labels only where semantics can't reach.
Then the tab order: input → suggestions → search button, matching the visual flow, so keyboard users can drive the whole thing. Cover this and you're ahead of most candidates.
Semantic HTMLARIATab order - 07
7. Performance & Caching Strategy
Of the three performance pillars, responsiveness matters most here: debounce interval + memoized list rendering with stable keys keeps INP healthy.
Caching has layers: most-recent searches in the browser (private cache), most-frequent searches for all users at application level (Redis, or even the CDN — suggestions are just small objects).
Know your cache eviction answer: least-recently-used beats least-frequently-used when trends die.
INPPrivate vs shared cacheCache evictionRedis
Transcript
If you're a front end developer and you don't want to bomb your next system design interview, then you better watch this. We are going to go to one of the most commonly asked system design interview focused on the front end. This is a real system design interview question that got in one of those interviews. He of course passed that interview and today he's going to show us how he did it, he's going to show us a structured step-by-step way for you to use when you face your next system design interview.
Are you ready? Perfect, this is my screen. Yes, I see your screen, I see a search bar there with some results. Maybe you can walk us through the problem first so we understand what we're talking about. And then you can let us know how you went about it and how you passed this interview. Perfect. So, what they come me with was something like this and basically an empty drawing board and they told me we are building a search component with an auto complete.
And I just went ahead and said, hey, how would you go about it? And that's one of the biggest challenge. If you don't have a structure, you will come across as non professional or as a junior. Uh because you could start literally anywhere when I come to you with it. So, the requirements are there's this interface, user type in a search bar and as they type, they see this search suggestion. The first thing you want to do in any of those interviews is to dig farther into the requirement and maybe you don't discover anything new, although most of the times you will, but it will show that you're then going into solving the problem first.
And there's two kinds of requirements. There's the FRS, which would be um functional requirements. To be like, what does the app needs to do? So, we definitely need an input, and we definitely need a button for search. In this case, there's no button, we see in the Google case, but you could add a button or not. And then there's a list place. For example, the button, the button would be mandatory on mobile.
Because on mobile, it's not so easy to hit enter sometimes, but when you're on a PC, it's very easy. to to search on enter. Now, when it comes to the non-functional requirements, I mentioned this, there's two type of requirements. Then you want to look at what is how user base, how much do we need to invest in accessibility. If you're working for or interviewing with a financial institution or and more old style old style corporate or the government, they will want to be very, very accessible.
By the standards of A11y, this would be a triple A. But most companies don't need that kind of coverage. Then there's web security, and then there is web performance. Looking at it as a front engineer, talking about performance, we already uh you're probably quering an API to get those results. Uh you don't want to overquery that that that will be one of the major issues and then probably caching those results.
Yes, but again, you don't want to mention those at the beginning of the interview because it will feel like you got there too fast and they will feel like you're making too many assumptions. And uh we don't want to make too many. So right now, I would just mention them and ask them about it. Like, how important is it? You know, does this needs to be international? Do I need like several to support several languages?
Uh browser? This is really important for the front end. That's pretty much all the requirements you want to excel. And once you have the requirements, we can go into actually building this. And I will follow a very structured way. But basically, we will want to build the UI, uh go into the state, component structures and what not, to satisfy the functional requirements, and then go over scalability at the end and all the non-functional requirements.
So let's move on into actually building. And of course you want to get buying for the interviewer, so you want to be always speaking out loud. But also, make sure you write things down because at the end of the interview, I usually all the time, zoom out, take a screenshot, send it to them in an email. Because once they hang up the zoom call, they have nothing to show that I'm different. If you have this written down, it shows that you are very structured, methodical thinker, and also you have something to show when the interview is over.
Which is very important in the current market where you are probably competing with many other great front-end engineers. And the other thing, it's senior developers are structured in their thinking. Awesome. So now you said we're going to move on to breaking the UI, right? Breaking those functional requirements into the the components. Yes, we will go for the functional requirements. And in that case, the flow, I always you always want to follow, is number one.
You want to look at the component, especially because in this interview, they told us that this have to be usual components. After that, we want to look into state, and after that, we want to look into state mutations with user interactions and data. And finally, they might make you talk a bit about the styling. These are the steps I would always follow. months. So, if we look at this UI, we are breaking down into components.
We go really quickly. And of course, this is an interview, so you have to be slow and fast at the same time. You cannot be too slow and too explicit, but you um you need to take your time and explain at least the important part. So, that's our input field. This would be my button. I have a search here. Just out of curiosity, how much time you had to do this interview? Uh I think it was one hour chat.
But um you know, between greetings and all, you might have half an hour for it. So you need to do all these steps and make sure you mention everything that's meaningful in in about 30 to 40 minutes, right? Yes. The problem is if you are too slow, you're perceived as you didn't make too much progress, and if you are too fast, you're probably skimming through things. But another problem most people have is they don't know where to start or they run out of things to say, which should never be a case for an experience engineer.
You should be able to talk about these kind of things for a week. And then they ask me a bit about reusability. So, okay, like the search button is pretty easy to make reusable. You just have a a prop, in this case, it was a react um based interview. So we had props. And then you have an on click and a title, right? And maybe maybe some other props. The input, it's a bit more complex because you have on type listeners.
And then these two are just list headers, basically rendering a list of elements. So that would be my component. The second thing, it's state. And to identify the state, we always want to look at the things that actually change in our UI. So, what's actually changing right now? Well? Well, we definitely have the user typing and be careful because it's usually either using interactions. That changed things or exactly external calls, which is usually over the net.
Yeah, you might have like local storage or some some edge cases you might have browser notifications. Yes. It's not always the the network, yeah. Yes, but 99% of the cases, it will be using interactions or external calls over the network. That's also an API for the people for the people watching us, sometimes they give you the API or they tell you a few words about the API, or worse, they want you to have an opinion about how the API will look like if we're talking about the back end for front end where the front end developer, it's involved in defining those API, those interfaces.
Senior developers, senior front end developers, I suppose, you know how to design a rest API or even a graphical end point because they might end up having to do that when they build a back end for front end. It's a front end team that usually owns the BFR in most um technology companies so. We're going to go ahead and write uh really quickly the uh the state, that would be the search query. Let's call it that way.
Um then we have our suggestion place, that would be an array of strings. I'm going to add the type here, string array. This would be a string. And then we have because we we are getting the suggestions over the network, we have like the data slash loading slash error kind of the network client state right. Yes, exactly. Number three, we said we're going to talk about the the state mutations, which okay. The state mutations come from user interactions or external calls and state is just what changed.
I'm going to move all this. So what are what are the user interactions? Well, first of all, they can type and when they type, we can trigger the on change and update basically the search query. I'm going to put here user type. You might have the user either click search or hit enter. That's a usability thing to have search on enter and then we might have data arriving or errors over the network or the loading state.
So these are our state mutations. The first thing you want to mention here and they would ask is what happens when the user type? What what is a state mutation? And then you go into, okay, when the user types, let's have an arrow here. So the user goes ahead and type. What will happen? It's just as pseudo code, let's imagine I'm writing the pseudo code for on uh for when the user types. First of all, you want to update the search query.
And second of all, you want to trigger to the API to get the suggestion. Yes. Now the problem here is we will end up D DOSing. If they type really fast, it's a very long query. We'll end up uh D DOSing which is it's a denial of service attack. Uh because we're making too many requests to our back end, so our back end will go down. If you have so many users typing and launching all these requests. Um so this is when you want to mention de-bouncing.
And whenever you have an input field and user type, de-bouncing or throttling would be applicable. will also reduce your maybe reduce your AWS bill, yes, in the process. Make sure you know how to explain both of those, how they work. Just to explain, make a quick fantasy here. can elapse since the last call to our event handler. So we debounce the event handler. Perfect. So that would be debouncing. Throttling would be that even if they make like 50 requests, we only send one every 5 seconds. So we kind of control the flow. Throttling is much better when you're streaming data, when you're streaming video. Debouncing is good when you have user interactions. as users type. Um, perfect. So following a process, component structure, state, state limitation, and then they'll ask you a bit about styling. with a bunch of flex boxes, you are you are done. The other thing is over here we have a list of different elements and you need to make sure they have a unique key prop. If you're using React, that ideally comes from the backend to avoid re-rendering. They did ask me what would be the data structures I would use. So, how would a suggestion, for example, how does the suggestion look like? And in this case, um, because a lot of people might think, oh, a suggestion could be just text. But in reality, it has to be an object because it does have a unique ID. To have an ID, that would be something like a unique UUID, and then uh whatever the suggestion is. Say text. The other thing is to to keep these things consistent. You see they appear in order. So to render them, you might also have some sort of priority. Because um you can't just rely on the array to render them. They have different priorities. So maybe we have here an order, that's a number. Let's say the first one would have zero, and the next one would have one, and the next one would have a two. So that will ensure consistency. So they might ask you, why, why did you had an ID? Do you really need an ID? And, you know, all that kind of stuff. So do you really need an order? Can you rely on the array order for rendering it? And you need to explain why is that a bad idea. Okay, this will uh fulfill most of the functional requirements, and now I would go over non-functional requirements. And so if we look here, we kind of have all the users' interactions mapped out. We have the state, we have the state transitions, and the next thing would be, for example, accessibility. How would you make all this accessible? The answer there, I'm going to go over here and add all these topics as individual topics. So we go over to accessibility. And here I would say, for the most part, you go away with HTML with semantic HTML. What does it mean? Everything that's not a div or a span. So don't use divs and spans, use input fields, use buttons, use list elements, use ULs, like unordered list elements.
UI we have probably input button, lead or list, and then a UL or OL for the suggestion. Now, you might uh got into the case where you cannot use semantic HTML, so you'll need some area label to specify for non-semantic tags what is their role in the AOM, the accessibility object model. It's like the dome, but for the accessibility part of the browser. And the last thing you want to mention here is the tab index or the tab order.
And what's very important is that the way if I press order um if I press tab, the way these elements get selected is the same natural order in which they appear. So if I press tab, I select the input, then I select the search, that wouldn't be too good. Because I really want to press tab, and go from the input to the suggestion, select the suggestion, and then if I press tab again, go to the search.
So the tab index in this case should be one, right? The tab order, then two, two, three, four, five, all the suggestions, and then finally it should be the final one. Right. Very, very important detail. You go from here, to here, to here, to here, and when you're at the end, finally. So someone without a mouse can navigate this perfect. Yes, and that's all for accessible. If you mention all these, you're already like a top candidate.
That's about, you know, 80-90% of everything you need to know about accessibility as a as a front-end engineer, what you what you have there. Let's talk a bit about performance. I know caching, it it's a big deal. Of course, uh one thing I wanted to to add like about this tab order or anything you've done so far, bogen needs. For senior developers, the the details in the details. Uh if you look, uh you are able bogen to to cover this last mile.
Those little details, you do have an opinion about it. You know, the the component search here is quite intuitive, uh putting together some state with React. Anybody might get there, but it's that's not what makes you a senior. It's it's kind of these these little details where you know accessibility, you know the mutations, you know everything before starting to build. So this is this is something you want to develop. If you're a junior, mid developer, looking to be considered more of a senior dev, should do is there's actually a thinking model behind it and they play that to the problem context. So, um web performance, as always, the three pillars of web performance are number one, loading speed, number two, um layout stability, so things that move around when they're not expected to, and number three, responsiveness to, okay? The UI doesn't get stuck. Exactly, we want things to load fast, we want them to be stable, not to move around, and we want things to be responsive on user types. For this UI, the probably most relevant one are two and number three. Because we are not in the case where we're not you know SEO or e-commerce where people land on a page there's huge images. So loading speed, because these are only for the most part, they are native native HTML elements, they will be loaded pretty fast. And there's not so much JavaScript in this file, like if you look at the interactivity, there's not going to be a lot of JS. So I I would assume loading speed would be decently fast. So we mentioned layout stability and responsiveness to input for this, this is more important when users are typing and the search going to be uh testing move down. You might have a loading indicator or you might show them great out, just not to move these things a lot. But then this is the most important one, responsiveness to input. So when I type, right, as I type, um I have this fluent feeling, and there's two sides of that. Number one was the debouncing, so the fact we don't make that request all the time will make things more responsive. So debouncing, but we don't want to debounce too much. Because then the users will have the feeling that there's no suggestions appearing if you go and debounce for three seconds. So your debouncing interval interval, it's important and then you want to mention the rendering. So if you're using something like React or any of those frameworks, you really want to make sure that you're using things like use memo and memo um for example use the the react.memo for this component for the list and stable key so you avoid. And that will make sure that your interaction to next pain, which is the CLS, the core web vital that measures the responsiveness to input. I'm just going to write it here, folks, make sure you look this one up interaction to interaction to next pain. I think it's ENTP or something like that. Interaction to next pain, yes, the ETMP. It's a new metric, metric and lighthouse, and this is the one that measures if I type, how much time it takes until we
paint browser. Um, really important for this specific problem. We have caching of suggestions, suggestions, and rendering. Um, and for the caching, when you say caching of suggestions, uh is this caching the results or is this caching the most frequent searches that the user actually chosen from? That's something you would have to decide. So, you could cache the most frequent, so most recent, and you could also cache the most frequent.
And you could do this at user level, in a private cache, in a browser cache, or you could do this at application level for all the users. So, what I mean is application level. Imagine the European Cup was a couple of months ago and everybody's looking for the name of a specific player because they they stand out. You could actually cache that at the application level because you know a lot of users will need that.
So, you could cache that in a public cache, in this case, you could even do it in a CDN. Because suggestions are just those objects, we saw they are relatively simple objects. So, you could cache that either in a redis, redis style cache, you know here, something like a redis, right? And then um distribute it somewhere. So, you have a distributed cache. Or most frequent, what do people search most frequently? In the case of Google, I guess there are some searches that everybody look for.
I don't know, how to change car oil, for example. That's something that people every once in a while, everybody look, and that would be the most frequent. They might ask you about your cache eviction strategy. So, cache eviction, and this is the opposite of what you're caching. For example, list use. So, it's either the the one that the the cache that nobody's really using or the one that has used a very long time ago, like last year.
Maybe it was very frequent, but it was just a fad, it was a trend. Nobody remembers the name of the player that won the early two years later. So, you can empty your cache, but this should be quite an advanced for sure. If you want to go in depth, you could also specify the shape of the cache in the at user level. So, imagine we are getting an array with all these suggestions. So, I would imagine you type something, like let's type let's say I type this, I type the and I get some suggestions for it.
From the back, I get an array of suggestion objects and I could cache that. So, if you go ahead and type this again, I retrieve it from browser cache. I have all my suggestions here, suggestion object. These are the one way to store it. There are smite smite ways to store it. We don't need to go so in there. You could actually store all this in a single again, and then have this store a mapping. Instead of storing this, imagine I have a cache, I store all those objects and they have a unique ID in my cache.
To make this more efficient, I store it like this, and then I reference to my cache, you know, when when I have here one, I reference to the actual cache. the uh the mapping to this up. So there's different ways to store this. We can do a whole interview about caching. And this is one thing I wanted to say because I mean we've been working with a lot of front end engineers, purely front end engineers and they usually struggle with the topic of caching.
Because this is not something that we do very often. A lot of front engineers that know how caching actually works. They know all the different ways you can cache on the client side, uh you talk about Redis. Many of them never really um had to deal with something like that. So one thing you want to do if you are going to have a system design interview in the front end uh is to do touch some back end uh some back end topics like data structures.
uh topics like caching. How deep should you go into those things? Not as deep as a back end engineer, but they will come up and they will be expected to have an understanding about them. My last question for you, what advice would you give to people watching us that are going to face a similar interview in the upcoming um weeks? So probably one of the most important thing leaving aside your overall knowledge, which you cannot really multiply in the next couple of days, it's your delivery.
So how structured and how can you lead this interview? And probably the gold thing you can take away from here, it's the structure. So first, we want to look at functional requirements. Then we guide it down the non-functional, but we won't dig into them yet. Because that will side track and then we go into functional requirements. By looking at the component structure, state, the state mutations, which come from user interaction and data.
And finally, styling. And once you do all that, you should arrive to something like this, a clean component structure, a clear idea of the state, and a clear idea of user interact. Once you have that, it's extremely easy to add the layer of accessibility, web performance, web security, and all the non-functional requirements on top. Amazing, I mean you've done an amazing job and folks one thing I wanted to say is we have people watching those videos just because it looks easy.
easy when Bogdan does it doesn't mean it will be easy when you will do it. So we do invite you whatever you see on our channel to try these things yourselves after you see Bogdan. Okay, if not, there is no way for you to to actually learn. I mean, you can watch some content, feel good about it, you probably learn a lot. But in the end, we do advise you to go ahead and do them yourselves, which brings me to the next point.
If you want Bogdan Knight to go into any specific interview or to do more of those videos, just let us know in the comments. The other thing is if you are interviewing now or if you are interested in leveling up. As a JavaScript engineer towards the senior level and beyond, the most important is to find out what your gaps are, instead of just chasing frameworks. With that being said, thank you so much, amazing interview.
Great performance and we will see you folks in the next one.