Mastering System Design Interviews
System Design Fundamentals
The Four Pillars of System Design
Great systems aren't built by accident. Whether it's a social media app serving billions or a banking platform processing millions of transactions, a well-designed system is built on a solid foundation. This foundation rests on a few core principles that ensure the system works well today and can grow to meet the demands of tomorrow.
We're going to explore four of these pillars: scalability, reliability, availability, and maintainability. Understanding them is the first step toward thinking like a system designer.
Effective system design ensures that the final product is scalable, reliable, and efficient, capable of handling growth and the inevitable changes in user demand.
Scalability: Handling More Load
Scalability is a system's ability to handle an increasing amount of work. Imagine you open a small coffee stand. At first, one barista can handle all the orders. But as your coffee gets popular, the line grows. You need a way to serve more customers without making everyone wait forever.
In system design, you have two basic options to handle this extra load.
Vertical Scaling (Scaling Up): You replace your small espresso machine with a bigger, faster, more powerful one. In tech terms, this means upgrading your server with more CPU, RAM, or storage.
Horizontal Scaling (Scaling Out): You add more espresso machines and hire more baristas. In tech, this means adding more servers to your system. The work is distributed across multiple machines.
Vertical scaling is often simpler initially, but it has limits. You can only make one machine so powerful, and it can get very expensive. Horizontal scaling is the standard for most large-scale applications because it's more flexible and doesn't have the same upper limits. You can just keep adding more machines as your needs grow.
Reliability: Working Correctly
A reliable system is one that performs its intended function correctly, even when things go wrong. It's about trust. When you use an ATM, you trust it to dispense the correct amount of cash and accurately debit your account. That's reliability.
In software, this means the system can tolerate faults. A fault could be a server crashing, a network connection failing, or a bug in the software. Reliable systems are designed with these failures in mind. They often use techniques like redundancy (having backup components) and failover (switching to a backup automatically when a primary component fails) to keep things running smoothly.
Think of it this way: Reliability is about correctness. Does the system do the right thing, as defined by its specifications?
Availability: Being Operational
Availability is closely related to reliability, but it's not the same thing. Availability measures the percentage of time a system is operational and able to respond to requests. It's often described in terms of "nines."
High Availability
noun
A quality of a system that guarantees a high level of operational performance for a given period. It's often expressed as a percentage, like 99.999% uptime.
A system can be reliable but not highly available. For example, a system that perfectly processes data but is down for maintenance for an hour every night is reliable in its function but has limited availability. The goal is to maximize uptime and minimize downtime. This is typically calculated with a simple formula.
Even a small difference in percentage points can have a huge impact on the user experience.
| Availability % | Downtime per year |
|---|---|
| 99% ("two nines") | 3.65 days |
| 99.9% ("three nines") | 8.77 hours |
| 99.99% ("four nines") | 52.6 minutes |
| 99.999% ("five nines") | 5.26 minutes |
Maintainability: Keeping It Simple
The best systems are easy to work with. Maintainability refers to the ease with which a system can be repaired, updated, and understood. A system with high maintainability makes life easier for the engineers who have to manage it.
This involves a few key ideas:
- Operability: Making the system easy for an operations team to run smoothly.
- Simplicity: Managing complexity so that new engineers can understand the system without an enormous learning curve.
- Evolvability: Making it easy to change the system in the future, whether that's adding new features, fixing bugs, or adapting to new requirements.
Good maintainability is about fighting complexity. Simple, well-documented, and modular systems are easier to maintain, which saves time and reduces the chance of introducing new bugs during updates.
These four principles are in constant conversation with each other. For instance, scaling out horizontally can improve availability because if one server fails, others can pick up the slack. A highly maintainable system makes it easier to find and fix the bugs that impact reliability. As you design systems, you'll find yourself balancing these concepts to meet your specific goals.
A social media app is struggling to keep up with a surge in new users. To handle the increased load, the company replaces its single, powerful main server with an even more powerful one with a faster CPU and more RAM. What type of scaling is this?
A system that performs its function correctly but is taken offline for maintenance for one hour every day can be described as reliable but not highly available.