Welcome to our System design series. In this article, we will try to answer a basic question as “What is System Design?” and what is the use of system design in software applications. All journey to software development starts with system design.
Table of Contents
What is System Design
Designing a system that supports millions of users is an interesting but challenging task. Unlike coding, system design requires a continuous focus on refinement and improvement. Even large-scale systems like Netflix, Google Search, and YouTube go through this process to ensure scalability, performance, and security. To put in a formal definition, System design is a process for:
- defining the architecture of the application.
- Laying out different interfaces
- Different data components for the application
It will ensure that specific requirements are met by following the above 3 criteria. Thinking about all aspects starting from software to hardware and infrastructure is a key characteristics of a good system design.
1. System Design Phases
Lets take a look at the different phases of the system design
As clear from the above image, system design is the core of any application. If the design is good, it will ensure that our application is scalable, easily manageable.
2. System Design Components
System design is like a similar to the blueprint or roadmap for creating or building a system which meets the requirements and meet the objectives. The process is like building your house, where we create a design to ensure it meets our requirements before we start the real work on building the house. Here are some of the main aspects or components while working on our design:
2.1. Meet User Needs
This is the first and core step of our system design journey. Before we start, we should be clear on our goal and objectives. While designing the system, we should clearly understand the requirements and what can be the end product. Without a clear vision and understanding, its very hard to design various components of our application.
2.2. Architecture
System architecture talks about the overall design / structure of the application, which includes:
- High-level details of components.
- Relationship between different components.
- data flow design.
System architecture also includes choosing various system design patterns like micro services vs monolithic, etc.
2.3. Data
Data is a backbone for any application. Data design will determine the following items at a high level.
- Data model used for application.
- Data storage mechanisms.
- data retrieval, manipulation process.
It also involves choosing an underlying data storage mechanism like RDBMS vs. NoSQL or MySQL vs PostgreSQL. Choosing an appropriate data storage system is critical as it will also affect other components of our system designs like scalability, throughput, etc.
2.4 Scalability and Performance
If we don’t consider these during our system design, it will be difficult to scale or handle any performance issue at a later stage. Scalability and performance are the key components of any system design. This will ensure that we have a plan in place to handle increased load and traffic as our application grows. Scalability and performance involves choosing our caching strategies, load balancers, optimizing our data storage, and many others.
2.5. Security and Reliability
In today’s threat landscape, application security is imperative. It must be a foundational element of the system design process, not an afterthought. Adding a security layer at the latter stage will not only be challenging but may not be that effective as compare to when we made it a first-class citizen during our design process. Here are some of security components which we can think during our design process:
- Access designs, e.g. authorized and unauthorized access.
- Data security.
- Data breaches.
- Handling PCI data (important in financial applications)
- Security and threat monitoring.
2.6. Communication
Modern system includes different components and having a clear communication design between these components lay a foundation for a good application. Communication design outlines how the different components will communicate with each other. Some of the key items for communication designs are:
- Data formats.
- APIs
- Communication protocols, e.g. HTTPS, RPC, etc
2.7. Maintainability and Extensibility
The design should prioritize code clarity, modularity, and documentation. This allows developers to easily understand, change, and extend the system as new features or requirements arise.
2.8 User Experience
Any application which involves users interaction, a good user experience is needed. A good application with poor user experience will not make any impact and lose the entire relevance of the application. User experience determines how the application users will interact with different components of the application and how will be the experience.
3. How to approach System Design Questions
Although system design seems easy for software engineers or anyone with technical background as we are familiar with most of the terminologies and technologies however, in most of the cases, we face difficulties or challenges during our system design interviews because of the following
- System design interviews are unstructured. We will be asked an open-ended design question and there is no perfect or complete answer to these questions. Keep in mind that 2 different software engineers can have completely different approaches for these questions. However, our focus should be to provide a well-rounded design and show our design thought process with the goal of demonstrating a scalable, secure, and user-friendly system.
- Many times, we might lack experience developing complex applications which can pose some challenges during these questions.
- If we have not spend enough time on preparing for system design interview, it can pose some challenges as how to structure our approach within those 30-45 minute ensuring we are not over complicating or missing any critical component in the design process.
Let’s go through a step by step process outlining the approach for to effectively handle system design interviews
3.1 Requirement Clarification
Clarification is Key. Before we jump to the next step, it’s always best to ask clarification question to understand the scope of the problem. You can always ask clarification questions on the following:
- Scope of the problem.
- User base.
- Usage patterns.
- Scalability requirements.
- Geographical presence (e.g. application for a specific country / location and global can have changed the entire design )
- Security constraints or requirements.
Don’t be afraid to ask any clarification question, it’s always good to ask rather than working on wrong assumptions.The better you understand the problem, the more focused your design can be. Keep in mind that you will have 30-45 minutes to design your application, so it’s a good idea to clarify on what part of the application we should focus, you can’t cover every part of the application in 30 minutes :). Let’s say you are being asked to build a URL shortening system. Here are some of the clarifying questions I might ask with my interviewer:
- What kind of user we are focusing? Is it internal application or a public facing?
- What should be the maximum length of the URL?
- Do we need to keep the URL for certain period (e.g. 5 years, 10 years or no expiry)
- What are the total user bases and what is the expected volume per day?
- Do we want to provide custom URL feature (e.g. user can provide there on a short key)?
- Are there any geographic considerations for the user base?
- Any rate limiting we want to apply?
- Any spam protection we like to put in place?
You don’t have to ask every question, for some of them, you can take some assumption and call them loudly and let your interviewer confirm or change them, for others, you can ask your interviewer to provide you with the inputs.
3.2 Back-of-the-envelope Estimation
Next is to do a quick back-of-the-envelope estimation. This will provide you with the sense and idea on the scale of the system we are building. This step is crucial, especially when you might want to focus on the scalability, load balancing, caching and other aspects at the later stage of your interview. These calculations will help you
- To understand how much storage space we might need for our application.
- What is the scale of the system we are talking about?
- What is the network capacity expected?
- Number of servers we might need
3.3. Design Framework
While going through your system design interview, you can use a general design framework. This will help you guide your discussion even if you have not in depth knowledge of a topic. Don’t worry, no one has knowledge of all the components that can be used in a system design. Use the following approach:
- High-level Design – Start with a high level design of your application. Put an overall system architecture which can include components like database, web-server, application server, user interface. Don’t go into details. This step to ensure that you have set the building blocks and boundaries for your design.
- Deep Dive : Once we have discussed the high level design with the interviewer, the next step is to deep dive in our system design. Talk to your interviewer and pick 2-3 components where your interviewer wants to focus, e.g. database or caching etc. Pick one component at a time and start getting in to more details. Keep in mind that the interviewer is your guide and, in most of the cases, they will guide you and even help you if you are going in the wrong direction. Make sure you follow the prompt.
- Scalability and Trade-offs – Once we covered few components in details, the next step of our framework is the scalability and also call out any trade-offs which are there because of our design choices. Mention potential trade-offs you considered when making design decisions. Talk about various scalability challenges e.g sudden spikes, exponential user growth etc and your plan to handle it.
3.3.1 High-Level Design
You can draw 4-5 main components of your system, e.g. Load Balancer, Web Server, Application servers, Database etc and highlight how they will interact in your high-level design. This will set the building block when we start a deep dive into a few components. Here is an example for you:
3.3.2 Deep Dive
As I mentioned earlier, pick 2-3 components based on your discussion with your interviewer and start getting deeper into the design. Keep an eye on your interviewer’s feedback when you are identifying these components, their feedback will help you identify the components where interviewer might be interested. While you work on the details of design, remember there is no single solution and every solution will have some limitation and trade-offs. You need to discuss those loudly and highlight why are you picking one over other. Here are some example for you:
- Since we need a quick look up for our URL service and it’s a small data, we may use key value DB like Redis which has low latency, you can also highlight that URL key doesn’t have a lot of relational data.
- Since we might store a lot of data, how to partition the data, e.g. partition based on the hash-key vs geographical location.
- How to handle some high traffic URL (e.g. We can cache those).
- What all layer we can utilize caching strategies?
- How about load balancing and where are all we need?
Now let’s look at some of the other things which you should keep in mind and use during your system design interview.
3.4 System Interfaces Design
Outline or define the API structure for your design, pick 3-4 main features of the application and discuss the API structure. This step helps you to establish system contracts and you can use this opportunity to identify and wrong requirement or assumption that we might have created. You don’t have to go into deep details of the API structure, but a high level should be more than sufficient. Here is an API interface contract for the “URL shortening system”
payload = { "url": "https://google.com/" ,
"alias":"",
"user":"xyz",
"expire_date":""
}
headers = {
"content-type": "application/json",
"API-Key": "XYZ"
}
shortURL(final String url, final String alias, final User user, final Date expiryDate) {}
3.5 Data Model Definition
If the design requires you to save the data, it’s a good practice to talk about the data model and underlying storage engine. You might have to choose between No-SQL or SQL database and this step will help you call out why you are choosing 1 type of data storage over other. This will also set the ground on how the data flow between different components of the application. You can use this building block in the latter part to discuss data partitioning and management. Here is an example from our URL shortening system.
You can use this time to discuss and call out a few things exclusively
- Which type of database you like to use and why?
- Any trade-offs for using that specific data type?
- Will NoSQL database fits your needs, and you can call out a few of them.
- Any block storage you might need for your design and what that might be?
3.6 Highlight Your Though-process
Keep in mind one thing: system design interviews are not to judge how well your design is, the intention is to understand your thought process. While you are working on the design, explain why you’re choosing specific components and approaches. This is a good way to build a repo with your interviewer. If you keep explaining your thought process, you will also get some hits and navigation directions from your interviewer. Talk about any alternate solution and why are you choosing a solution, it’s a good step to show your analyzing and decision-making skills.
3.7 Identifying and Resolving Bottlenecks
No system can be with no bottlenecks or limitations, you can use the end of your system design interview to discuss bottlenecks and your approach to resolve them. Try to talk about as many bottlenecks as possible, e.g.
- What if we have a single point of failure? How will you mitigate this bottleneck?
- Data loss and how will you handle it (e.g data replication).
- How to do monitoring?
For system design question Don’t Be Afraid to Ask Follow-Up Questions
Summary
Preparation, being organized and following design framework are the keys for a successful system design interview. Practice is another major key to be successful in your interview. We will talk about a few core components of system design before dive in to some of the real-world examples. As always, you can explore our GitHub repository to get the latest code and run it locally.