A long-time favourite of FAANG companies, system design interviews have grown in popularity since they were initially introduced a few decades back. They are a standard part of any interview process for most backend roles. And now, they have eventually reached us, mobile engineers, who were more accustomed to demonstrating our technical design skills and architectural knowledge through take-home assignments.
The system design interview focuses primarily on those two topics: design and architecture. As a candidate, you will likely be tasked with the technical design of a mobile application or a feature. Something brief and vague, in the lines of:
- Design a photo-sharing app (i.e. Instagram)
- Design a messenger app (i.e. WhatsApp or Messenger)
- Design a newsfeed feature (like in Twitter)
The aim is to let you demonstrate how you tackle the process of transforming an abstract set of requirements into a precise and meticulous solution. It also allows your interviewer to picture the breadth of your knowledge through the different decisions you make along the way. While certainly not perfect, they have one significant benefit over take-home challenges: a considerable reduction of the time required by both candidate and interviewer.
In the current competitive market to hire great talent, big tech companies and small startups are regularly looking at new ways to streamline their hiring process. As part of that effort, more and more companies are adopting this type of interview, replacing take-home challenges for Android and iOS developer roles. In fact, I did it myself when growing my last team. We reduced our time-to-hire from 3+ weeks on average to just about one week. The change worked fantastically for both candidates and interviewers, but that's probably a story for another post.
System design interviews may seem a bit scary, particularly when you have never done them before or don't have much experience designing large applications serving millions of users and with dozens of engineers working on them. There is also an aura of mystery around how these interviews are set for mobile. If you have searched around, you have probably realised that there is plenty of materials, courses and fantastic books explaining how backend system design interviews work and with help to prepare for them, but not so much for mobile. We are rookies in the matter, and that's why I decided to share my experience tackling these interviews both as a candidate and interviewer.
You will shortly discover there is no reason to be afraid. Getting yourself comfortable preparing and passing this type of interviews (as you currently do with take-home challenges) is relatively easy with a bit of guidance and practice. And perhaps you may end up even enjoying them.
Most system design interview last around 45 minutes (sometimes they might be extended up to 1 hour) and they all follow a very similar structure:
- 6 - 8 min: Introductions and a brief prologue by your interviewer
- 4 - 5 min: Problem statement
- 25 - 30 min: Design and discuss your solution
- 5 min: Your time to ask questions to the interviewer
A rather typical mistake I have seen many candidates do, and I have done myself as well, is to assume you have 45 min to solve the problem since that's what the interview lasts. In reality, as you can see from the schedule above, you will have around 30 minutes to design your solution. Therefore, keeping track of time is essential. You want to distribute those 30 minutes in the best possible way, allowing you to cover as much as you can. And even during those 30 minutes, there will be interruptions. So better to come with a clear plan and enough practice to make sure you nail it.
💡 Tip: When you practice, do it with a timer and force yourself to hard-stop at 30 minutes. Then, review the topics you covered and list the ones you would have added if you had a bit more time. Go over both lists and ask yourself: have I covered the most relevant topics for this problem? Is there any topic in the second list that I feel I should have covered? If so, how would you add it to your narrative if you did the same problem again? Doing this will help you create a consistent approach and slowly develop a sense, a feeling, for which topics/areas are more relevant to explore for each kind of problem and to what extent.
Before describing the approach to grokking these interviews, we need to understand the point of view of the person (or people) on the other side of the table. What are they looking for?
Interviews with an open-ended question are intended to find the boundaries of your knowledge. Letting you choose the topics you want to cover and see how you prioritise them when developing your solution. They are designed this way to allow your interviewer to evaluate the following:
- Your ability to navigate an ambiguous problem by asking the right questions, shaping it into a concrete set of requirements
- Your thinking process: How you break a large problem into smaller parts while keeping the whole picture connected and meeting all requirements
- How you make decisions, evaluating different alternatives and the trade-offs
- Your knowledge, which parts of Android or iOS development you're more familiar with, which ones you are less. Can you also propose a solution for the server?
- And last but not least, your communication and collaboration skills. How you synthesise your solution and get buy-in
There is no right or wrong answer —just different alternatives. And your interviewer knows this. So please don't focus on finding the perfect solution. Instead, focus on designing a solution as you would typically do in your day-to-day job, applying the knowledge you possess to emphasise your strengths. A piece of advice someone gave me once and I always find helpful is to focus on the bits you know. If the interviewer truly cares about helping you succeed, they would be more interested in understanding what you know instead of what you don't. Plus, you usually score extra points for proposing a solution fast and then improving it gradually. In most cases, the initial question will not be the whole exercise, and your interviewer will expect to cover a few follow-ups. That's why following an iterative approach, starting with a high-level "simpler" solution and evolving it as new requirements are added, works relatively well.
The freedom to pick the areas you want to focus on your exercise is a double-edged sword. It gives you the liberty to drive the conversation and explore the parts you are more comfortable with, but at the same time, the interviewer may assume that anything you don't cover is because you don't know it. Remember that most interviewers (more so in big companies) tend to fall on the conservative side when writing their evaluation. Hence why the trickiest bit is to strike the right balance between briefly covering all topics relevant to the question asked while digging into the more relevant ones for the problem.
Finding this balance is hard to master, mainly because what you and your interviewer deem relevant may not be the same. Luckily, most interviewers will give you a hand here. They may hint you when you are missing something they consider necessary or even ask you directly to cover a specific part they are interested in exploring. Therefore, the best you can do is listen to your interviewer and use her hints to guide your solution. And if in doubt, do not be afraid of asking her as many questions as you need.
Below I describe a strategy to tackle mobile system design interviews. I have developed it over the years from doing these interviews myself and seeing many successful candidates excel.
💡 Tip: Don't just take this as a one-size-fits-all strategy. I would encourage you to spend the time to understand it, learn each step's importance and goal, and then make it yours. Bend it to what feels more natural to you, at the end of the day, there aren't two equal candidates, and you are the one who will know better what works best for you. You have the skills, and you have the experience, trust yourself.
It consists of a sequence of six straightforward steps:
- Understand the problem
- Define the scope
- Identify technical requirements
- Propose a high-level design
- Deep-dive into one component
- Wrap up
Let’s run through the six steps into more detail.
The first step should be no surprise. Before creating a solution, we need to understand the question.
It's probably the most obvious step and yet is the one where most candidates fail, myself included —multiple times. Why? Because we jump to conclusions too quickly. But let's not be too hard on ourselves. There is a good reason for so many of us falling into the trap. It's a well-known bias, which the interview environment accentuates (the pressure to prove yourself).
"The jumping conclusion bias, also referred to as the inference-observation confusion, is a psychological term referring to making decisions without having enough information to be sure that one is right, this can give rise to poor or rash decisions that often cause more harm to something than good."
So, now that you know it, just don't jump to conclusions. Slow down your wish to start designing your solution and avoid being that candidate who jumps into the solution without fully understanding the problem. Instead, concentrate on knowing what the interviewer wants you to focus on, the most relevant challenges of this type of apps, and what similar situations have you solved previously.
There is a reason why the interviewer gave you a vague, open-ended problem, and this step is precisely it. Remember, she is evaluating your ability to analyse an incomplete question, identify the dark areas, and ask the right questions.
Therefore, in this step, you want to ask clarifying questions to understand the problem better. Think of the information you have been given and then ask relevant questions to complete the picture.
These are a few questions that I found useful to ask at this stage, depending on the problem:
- What are we being asked to design?
- Who is the user, and how will they use our system?
- What's the initial number of users? And the expected growth?
- Are we being given an initial design/wireframes, or should we produce them as well?
- Are we designing an MVP or final-product?
- Are we building this from scratch, or can we leverage any existing components? Any existing patterns/architecture we should follow?
- How big is the team who will implement and maintain our system?
- Are we expected to design just the mobile application or other parts of the overall system too (e.g. API)?
- Is it iOS or Android only, or cross-platform? Shall we support smartphones, tablets, both?
You don't need to ask all of them. Depending on the problem, and the information you have been provided, some of these questions might be redundant. Just prioritise the most relevant ones for the task.
The second step is to figure out and agree on the functional requirements for the app or feature you will be designing.
Think of similar famous apps or systems you have used in the past and how they solve a similar problem. What features they offer and what's their primary functionality. You can suggest many potential features you can think of and seek agreement with your interviewer on which features you will focus on in this particular design session. It should be quite a collaborative part of the interview.
Once the scope is clear and agreed with your interviewer, you are ready to move to the next step and slowly unfold your solution.
This is when the real fun begins! Once the functional requirements are clarified, you should switch hats and start thinking on the technical considerations necessary to build a solution capable of providing the desired user experience you and your interviewer just agreed.
Let's jump straight into what are usually the most common aspects to consider when designing a mobile app:
Most apps nowadays either share or retrieve their state from a backend. Spend a bit of time thinking about how this backend might look like. For most cases, a REST API will do. Is this API provided? If so, how does it look?
May any features require low latency to simulate live updates? If so, how will you push this information to the client? You may need to use a more sophisticated approach than plain HTTP requests. You could use push notifications, WebSockets, polling, etc. Each option has trade-offs for you to consider.
If above we said most apps require to communicate with other systems. Then it's obvious we will need to secure those communications. Think of the following topics:
- Authentication: How will your solution verify who is the user of your app (authentication) and how will it guarantee the correct level of access is provided (authorisation)
- Storing sensitive data: Will you need to save the user's credentials? Yes! Unless you want to offer quite a poor experience where the users will have to sign-in every time. Which credentials (e.g. access tokens, refresh tokens)? Do we have to handle Personally Identifiable Information (PII)? How will you store them securely? (e.g. Keychain, Smart Lock)
- Secure communications: How will you ensure your communications with the backend are secure? E.g. All requests follow the HTTPS protocol and are encrypted with TLS, certificate pinning, etc.
Does the app have to support offline mode? Most likely it will, as you don't want to start your app from an empty state each time the user opens it. You could use a local store to cache data (e.g. Core Data, Realm, SQLite, shared preferences, etc.), consider which one and why.
And what happens with images (or other media)? If needed, you can cache them locally, once retrieved from the network. That's a great option, but it certainly comes with a few challenges: handling multiple requests at once, cancelling expired requests, clean-up policy (e.g. LRU), limiting concurrent requests, etc.
In mobile, the scalability challenges are typically a bit different from the rest of the systems. While in backend interviews, you have to design your system to support millions of QPS and partition your Terabytes of data in multiple shards. In mobile apps, scalability is usually linked to growing the codebase and team working on the app. Therefore, think of how you could prepare your design to support new features, owned by multiple teams (dozens of devs working on the same app).
- Break the UI into smaller independent components. Each of them with their stack so different people can work on them efficiently.
- Standardise your UI by building a reusable UI components library. It reduces code and ensures a consistent UX across the app.
- Modularise the app: Split the features in individual modules (which each team can own), and extract reusable components into shared and core modules.
In the nowadays mobile eco-system, more and more apps differentiate themselves by offering a slick and smooth user experience. To achieve it, you have to face the challenge of hiding the need to retrieve data from the network.
Some topics related to performance you may want to explore are:
- Are there any UI intensive operations (e.g. infinite list scrolling, heavy animations or complex transitions)? How would you support this? For example, you could pre-fetch data and create a buffer.
- Does the app load heavier data like images, videos, audio? If so, we should think on how to do it asynchronously, so we keep our UI slick, while still offering the best possible user experience. For example, by having a separate service to handle the retrieval of the media data asynchronously, notifying the UI when ready. What might be the bottlenecks and challenges of your approach?
You could briefly mention how you plan to ensure the quality of your app. Nowadays, the default should be to create a reliable suite of tests, but how you do this will most likely depend on the requirements (e.g. are you building an MVP?). You may want to think and describe what your testing strategy will be.
You may want to discuss the following briefly:
- Explain your testing strategy: How will you apply the different types of tests (unit tests, integration tests and UI/Functional tests to cover end-to-end the main app flows)
- Highlight the strengths of your architecture explaining how easy it is to test each particular component
- The use of dependency injection to make writing tests easier
You won't usually spend too long on this point unless the interviewer asks you to. It's important to consider how you plan to ensure the system’s correctness and facilitate a fast response when things go downhill. The two most important pillars are usually:
- Crash reporting and logging
How do you foresee your system going live to production? It may depend on the requirements from the interviewer. The most common topics to mention are:
- CI/CD pipeline with automated releases (e.g. with Fastlane _lanes _to send builds to production, QA and beta)
- Leveraging remote feature flags enables rolling out changes gradually and decouple the release from the review process (e.g. ensuring the new feature is ready for a marketing campaign).
And that's all for this step!
Pheww... That's a lot to cover and time is tight! But don't worry, the goal is for you to mention enough in most of them (one or two sentences), so the interviewer knows you have considered it. Without getting into detail unless it's critical for the problem, or the interviewer asks you so (remember, listen to your interviewer hints and follow the breadcrumbs).
If you have not been given wireframes, the first step is to draw them before you go deeper in developing your solution. This step is vital. It will allow you and your interviewer to agree on the main screens, UI components, user interactions and navigation flow, which will later inform your technical decisions. You want to ensure you get your interviewer's buy-in for how you see the app functioning to meet all the given requirements.
It should be pretty straightforward if you follow just three simple steps:
- Draw the main screens as boxes, describing the main content
- Go over the flow, adding arrows to represent the user journey
- Add more details to discuss each screen's composition: identify main UI elements, split UI components (e.g. cards/cells in a CollectionView / TableView). Think about possible reusable elements
💡 Tip: Do not spend too long on drawing a high-fidelity wireframe. Think what matters the most: describe the user experience, focusing on the different views and their main components and how the user flow will look like.
At this point, you should check with your interviewer if she is expecting you to cover the end-to-end design or to focus only on the client-side. Most mobile system design interviews will focus just on the app, but depending on the level, the type of engineer they are looking for and the size of the team, they may want you to at least demonstrate you have a basic understanding of what's going on outside of the app.
Suppose your interviewer asks you to explore the end-to-end design. A few common elements your design will most likely need to rely on are:
- Mobile Clients
- An API Service (the layer the clients will communicate to)
- Backend App (the app which will do most of the heavy-lifting on the backend side)
- Data Store (to store info in the cloud)
- A Notification Service (if notifications are required)
At this point, you should have a good idea of the flow you are designing and the functionality your app will support. It should be pretty easy to describe the most important data entities applicable to your problem.
💡 Tip: Do not go into too much detail at first. You are not designing a database schema. You just want to list the entities (e.g. users, posts, comments), mentioning their most relevant attributes and relationships. If your interviewer asks for more detail, you can always go deeper.
Depending on whether your interviewer said the API was given to you or not when you asked her earlier, you may need to design the endpoints or not.
💡 Tip: Follow an iterative approach and do not produce a complete spec for each endpoint. List the endpoints with their HTTP method (
DELETE) and path (e.g.
GET /post/:id/comments), the input parameters the endpoint requires, and the output you expect. For the output, noting the main entities will most likely be enough (no need to write the complete JSON payload). As always, please confirm this with the interviewer.
Back to the app, it's time to discuss and decide which architecture and common software patterns your design will follow.
Recall the standard architectures you are familiar with (e.g. MVC, MVP, MVVM+C, VIPER, RIBs, etc.), as well as the most typical patterns to abstract and encapsulate logic at the different layers of your system (e.g. Repositories, Use Cases, Services, etc.). Consider their strengths and weaknesses when applied to the problem at hand. Which ones will fit better the requirements you have? Why?
💡 Tip: You will make the rest of the exercise easier by picking a clean architecture. These architectures make it easier to break your design into small, individual components, which improves your solution's scalability, flexibility, and testability. Remember that your interviewer may start with a relatively simple problem and then ask you to evolve it to handle more complex scenarios. The more flexible your architecture is to cope with new challenges, the easier adapting your system will be when faced with them.
Unfortunately, I can't tell you the best architecture to pick. That not only depends on the problem but also your experience. Choosing a new trendy architecture may be a mistake if you don’t know it well enough. Instead, I would encourage you to rely on the one you are more familiar with. It's essential you fully understand the architecture and each component, as you may need to describe it in detail during the interview.
In my case, I tend to default to using a relatively simple and trend-agnostic clean architecture composed of the following pieces:
- Presentation Layer (UI): MVVM + Coordinator, to handle views & controller or activities & fragments and navigation logic.
- Domain Layer (Business logic): Use cases, to combine data from the user and repositories.
- Data layer:
- Repositories, to retrieve data from the network or the local store
- Network Data: Individual endpoints on top of the typical API Client
- Persisted Data: Local store (if caching)
- Helper services: to extract functionality that might be shared by different features, for example:
- Networking Service
- Session Service (to hold a user session's info)
- Credentials Store (to handle reading and writing of user credentials)
While using standard components, I find it helpful to keep the architecture trend-agnostic. I prefer to be pragmatic and add the pieces I require for the problem, instead of a more opinionated option (e.g. VIPER). It's obviously a matter of preference, and you and your interviewer may differ in opinions. Therefore my suggestion is to negotiate this with her during the exercise, explaining your decisions' trade-offs.
It's time to examine in more detail one of your components. While being able to solve the problem at a high-level is a great deal. Your interviewer will most likely expect you also to describe the ins and outs of one or more of the design components.
Here I share the approach I follow:
- Choose the most interesting screen and draw its architecture: Cover all layers from the different UI components, VMs, Repos, Endpoints/Sockets, Network Layer, Local Store, etc.
- Trace the dependencies (draw arrows from the caller)
- Walk over the flow from the user's point of view: What is the user experience? What does the user see at every step? Describe the possible view states: Loading, Error, No Data, Data)
- Explain the Data flow: Data transformations that happen along the way Network Model → Business Model → View State Model. Draw arrows to show data flow (different to the dependency arrows, e.g. use dotted arrows, another colour)
- And once you have covered all the above, go in-depth into one component. Think about what might be the most challenging parts, if the design may have any bottlenecks, etc. For example:
- "Real-Time" updates
- Image Caching (challenges, NSOperation Queue)
- Reusing Cells (preparing VMs)
- Buffering data requests to improve UX
💡 Tip: Once again, listen to your interviewer. Most interviewers will let you choose which one(s), but some may guide you towards the components she wants you to cover in more detail. Possibly, also, if you have forgotten anything.
Review the initial scope and functional requirements and how your design satisfies all of them.
At this point, your interviewer might already be asking follow-up questions. Listen to them and explain how your design could adapt to support them. Otherwise, ask her if there any other things she would like you to expand on.
Briefly cover some refinements you would do, if you had more time: Go over the design and technical considerations described above and think if you can expand in any of those in a bit more detail. Think of the technical considerations you may have left aside previously. Now might be a good time to mention them briefly. Some ideas for topics you could cover what would your testing strategy look like? How would you use your system's correctness with crash-reporting and analytics? How would you make your app more inclusive through accessibility?
We have covered a lot while describing our approach's different steps (I hope by now, it's become your approach as well). Across all of them, you have probably noticed a common set of patterns. Let's go over them quickly:
- Do not be afraid to ask. The question will most likely be vague, and you need to gather the information required to ensure you are solving the problem your interviewer wants you to solve. There is only one way to do this: ask your interviewer.
- Validate your assumptions. Check with your interviewer any assumption you are making, to ensure you are going in the right path.
- Know and use your tools. Get genuinely good at drawing diagrams and synthesising your solution. Time is precious, and this will boost your speed articulating your solution. Whether it's on a whiteboard or using an online tool, practice structuring your thoughts in a sharp and easy to follow manner. Learn to make your diagrams easy to modify and expand.
- Share your thoughts. It's vital that you continuously communicate with your interviewer to make this an effective interview. Remember she wants to understand how you think.
- Get buy-in for your choices. For every decision you make, mention the different alternatives you consider, their strengths and weaknesses and why you pick a particular one and the trade-offs.
I have mentioned the importance of practising this type of interviews to increase your chances to succeed. By now, you might be wondering what the best way to do so is. Here you have a few suggestions that have worked well for me:
- Get familiar with different standard architectures: MVC, MVVM, MVP, Redux, VIPER, etc.
- Design common apps: Grab your phone and think of the top apps you use and their most famous/challenging feature (e.g. Mail client, Instagram, Spotify, Twitter, Facebook, WhatsApp, Etsy) and then think how you would design it. Grab a piece of paper and start imagining how you would implement these apps. This simple exercise is what has worked best for most people I know and me. Trust me; it works!
- Read about existing solutions: Check tech blog posts, recorded talks, etc., from engineers working at big companies and compare how they solve their challenges.
- Review a few well-known open-source projects.
- Ask friends and colleagues to review your designs, get feedback.
- Practice mock interviews with colleagues or other candidates in the same boat.
System design interviews can be difficult, and a bit overwhelming, but it's also a place to be creative and learn by imagining systems you have never worked on. Preparing any interview can be stressful, but if you learn to enjoy the preparation itself and take it as an opportunity to expand your knowledge, it can become quite an exciting experience.
If you are reading this article, chances are you are preparing for an interview.
Mobile system design interviews are like a puzzle. One you have never built before, but you get to bring the parts to solve it. So make sure to include a broad set of parts in your toolbox and become comfortable scrutinising them and selecting the best ones for the job.
In this article, I have tried to share an approach to face these interviews. But this is just my approach, the one I have compiled from doing dozens of interviews myself and interviewing hundreds of candidates. While describing it, I have purposely tried to cover as many topics as possible, so that you can then shape them to form your own strategy. Don't just take my approach, make it yours!
Practice before the interview to get great at it, but without memorising it. There not two equal system design interviews, as there are not two equal candidates, nor interviewers. Remember that your interviewer is there to guide you and help you succeed. Please pay attention to the small hints and suggestions your interviewer gives you and incorporate those little nibbles of data to your solution.
Thanks for reading this long. I hope you have a better understanding of what mobile system design interviews entitle: what they consist on, what your interviewer will be evaluating, plus a reliable approach to tackling them successfully.
I would love to learn from your experience. If you have other tips or a different strategy, please share it in the comments.
Good luck interviewing!
Here you have a list of suggested materials (posts, WWDC videos, courses, etc.) to dive deeper and expand your knowledge in the different topics touched in this article.
- App Architecture - iOS Application Design Patterns in Swift by Chris Eidhof, Matt Gallagher, and Florian Kugler. [Book]
- 33 Engineering Challenges of Building Mobile Apps at Scale by Gergely Orosz [Post | Book]
- System Design Interview: an Insider's Guide by Alex Xu [Book | Course]
- Push technology. Wikipedia [Article]
- Advances in Networking, Part I. WWDC 2019 [Video]
I am a Software Engineer with 15 years of experience. Around ten years ago, I switched from writing ANSI C for embedded systems to mobile development. Yeap! Those were the good ol' days with iOS 3, Interface Builder, Eclipse, the iPhone 3GS, Java, and Objective-C. I have worked in small projects where I was the sole engineer, and in big apps with multiple teams and 50+ developers, supporting millions of users worldwide. I have interviewed hundreds of candidates and I have done several dozens of interviews as a candidate myself during all this time from small start-ups to Big Tech companies.