Writing the System Design Codex Newsletter • I simplify software design with concepts and case studies

Join 27K+ readers →
Joined January 2019
If you want to get better at System Design, read these 19 articles: [1] Extracting Services from a Monolithic App Why read it: Learn how to migrate critical functionality to a new service in a risk-free manner newsletter.systemdesigncodex… [2] Should You Fire and Forget an Event Why read it: Know the different ways to handle an event acknowledgment (examples with Kafka). newsletter.systemdesigncodex… [3] Stateless Architecture - What’s the Deal? Why read it: Everyone suggests building stateless apps. But what does it really mean? newsletter.systemdesigncodex… [4] Practical Intro to Kubernetes Why read it: To learn the basics of Kubernetes, its internal architecture, and code examples newsletter.systemdesigncodex… [5] CAP Theorem with Tom the Prankster Why read it: Understand CAP Theorem in a way you’ll never forget newsletter.systemdesigncodex… [6] 5 Strategies for High Availability Systems Why read it: Simple tips to improve your system’s availability newsletter.systemdesigncodex… [7] Change Data Capture and Microservices Why read it: To learn how CDC can help implement Outbox and Strangler Fig pattern newsletter.systemdesigncodex… [8] 23 System Design Interview Tips Why read it: To learn key principles to consider while designing a system. newsletter.systemdesigncodex… [9] Introduction to ACID Properties Why read it: To learn about the basic guarantees provided by a database. newsletter.systemdesigncodex… [10] How DNS Works? Why read it: To understand what happens when you open a website in the browser. newsletter.systemdesigncodex… [11] Intro Circuit Breaker Pattern Why read it: Learn about the circuit breaker pattern of building microservices newsletter.systemdesigncodex… [12] Introduction to Pre-caching Why read it: To understand the secret technique that can boost application performance newsletter.systemdesigncodex… [13] Load Balancers Why read it: To understand the types, algorithms, and high availability considerations behind a load balancer newsletter.systemdesigncodex… [14] JSON Web Tokens and Authentication Why read it: To learn how JSON Web Tokens help with user authentication newsletter.systemdesigncodex… [15] Database Caching Strategies Why read it: To understand the various database caching strategies and how to choose one newsletter.systemdesigncodex… [16] Cookies and Sessions Why read it: To understand the difference between cookies and sessions with regards to authentication. newsletter.systemdesigncodex… [17] API Performance Strategies Why read it: To learn about the best strategies to boost your API’s performance newsletter.systemdesigncodex… [18] Types of NoSQL Databases Why read it: To learn about the most popular NoSQL database types and where to use them newsletter.systemdesigncodex… [19] How to Scale a Component? Why read it: Interview Tips on Vertical and Horizontal Scalability newsletter.systemdesigncodex…
7
145
3
658
59,537
15 articles to help you get better at System Design: [1] 4 Challenges of Distributed Systems - And Possible Solutions newsletter.systemdesigncodex… [2] Your Code is Fast, But Your Database is Slow—Now What? newsletter.systemdesigncodex… [3] 15 Must-Know Elements of System Design newsletter.systemdesigncodex… [4] How To Do Well in System Design Interviews? newsletter.systemdesigncodex… [5] 8 Must Know Distributed System Design Patterns newsletter.systemdesigncodex… [6] 6 Strategies to Build Secure APIs newsletter.systemdesigncodex… [7] How HTTP 2 Improves Upon HTTP 1 newsletter.systemdesigncodex… [8] How Netflix Uses Caching to Hold Attention? newsletter.systemdesigncodex… [9] 8 Must-Know Strategies to Build Scalable Systems newsletter.systemdesigncodex… [10] 3 Interview Questions on Event-Driven Patterns newsletter.systemdesigncodex… [11] Don’t Use Sync Communication for Every Case newsletter.systemdesigncodex… [12] How Consistent Hashing Works? newsletter.systemdesigncodex… [13] The Journey of a SQL Query Through a Database newsletter.systemdesigncodex… [14] TCP 3-Way Handshake newsletter.systemdesigncodex… [15] Database Sharding newsletter.systemdesigncodex…
5
8
46
3,660
15 articles to help you get better at System Design: [1] 4 Challenges of Distributed Systems - And Possible Solutions newsletter.systemdesigncodex… [2] Your Code is Fast, But Your Database is Slow—Now What? newsletter.systemdesigncodex… [3] 15 Must-Know Elements of System Design newsletter.systemdesigncodex… [4] How To Do Well in System Design Interviews? newsletter.systemdesigncodex… [5] 8 Must Know Distributed System Design Patterns newsletter.systemdesigncodex… [6] 6 Strategies to Build Secure APIs newsletter.systemdesigncodex… [7] How HTTP 2 Improves Upon HTTP 1 newsletter.systemdesigncodex… [8] How Netflix Uses Caching to Hold Attention? newsletter.systemdesigncodex… [9] 8 Must-Know Strategies to Build Scalable Systems newsletter.systemdesigncodex… [10] 3 Interview Questions on Event-Driven Patterns newsletter.systemdesigncodex… [11] Don’t Use Sync Communication for Every Case newsletter.systemdesigncodex… [12] How Consistent Hashing Works? newsletter.systemdesigncodex… [13] The Journey of a SQL Query Through a Database newsletter.systemdesigncodex… [14] TCP 3-Way Handshake newsletter.systemdesigncodex… [15] Database Sharding newsletter.systemdesigncodex…
5
8
46
3,660
System Design Codex retweeted
What’s the most important part of Event-Driven Architecture? Events, of course. In an EDA-based application, different components communicate by sending and receiving events. But what exactly is an event? It is an occurrence that has happened in the application. Some examples of events: - A customer signing up for your application - A payment is received for an order - A failed authentication attempt Whatever their nature may be, there are mainly 3 different patterns for handling events: - Event Notifications - Event-Based State Transfer - Event Sourcing ✅ Event Notifications In this approach, events are used to notify something has occurred within your application. Such an event carries the absolute minimum state. Most times, it’s just the identifier (ID) of an entity. When receiving such events, some components may record the information for auditing purposes. Other components might call the source component to fetch additional information about the event. Such events are general-purpose in nature and suitable for broadcasting requirements. Less data is sent over the network in this case. ✅ Event-Based State Transfer This is more like the asynchronous relative of REST. Instead of REST’s on-demand pull model, event-based state transfer follows a push approach. Data (id + information) is sent out to be consumed by any components. Some components may create their own local cached copies of the data. Others may take some other action based on the data received. The advantage of this approach is that the consumer need not call back the source component for additional information. The entire information is right there in the event payload. ✅ Event Sourcing This is not about event transmission but event storage. Changes to an entity are not captured as irreversible modifications but are stored as events in an event store. These changes can be read and processed to recreate the final state of an entity whenever required. 👉 So - which patterns for EDAs have you used?
13
45
266
11,487
What’s the most important part of Event-Driven Architecture? Events, of course. In an EDA-based application, different components communicate by sending and receiving events. But what exactly is an event? It is an occurrence that has happened in the application. Some examples of events: - A customer signing up for your application - A payment is received for an order - A failed authentication attempt Whatever their nature may be, there are mainly 3 different patterns for handling events: - Event Notifications - Event-Based State Transfer - Event Sourcing ✅ Event Notifications In this approach, events are used to notify something has occurred within your application. Such an event carries the absolute minimum state. Most times, it’s just the identifier (ID) of an entity. When receiving such events, some components may record the information for auditing purposes. Other components might call the source component to fetch additional information about the event. Such events are general-purpose in nature and suitable for broadcasting requirements. Less data is sent over the network in this case. ✅ Event-Based State Transfer This is more like the asynchronous relative of REST. Instead of REST’s on-demand pull model, event-based state transfer follows a push approach. Data (id + information) is sent out to be consumed by any components. Some components may create their own local cached copies of the data. Others may take some other action based on the data received. The advantage of this approach is that the consumer need not call back the source component for additional information. The entire information is right there in the event payload. ✅ Event Sourcing This is not about event transmission but event storage. Changes to an entity are not captured as irreversible modifications but are stored as events in an event store. These changes can be read and processed to recreate the final state of an entity whenever required. 👉 So - which patterns for EDAs have you used?
13
45
266
11,487
What’s the deal with Stateless Architecture? The term “stateless architecture” can be a little confusing. It seems to imply that the system is without any state. This is not exactly true. Stateless architecture just means that the state information (if needed) is stored outside the application server. Let’s understand it via a real-life example: ✅ You are visiting a stateless restaurant and each waiter has a perfectly forgetful memory. ✅ They just note the order on a separate system using a handheld device and forget about it. ✅ You make an order but then realize, you have an allergy to a particular item and want to change the order. ✅ The waiter will simply check their device to get the details of the order and make changes to it as required. 👉 The same is the case with a system built using Stateless Architecture. In such a system HTTP requests from a client can be sent to any of the servers. The state is typically stored on a separate database or cache that is accessible by all the servers. This way the load balancer can distribute the incoming requests more or less evenly across the instances. 👉 So - do you build your applications in a stateless manner?
7
28
112
4,842
What’s the deal with Stateless Architecture? The term “stateless architecture” can be a little confusing. It seems to imply that the system is without any state. This is not exactly true. Stateless architecture just means that the state information (if needed) is stored outside the application server. Let’s understand it via a real-life example: ✅ You are visiting a stateless restaurant and each waiter has a perfectly forgetful memory. ✅ They just note the order on a separate system using a handheld device and forget about it. ✅ You make an order but then realize, you have an allergy to a particular item and want to change the order. ✅ The waiter will simply check their device to get the details of the order and make changes to it as required. 👉 The same is the case with a system built using Stateless Architecture. In such a system HTTP requests from a client can be sent to any of the servers. The state is typically stored on a separate database or cache that is accessible by all the servers. This way the load balancer can distribute the incoming requests more or less evenly across the instances. 👉 So - do you build your applications in a stateless manner?
7
28
112
4,842
24 principles that can help you navigate System Design Interviews: ✅ If you need to scale an individual component, stick with Vertical Scaling first. Then, look at Horizontal Scaling when needed ✅ To deal with traffic spikes, evaluate the use of Autoscaling for Dynamic Resource Allocation ✅ If the system requires High Availability with Performance, consider using a Load Balancer ✅ If you’re building a read-heavy system, it’s a good idea to use a Cache ✅ Listen to the system requirements properly and note them down if needed ✅ To reduce the latency of static assets, consider using a CDN ✅ If you want to improve the database query performance, focus on the right indexes ✅ To scale the read requests to your database, consider Database Replication ✅ To scale write requests, consider Database Sharding ✅Clarify your assumptions before jumping into the solution ✅ For global distribution of data, use a CDN ✅ If you want to store complex data such as videos, images and files, go for an Object Storage ✅ To manage the load on the server and prevent denial-of-service attacks, use Rate Limiting ✅ In order to remove a Single Point of Failure, implement Redundancy and Isolation ✅ Clarify about the Non-Functional Requirements as well and take them into account ✅ To improve the Fault Tolerance and Durability of your data, consider Data Replication techniques ✅ If the system needs to execute long-running tasks, use Async Processing and Background Processes ✅ To build a loosely coupled system, consider the use of Event-Driven Architecture ✅ If the system needs to store unstructured data, consider NoSQL databases ✅ Keep getting feedback during the discussion rather than waiting till the end ✅ To deal with large amounts of data flowing through the network, use Compression and Pagination techniques ✅ For automated builds and deployments, consider implementing CI/CD pipelines ✅ If you want to achieve independent deployments of various parts of the system, consider microservices architecture ✅ Establish good eye contact with the interviewer and answer the questions confidently. Above all else, remember that System Design questions don't have perfect answers. They are meant to test your analytical skills and ability to consider trade-offs. 👉 So - what would you add to the list?
4
34
1
138
7,999
Layer 4 vs Layer 7 Load Balancers Simplified ✅ Layer 4 Load Balancer As the name suggests, Layer 4 load balancers operate in the transport layer of the OSI model. Yes, the famous OSI model! What does it mean? The routing decisions are made solely based on the info available at that layer. Information such as IP address or port. In other words, a layer 4 load balancer cannot see the data in the network packet. It has some advantages: - Simpler to run and maintain - Better performance since no data lookup - More secure since there’s no need to decrypt the TLS data - Only one TCP connection But there are disadvantages as well. - No smart load balancing - No routing to different service types - No caching since the LB can’t even see the data. ✅ Layer 7 Load Balancer Layer 7 load balancers operate at the layer 7 of the OSI model. They deal with protocols such as HTTP(S), WebSocket, FTP, and SMTP. What this means is that Layer 7 LBs can see the actual data within the packet and make routing decisions based on that data. Here’s how they work: [1] Let’s say you have two microservices - one dedicated to the blog posts (/blog) and the other dedicated to the comments (/comments). [2] The client makes a request to the load balancer by establishing a TCP connection and says that it wants to access the route /blog. [3] The load balancer decrypts the data and checks the configured rules [4] Based on the request destination, the load balancer establishes a new TCP connection to the server instances hosting the blog microservice. [5] Once the response comes back, it sends over the response to the client. Advantages: - Smart load balancing (big benefit) - LB can also cache data - Can play the role of a reverse proxy Disadvantages: - Expensive to run and maintain - Needs to decrypt the data - Maintains 2 TCP connections - one from the client to LB and another from LB to the service 👉 So - have you used Layer 4 or Layer 7 load balancer? Or have you used both together?
3
5
34
2,684
Layer 4 vs Layer 7 Load Balancers Simplified ✅ Layer 4 Load Balancer As the name suggests, Layer 4 load balancers operate in the transport layer of the OSI model. Yes, the famous OSI model! What does it mean? The routing decisions are made solely based on the info available at that layer. Information such as IP address or port. In other words, a layer 4 load balancer cannot see the data in the network packet. It has some advantages: - Simpler to run and maintain - Better performance since no data lookup - More secure since there’s no need to decrypt the TLS data - Only one TCP connection But there are disadvantages as well. - No smart load balancing - No routing to different service types - No caching since the LB can’t even see the data. ✅ Layer 7 Load Balancer Layer 7 load balancers operate at the layer 7 of the OSI model. They deal with protocols such as HTTP(S), WebSocket, FTP, and SMTP. What this means is that Layer 7 LBs can see the actual data within the packet and make routing decisions based on that data. Here’s how they work: [1] Let’s say you have two microservices - one dedicated to the blog posts (/blog) and the other dedicated to the comments (/comments). [2] The client makes a request to the load balancer by establishing a TCP connection and says that it wants to access the route /blog. [3] The load balancer decrypts the data and checks the configured rules [4] Based on the request destination, the load balancer establishes a new TCP connection to the server instances hosting the blog microservice. [5] Once the response comes back, it sends over the response to the client. Advantages: - Smart load balancing (big benefit) - LB can also cache data - Can play the role of a reverse proxy Disadvantages: - Expensive to run and maintain - Needs to decrypt the data - Maintains 2 TCP connections - one from the client to LB and another from LB to the service 👉 So - have you used Layer 4 or Layer 7 load balancer? Or have you used both together?
3
5
34
2,684
How do you scale a component? There are three points that I consider: ✅ Vertical Scaling vs Horizontal Scaling The easiest way to scale a component is vertical scaling. Think bigger RAM. A larger disk or CPU. It's cost-effective in the short term. Plus, you avoid dealing with distributed stuff. But it becomes expensive in the long run and doesn't help you get rid of single points of failure. This brings us to Horizontal scaling i.e. scaling a component by adding more machines. ✅ Horizontally Scaling Stateless Apps A stateless component doesn't save the client data from one session for use in the next session. This makes it easier to scale horizontally. You can use a load balancer to distribute requests between multiple stateless components. Of course, it becomes important to build the services in a stateless manner. ✅ Horizontally Scaling Stateful Components A stateful component saves data from one session to the next one. For example, a web application that stores the session info. Or a database/key-value store. For scaling out stateful components, we've to adopt techniques like replication, sharding, and so on. 👉 TL;DR - Vertical scaling is less complex and you should stay with it for as long as possible. It can also be sufficient for a majority of the apps. - Think horizontal scaling when vertical is no longer cost-effective. - Try to build your application layer in a stateless manner so that it's easy to scale out. - For stateful components like databases, choose modern options designed for horizontal scalability. It will make your life easier. 👉 So - how do you approach the task of scaling a component?
7
46
1
183
11,649
How do you scale a component? There are three points that I consider: ✅ Vertical Scaling vs Horizontal Scaling The easiest way to scale a component is vertical scaling. Think bigger RAM. A larger disk or CPU. It's cost-effective in the short term. Plus, you avoid dealing with distributed stuff. But it becomes expensive in the long run and doesn't help you get rid of single points of failure. This brings us to Horizontal scaling i.e. scaling a component by adding more machines. ✅ Horizontally Scaling Stateless Apps A stateless component doesn't save the client data from one session for use in the next session. This makes it easier to scale horizontally. You can use a load balancer to distribute requests between multiple stateless components. Of course, it becomes important to build the services in a stateless manner. ✅ Horizontally Scaling Stateful Components A stateful component saves data from one session to the next one. For example, a web application that stores the session info. Or a database/key-value store. For scaling out stateful components, we've to adopt techniques like replication, sharding, and so on. 👉 TL;DR - Vertical scaling is less complex and you should stay with it for as long as possible. It can also be sufficient for a majority of the apps. - Think horizontal scaling when vertical is no longer cost-effective. - Try to build your application layer in a stateless manner so that it's easy to scale out. - For stateful components like databases, choose modern options designed for horizontal scalability. It will make your life easier. 👉 So - how do you approach the task of scaling a component?
7
46
1
183
11,649
15 articles to help you get better at System Design: [1] 6 Strategies to Build Secure APIs newsletter.systemdesigncodex… [2] How HTTP 2 Improves Upon HTTP 1 newsletter.systemdesigncodex… [3] How Netflix Uses Caching to Hold Attention? newsletter.systemdesigncodex… [4] 8 Must-Know Strategies to Build Scalable Systems newsletter.systemdesigncodex… [5] 8 Must-Know Strategies to Build Scalable Systems newsletter.systemdesigncodex… [6] Don’t Use Sync Communication for Every Case newsletter.systemdesigncodex… [7] How Consistent Hashing Works? newsletter.systemdesigncodex… [8] The Journey of a SQL Query Through a Database newsletter.systemdesigncodex… [9] TCP 3-Way Handshake newsletter.systemdesigncodex… [10] Database Sharding newsletter.systemdesigncodex… [11] Eventual Consistency is Tricky newsletter.systemdesigncodex… [12] Intro to GraphQL newsletter.systemdesigncodex… [13] 3 Kafka Messaging Strategies newsletter.systemdesigncodex… [14] Intro to Kafka newsletter.systemdesigncodex… [15] 3 Interview Questions on Event-Driven Patterns newsletter.systemdesigncodex…
7
60
1
239
14,145
15 articles to help you get better at System Design: [1] 6 Strategies to Build Secure APIs newsletter.systemdesigncodex… [2] How HTTP 2 Improves Upon HTTP 1 newsletter.systemdesigncodex… [3] How Netflix Uses Caching to Hold Attention? newsletter.systemdesigncodex… [4] 8 Must-Know Strategies to Build Scalable Systems newsletter.systemdesigncodex… [5] 8 Must-Know Strategies to Build Scalable Systems newsletter.systemdesigncodex… [6] Don’t Use Sync Communication for Every Case newsletter.systemdesigncodex… [7] How Consistent Hashing Works? newsletter.systemdesigncodex… [8] The Journey of a SQL Query Through a Database newsletter.systemdesigncodex… [9] TCP 3-Way Handshake newsletter.systemdesigncodex… [10] Database Sharding newsletter.systemdesigncodex… [11] Eventual Consistency is Tricky newsletter.systemdesigncodex… [12] Intro to GraphQL newsletter.systemdesigncodex… [13] 3 Kafka Messaging Strategies newsletter.systemdesigncodex… [14] Intro to Kafka newsletter.systemdesigncodex… [15] 3 Interview Questions on Event-Driven Patterns newsletter.systemdesigncodex…
7
60
1
239
14,145
Load Balancer vs API Gateway vs Backend-For Frontend simplified. ✅ Load Balancer When you check in to a hotel, you are usually greeted by a receptionist. The receptionist checks your documents, enters your info into their system, and guides you to your room. If there are too many guests, the hotel might keep multiple receptionists. Load balancers do a similar job for your application. It’s a tool that distributes incoming requests across multiple servers. Also, load balancers keep your system available. If one server goes down, it directs the request to another server. ✅ API Gateway Imagine a scenario where a company is conducting interviews for various positions, such as Tech Architect, Engineering Manager, and Software Engineer. Each position has a dedicated interview panel. Now, you don’t want the candidates to check each room to find the correct panel. This is where a coordinator checks the candidate’s profile and directs them to the correct panel. For a system, API Gateway is that coordinator. API Gateways can also perform different functions like authentication, rate limiting, logging, and caching. ✅ Backend for Frontend Let’s take our interview example further. For every position (Arch, Engineering Manager, Software Engineer), there are specific rounds of discussions. Some rounds are different based on the position but some may be common for all positions (such as the Director Round). How do you coordinate this for each position? Backends for Frontends is your BFF in this scenario. It’s a coordinator that takes care of the specific rounds for a particular type of interview. In system terms, BFF is the component that can take care of different device requirements. 👉 So - have you used Load Balancers, API Gateways & BFFs?
9
113
1
645
36,031
System Design Codex retweeted
4 must-know Microservice Design Patterns: ✅ Database per service - In this pattern, each microservice manages its own data. - This means that no other service can access that data directly. - Communication or exchange of data can only happen through the owner service. - The success of this pattern depends on how well you’ve defined the bounded context of your application. ✅ Shared Database - Avoid this pattern as much as possible - But sometimes, it’s the only viable option to incrementally move to a microservice architecture. - This approach is lenient in the sense that multiple services use a shared database. - However, it creates a bigger impact surface and chances of run-time issues. ✅ API Composition - This pattern tries to solve the problem of implementing complex queries in a microservices architecture. - An API Composer invokes other services in the required order. - After fetching the results, it performs an in-memory join of the data before returning it to the caller. - This is an inefficient approach due to in-memory joins on potentially large datasets. ✅ CQRS + Event Sourcing - Next, we have CQRS - It can help get around the issues with the API Composition Pattern. - An application listens to domain events from other services and updates a separate query database. This makes it easy to serve complex aggregation queries. - CQRS can also be combined with Event Sourcing where you store the state of the entity (aggregate) as a sequence of events. - Of course, this pattern can sometimes be unfamiliar to the developers. At the end of the day, no pattern is perfect. Learn about the trade-offs with each pattern and choose what works for you. 👉 So - which patterns have you used?
4
69
1
283
14,190