System Design
Client-Server Architecture Explained
It's the model behind nearly every app, website, and online service you use - one side asks, the other answers. Simple in principle, and the foundation for everything else in system design.
Nearly every digital service you use runs on the same basic shape. When you load a web page, check your email, send a message, or stream a video, one piece of software is asking for something and another is answering. That arrangement - one side that requests, one side that responds - is client-server architecture, and it's the foundation almost all of modern computing is built on.
It's a simple idea, but understanding it properly unlocks everything else in system design, because every more advanced concept - load balancing, caching, APIs, databases - is ultimately about making this client-server conversation faster, more reliable, and able to handle more users. This guide explains the model from the ground up: what clients and servers are, how they communicate, the common variations, and why this architecture dominates.
The two roles
Client-server architecture divides the work of a system into two roles:
- The client is the side that requests services. It's what the user interacts with - a web browser, a mobile app, a desktop application. The client's job is to present information to the user, collect their input, and send requests to the server. When you tap a button in an app, the client packages up what you want and asks the server for it.
- The server is the side that provides services. It's a powerful computer (or, usually, many of them) that waits for requests, does the work - looking up data, running logic, storing information - and sends back responses. The server holds the shared data and the business logic that all clients rely on.
The relationship is asymmetric and clear: clients initiate, servers respond. A client makes a request; the server fulfills it and replies. The server doesn't reach out to clients on its own (in the basic model - real-time variations like WebSocket change this, which we'll touch on). This request-response cycle is the heartbeat of the architecture.
sequenceDiagram
participant U as User
participant C as Client (browser/app)
participant S as Server
participant D as Database
U->>C: taps "show my orders"
C->>S: request: GET /orders
S->>D: query the data
D->>S: returns order records
S->>C: response: order data
C->>U: displays the orders
This sequence diagram shows a full client-server interaction. A user taps "show my orders" in the client app. The client sends a request to the server. The server queries the database, which returns the order records. The server sends the data back to the client as a response, and the client displays the orders to the user.
How they communicate
Clients and servers talk over a network - usually the internet - using agreed-upon rules called protocols. The most common protocol for web communication is HTTP (and its secure version, HTTPS), the same protocol your browser uses for every page it loads.
The communication follows the request-response pattern:
- The client sends a request to the server's address, specifying what it wants.
- The server receives the request, processes it (perhaps reading from a database, running some logic), and prepares a response.
- The server sends the response back to the client.
- The client receives the response and does something with it - displays it, stores it, updates the screen.
For this to work, the client needs to know the server's address (found via DNS, which translates a human-friendly domain name into the server's network address) and both sides need to speak the same protocol. The structured way a client asks a server for things - what requests are valid and what responses to expect - is the server's API, the contract between them.
Note: A single server typically handles many clients at once. Thousands or millions of clients can be sending requests to the same service simultaneously. This is precisely why all the scaling techniques in system design exist - load balancing, caching, horizontal scaling - they're about helping the server side keep up with a huge number of clients without slowing down or falling over.
Why split into clients and servers?
The separation isn't arbitrary - it solves real problems and provides real benefits:
- Centralized data and logic. The server holds the single source of truth. Every client sees the same data because they all talk to the same server. If you and a friend both check the same shared document, you both get the current version because it lives on the server, not on either of your devices.
- Clients can be lightweight. Because the heavy lifting (data storage, complex processing) happens on the server, clients can be relatively simple - even a basic phone can use a powerful service, because the power lives on the server.
- Security and control. Sensitive data and critical logic live on the server, under the operator's control, rather than being distributed to every client device where they'd be exposed. The server decides what each client is allowed to see and do.
- Easier updates. Update the logic on the server, and every client immediately benefits - no need to update millions of client devices. This is why web apps can change overnight without you installing anything.
- Scalability. The client and server sides can be scaled independently. You can add more servers to handle more clients without changing the clients at all.
The tiers: 2-tier, 3-tier, and n-tier
Client-server systems are often organized into tiers (layers), and the number of tiers describes how the responsibilities are divided.
2-tier is the simplest: clients talk directly to a server that includes both the application logic and the database. It's straightforward but couples the logic and data tightly together, which limits how independently you can scale or change each.
3-tier is the most common modern arrangement and separates the system into three layers:
- Presentation tier - the client: the user interface the person interacts with.
- Application tier - the server's business logic: the rules and processing that make the application work.
- Data tier - the database: where information is stored and retrieved.
graph LR
P[Presentation Tier<br/>client / UI] --> A[Application Tier<br/>business logic]
A --> D[Data Tier<br/>database]
This diagram shows the three-tier architecture. The presentation tier, which is the client or user interface, connects to the application tier, which holds the business logic. The application tier connects to the data tier, which is the database where information is stored.
The power of three-tier separation is that each layer can be developed, scaled, and changed independently. You can scale the application tier by adding more servers without touching the database, or swap the database without changing the client. This separation of concerns is why three-tier is the default for so many web applications.
N-tier extends the idea further, splitting the system into even more specialized layers - separating caching, message queuing, authentication, and other concerns into their own tiers. A microservices architecture is, in a sense, a highly decomposed n-tier system. More tiers mean more flexibility and independent scaling, at the cost of more complexity.
Thick clients vs thin clients
Client-server systems also differ in how much work the client does:
- A thin client does very little itself - mostly displaying what the server sends and forwarding user input. The server does almost all the work. A simple web page is a thin client: the browser just renders what the server provides. Thin clients are easy to manage and update (the logic is all on the server) but depend entirely on a connection to the server.
- A thick client (or "fat client") does significant processing on its own. A modern single-page web app or a feature-rich mobile app handles a lot of logic locally and only contacts the server when it needs shared data. Thick clients can be faster and can work partially offline, but they're more complex and harder to update.
Most modern applications land somewhere in between, balancing responsiveness (more work on the client) against simplicity and consistency (more work on the server).
Client-server vs peer-to-peer
It's worth knowing the main alternative to understand client-server by contrast. In a peer-to-peer (P2P) architecture, there's no central server - every participant ("peer") acts as both client and server, requesting from and providing to others directly. File-sharing networks and some blockchain systems use this model.
The trade-off is clear. Client-server centralizes control, data, and logic, which makes it easier to manage, secure, and keep consistent - at the cost of the server being a potential bottleneck and point of failure. Peer-to-peer distributes everything, which makes it highly resilient (no central point to take down) and scalable in some ways, but much harder to control, secure, and keep consistent. The vast majority of applications use client-server because the central control it provides is worth far more than the decentralization P2P offers.
What happens when you load a web page
To see client-server architecture in motion, follow what happens the instant you type a web address and press enter - it's a client-server conversation from start to finish:
- Your browser (the client) needs the server's address. It asks DNS to translate the human-friendly domain name into the server's actual network address.
- The client establishes a connection to the server over the network, using the agreed protocols.
- The client sends an HTTP request - essentially "please send me this page."
- The server receives and processes the request. It may run application logic and query a database to gather what's needed.
- The server sends back an HTTP response - the page's content, along with a status code indicating success or failure.
- The client renders the response - your browser turns the returned content into the page you see.
Every web page you've ever loaded followed this dance. And because the server can serve this same content to countless clients, a single service reaches a global audience. Each step in this flow is also where a system design concept lives: DNS resolution, connection handling, load balancing across servers, caching responses, database queries - they're all about making this exact conversation faster and more reliable at scale.
Request-response and its real-time cousin
The basic client-server model is request-response: the client always initiates, the server answers, and the server never speaks unless spoken to. This is perfect for most interactions - you ask for a page, you get a page.
But some applications need the server to send data to the client without being asked - a chat message arriving, a live score updating, a notification. The pure request-response model can't do this directly; the client would have to keep asking ("any new messages? any new messages?"), which is wasteful. This is why real-time technologies like WebSocket exist: they establish a persistent, two-way connection so the server can push data to the client the moment it's available. It's a variation on client-server - still a client and a server - but one where the strict "client always asks first" rule is relaxed to let the server initiate too.
Scaling the server side
The reason client-server architecture connects to everything in system design is that the server side is where scaling happens. One server can only handle so many clients before it slows down or fails. As a service grows from hundreds to millions of clients, the server side must grow with it - and that growth is what nearly every system design technique addresses:
- Load balancers spread client requests across many servers so no single one is overwhelmed.
- Caching stores frequent responses so the server can answer without repeating expensive work.
- Database scaling (replicas, sharding) helps the data tier keep up with demand.
- Horizontal scaling adds more servers to handle more clients.
All of these exist to help the server side of the client-server relationship serve a growing number of clients reliably and quickly. That's why understanding this architecture is the foundation: everything else is an answer to the question "how do we make the server side handle more clients?"
The database is part of the picture
One refinement worth making: in most real systems, the "server" isn't a single thing but the whole back end, and a critical part of it is the database. When a client makes a request, the application server often needs to read or write data, so it talks to a database - which is itself a server the application server acts as a client to. This layering (client → application server → database) is the three-tier architecture in action, and it's why the data tier is treated as its own concern with its own scaling challenges. The client-server pattern even repeats within the back end: the application server is a server to the user's client, and a client to the database. Recognizing this nesting helps the whole architecture make sense.
Examples in the wild
It helps to see how universal the pattern is. Almost everything you do online is client-server:
- Web browsing: your browser (client) requests pages from web servers.
- Email: your mail app (client) talks to mail servers that store and route messages.
- Streaming: your video app (client) requests video data from streaming servers.
- Mobile apps: the app on your phone (client) constantly talks to backend servers for data.
- Online gaming: game clients communicate with game servers that hold the shared game state.
- Cloud storage: your device (client) syncs files with storage servers.
In every case, the same shape: a client that requests and presents, a server that stores and processes. Once you recognize the pattern, you see it everywhere - which is exactly why it's the foundation worth understanding first.
Why it matters in interviews
Interview: Client-server is the implicit foundation of nearly every system design question - when you're asked to "design X," you're almost always designing the server side of a client-server system. Understanding the tiers helps you structure your design: the client (presentation), your application servers (logic), and your data stores (data). Being able to talk about separating these concerns, and scaling each tier independently, is exactly the structured thinking interviews look for. Most of the building blocks you'll add - load balancers, caches, databases - are about strengthening one tier of this architecture.
The bottom line
Client-server architecture is the simple, powerful idea underneath almost all of modern computing: one side requests services, the other provides them, communicating over a network using shared protocols. The server centralizes data and logic, clients stay relatively lightweight, and the two sides can be scaled and updated independently. Organized into tiers - presentation, application, data - the model separates concerns cleanly and forms the skeleton that every more advanced system design concept builds upon.
Master this foundation and the rest of system design becomes much clearer, because almost everything else is about making this client-server conversation faster, more reliable, and able to serve more people. We start exactly here and build all the way up across System Design Fundamentals.
Go deeper
- Client-server model (Wikipedia) - the foundational architecture in depth.
- Multitier architecture (Wikipedia) - how 2-tier, 3-tier, and n-tier systems are structured.
- Peer-to-peer (Wikipedia) - the main decentralized alternative.
- What is a web server? (MDN) - the server side of the web explained.