Fundamentals
Core building blocks and trade-offs behind designing software systems
Overview
System design is the process of defining how the parts of a software system fit together to meet functional and non-functional requirements. It matters because early structural decisions shape performance, cost, and how easily a system can grow. Beginners should focus on the recurring building blocks: clients, servers, databases, caches, and the network between them.
Syntax / Usage
Most systems share the same high-level shape: a client sends a request, a server processes it, data is stored or read, and a response comes back. Non-functional requirements (latency, availability, scalability) drive which components you add.
[ Client ] --> [ Load Balancer ] --> [ App Servers ] --> [ Database ]
|
[ Cache ]
Key trade-offs to always weigh:
- Consistency vs. availability (you often can't fully have both under failure)
- Latency vs. throughput
- Cost vs. redundancy
Examples
A URL shortener: the client submits a long URL, the app server generates a short key, stores the mapping in a database, and returns the short link. Reads (redirects) hugely outnumber writes, so a cache in front of the database is a natural fit.
A basic to-do app: a single app server plus one database is enough. Adding a load balancer or cache here would be premature optimization for a low-traffic system.
Common Mistakes
- Designing for massive scale before you have any users
- Ignoring non-functional requirements like availability and latency
- Treating the database as an afterthought instead of a core component
- Adding components (caches, queues) without a clear reason
- Forgetting that every network hop can fail
See Also
system-design-client-server system-design-scalability system-design-databases