System Design Foundations: What and Why
Understand what system design is, how software systems are evaluated, and how to reason about requirements before choosing technologies.
What System Design Actually Means
System design is the process of deciding how software components cooperate to deliver a product under real constraints. It covers responsibilities, interfaces, data ownership, deployment, failure handling, security, and operational behavior—not just drawing boxes or choosing a database.
Imagine building a URL shortener. The visible feature is simple: accept a long URL and return a short code. A production design must also answer questions such as how codes are generated, how redirects stay fast, how abuse is prevented, what happens when a database is unavailable, and how the service scales during a traffic spike.
A system is a collection of interacting parts. A design is the set of decisions and trade-offs governing those parts. Good design is contextual: a small internal tool and a global consumer service should not automatically use the same architecture.
- System design includes behavior, data, deployment, and operations.
- There is rarely one universally best architecture.
- Start from user outcomes and constraints, not fashionable technologies.
Which activity belongs most directly to system design?
Functional vs. Non-functional Requirements
Functional requirements describe what the system must do: register users, publish a post, upload a file, or process a payment. Non-functional requirements (NFRs) describe qualities and constraints: latency, availability, durability, security, cost, maintainability, and compliance.
Turn vague goals into measurable statements. “Fast” could mean p95 read latency below 200 ms for a specified workload. “Highly available” could mean 99.95% monthly availability for a defined API. Numbers must be negotiated with stakeholders; they are not universal defaults.
Separate must-haves from preferences. A payment platform may prioritize correctness and auditability over accepting every request during a partition. A social feed may prefer serving slightly stale content over failing completely. These choices influence architecture long before code is written.
- Functional example:
A user can create and retrieve a shortened URL. - Quality example:
95% of redirects complete within 100 ms in the target region. - Constraint example:
Personal data must be encrypted and retained for a defined period.
- Write observable requirements.
- Attach a workload, percentile, region, and time window to performance targets.
- Different product features may require different consistency and availability choices.
Which is a non-functional requirement?
A Repeatable System Design Process
Use a repeatable sequence rather than jumping immediately to microservices:
- Clarify product scope and user journeys.
- Quantify scale and workload.
- Define APIs and important data entities.
- Sketch a simple high-level architecture.
- Deep-dive into the highest-risk components.
- Evaluate bottlenecks, failures, security, and consistency.
- Explain trade-offs and how the system will be operated.
A design is a set of hypotheses. For each important choice, record the reason, alternatives, costs, and conditions that would trigger reconsideration. For example, a single relational database may be the simplest initial choice; read replicas or partitioning can be introduced when measurements show a specific bottleneck.
Avoid premature complexity. Every queue, cache, service, and replica introduces failure modes, operational burden, and new consistency questions.
- Design from requirements to architecture.
- Keep the first design as simple as possible while meeting requirements.
- Document why a decision was made and what evidence could change it.