System Design Β· Chapter 03

Web Architecture, From Client to Server and Back

How a browser talks to a backend, why we put an API in between, and every technique for moving data across that gap, from plain requests to persistent real-time streams.

🧭
How to read this

The chapter is built as a chain: each concept exists to fix a limitation of the one before it. Read top to bottom and you'll watch the architecture assemble itself. Anything marked [+] is context added beyond the source course to fill a gap it assumed you already knew.

01

The shape of a web application

What "web architecture" actually refers to

Web architecture is the set of components that run together to form an online service: a user interface, a server running business logic, a database, plus optional pieces like a cache and a message queue. Understand how these connect and you can extend the same blueprint to satisfy almost any requirement.

Nearly every online product you use, a WordPress blog, Facebook, your banking app, is assembled from these same parts. The rest of this chapter zooms into each one, starting with the relationship that everything else is built on: the client and the server.

Client browser / app SERVER SIDE API gateway Database Cache Message queue Worker
Figure 1 β€” The components of a typical web application. The client only ever talks to the API; everything behind it, database (blue writes/green reads), cache (amber), and asynchronous queue work (purple), is hidden from the client.
02

Client-server, the core loop

The request-response model that underpins the web

The client-server model is the foundation of the web. It runs on one simple rule: the client asks, the server answers. The client sends a request for information; the server does whatever work is needed and sends back a response. No request means no response, ever.

This pattern is so universal that almost every site and app is built on it. The main exception is peer-to-peer architecture, where machines talk to each other directly without a central server; only a small slice of the web uses it, and the course returns to it much later.

Client asks Server answers 1 request 2 process 3 response
Figure 2 β€” The request-response loop. Blue carries the request out; green carries the response back. Without step 1, steps 2 and 3 never happen.
03

The client and what runs on it

The user interface, and the two flavors of client

The client is where your user interface lives, the presentation layer written in HTML, CSS, and JavaScript that controls look and feel. Think of it as the gateway into your application. It can be a mobile app, a desktop program, a tablet, or even a command-line console issuing commands to the backend.

Two kinds of client

Clients split into two types based on where the business logic lives:

Type Holds business logic? Typical examples
Thin client No, UI only. Every action is a request to the backend, like a three-tier app. A standard web app in a browser
Thick (fat) client Yes, all or part of the logic runs locally, like a two-tier app. Utility apps, desktop software, online games

What clients are built with

Web UIs are written mostly in JavaScript and its ecosystem: vanilla JavaScript, jQuery, React, Angular, Vue, Svelte, and others. Different platforms demand different toolkits, an Android front-end uses a different stack than an iOS or Windows one. The specific library matters less than the role: the client renders the interface and talks to the server.

πŸ’‘
Thin vs. thick maps onto the tier model [+]

A thin client is the front of a three-tier system (UI Β· logic tier Β· data tier, all separated). A thick client collapses UI and logic together, the classic two-tier setup. If you've studied application tiers, this is the same idea seen from the client's side.

04

The server and its many forms

Where requests are received and business logic runs

A server's core job is to receive requests from clients, run the appropriate business logic using the request parameters, and return a response. The server that runs your application code has a specific name: the application server.

But "server" is a broad word. Alongside application servers, specialized servers each own a narrow task:

Proxy serverSits in front of other servers, forwarding traffic.
Mail serverSends and receives email.
File serverStores and serves files.
Virtual serverA software-defined server running on shared hardware.
Data storage serverDedicated to persisting data.
Batch job serverRuns scheduled or bulk background jobs.

The choice of server software follows the use case. Java backend code runs on Apache Tomcat or Jetty; a plain static website is happy on the Apache HTTP Server. In modern development, every component, the database, the cache, the message queue, even the UI, gets its own dedicated server.

πŸ–₯️
Servers can render the UI too

Sometimes the server builds the interface itself and ships finished HTML to the client. That's server-side rendering, covered in detail in the final section, where its tradeoffs against client-side rendering decide which one you should reach for.

05

How they actually talk (HTTP)

The protocol, its statelessness, and the endpoints in between

All client-server communication travels over HTTP, the request-response protocol of the web. It defines how information moves across the wire. Its defining trait: it is stateless. Every exchange is treated as brand new, with no memory of anything that came before.

⚠️
Statelessness has a real consequence

Because the server remembers nothing between requests, the client must resend its authentication credentials every single time. That's how the backend re-checks, on each request, whether the caller is allowed to touch the data it wants.

Endpoints, the addresses clients call

In an n-tier app, a client never reaches into the backend directly. It hits an endpoint, a URL the service exposes. A birthday-reminder app, for instance, would call Facebook's Social Graph API (itself a REST API) at a known URL to fetch friends' birthdays, then run its own logic on the returned data. The next sections explain what these APIs are and why they exist, so if endpoints feel abstract here, that's expected.

πŸ”‘
The one line that carries the whole chapter

The client and server communicate only through an interface of endpoints. Neither knows how the other is built. That deliberate ignorance is the foundation everything after this depends on.

06

Why an API sits in the middle

The interface that decouples everything

An API (Application Programming Interface) is the interface an online service presents to the outside world. Every interaction, client-to-server and service-to-service, flows through one. Search a product on an e-commerce site and the backend answers via an API. A single service typically runs many: one API for search, one for payments, one for reviews, each usually backed by its own microservice, and those microservices call each other through APIs as well.

The reason web-scale companies (Uber, Amazon, Facebook, LinkedIn) build everything on APIs comes down to three payoffs:

  1. Loose coupling. An API is a well-defined contract that hides the backend code. Change the backend without breaking clients; change a client without touching the backend. Neither side is chained to the other.
  2. New clients for free. iOS, Android, a browser, a third-party service, any new client can join as long as it follows the contract. The backend doesn't change to welcome it.
  3. Extending the platform. Google Workspace can't build every feature itself, so it publishes APIs and lets outside developers build on top. The product's capabilities keep growing without the core team writing that code.
πŸ“œ
What "the contract" means [+]

The contract is the documented set of endpoints, their required parameters, and the shape of the data they return. Follow it and your client works, regardless of language or platform. It's the promise that lets both sides evolve independently.

Three paradigms dominate how APIs are structured, each with its own rules and best-fit use case: REST, GraphQL, and RPC. The next three sections take them one at a time.

07

REST, the default choice

Stateless, HTTP-native, and simple to consume

REST (Representational State Transfer) is an architectural style for web services; services that follow it are "RESTful." A REST API communicates mostly over HTTP, using HTTP methods as its verbs, and it lets servers cache responses to boost performance. Like HTTP itself, it's stateless: each call is self-contained and carries its own auth.

Endpoints decouple the two sides

A REST endpoint is just a URL the client can hit, for example https://myservice.com/users/{username} to fetch one user. The backend publishes these URLs and effectively says: "Here's the address of what you need, hit it when you want it, as long as you're authorized." Different clients (mobile browser, desktop browser, tablet, an API testing tool) all consume the same endpoints while being written in totally different codebases.

Why REST was a leap forward

Before REST, backend and client were tightly coupled. With Java Server Pages, business logic got embedded in JSP tags right on the UI, and the backend needed a separate servlet for each client type, one for mobile, another for web. Refactoring was painful because logic was smeared across layers.

REST erased that. The backend stopped caring about client type; it just exposes endpoints and returns a standard format like JSON, which each client parses and renders. Adding a new client became trivial.

πŸšͺ
REST is also your front door

A REST API doubles as a gateway, a single entry point that wraps the business logic and handles authorization, authentication, and input sanitization before anything reaches your application resources.

08

GraphQL, ask for exactly what you need

The fix for over-fetching and under-fetching

With REST, the server decides the shape of the response. That creates two problems. Over-fetching: you hit /products and get names, descriptions, prices, and inventory when your Android list only needs names and prices, wasting bandwidth mobile clients can't spare. Under-fetching: to show a product with its reviews and related items, you fire three separate REST calls and stitch them together on the UI.

REST Β· 3 ROUND TRIPS Client /products/id /reviews /related GRAPHQL Β· 1 QUERY Client GraphQL server 1 query exact fields
Figure 3 β€” Where REST needs three round trips to assemble one screen, GraphQL resolves the same data in a single query returning only the requested fields.

GraphQL is a query language and runtime for APIs where the client declares exactly which fields it wants. The server returns just those, in one response, no over-fetching, no multiple round trips. A single query can pull a product plus its reviews plus related products at once.

βš–οΈ
Power with a cost

GraphQL shines only when data needs are genuinely complex. For simple use cases it's overkill, the same verdict the course gives RPC. Reach for it when clients juggle varied data from multiple sources; skip it otherwise.

Aggregating many sources into one response

GraphQL can also merge data from multiple backend services into a single query result, via two approaches:

Approach How it works Best for
Schema stitching A gateway combines several individual schemas into one unified schema. More centralized. Integrating multiple APIs into one; simpler cases.
Schema federation Each service owns a "subgraph" of the schema; a gateway coordinates queries across them. More decentralized, lets teams work independently. Distributed systems needing scalability and independent ownership.
09

RPC, calling remote code like local code

The high-performance paradigm for service-to-service work

RPC (Remote Procedure Call) lets a client invoke a function on a remote server as if it were a local function call. It hides all the networking and serialization plumbing, so from the caller's view there's no difference between "run this here" and "run this on another machine." It typically rides lightweight protocols (gRPC, JSON-RPC, XML-RPC) that are leaner and faster than REST.

⚑
Why gRPC is fast

gRPC, Google's open-source RPC framework, serializes data with protocol buffers: think JSON, but binary, smaller, and quicker. Google uses it internally for high-frequency microservice communication at scale.

When RPC wins, and when REST does

RPC's binary protocol beats REST's JSON on bandwidth and speed, so it fits performance-critical, high-throughput, real-time systems. Its standout feature is bidirectional streaming: client and server can push messages to each other over a single connection, which REST doesn't support out of the box. That makes RPC the backbone of live video, collaborative editing, and online gaming, and a favorite for inter-microservice communication. Uber, for example, uses gRPC bidirectional streaming to keep pickup times, arrival times, and route lines synced live on screen.

So why ever use REST? Because for public-facing, standard CRUD work, REST is simpler and more universal:

REST RPC (gRPC)
Data format JSON, human-readable, easy to debug Binary protocol buffers, compact and fast
Client needs Any HTTP client, cURL, Postman, a browser A specific client library for protobuf + gRPC
Coupling Loose, widely understood Tighter, client and server share the library
Best fit Public APIs, simple CRUD, not performance-critical Real-time, high-throughput, service-to-service
10

Pull vs. Push, who starts the conversation

Two modes of moving data over HTTP

Data crosses the client-server gap in one of two modes, and the difference is simply who initiates each exchange.

HTTP Pull, the client keeps asking

This is HTTP's default. The client pulls data whenever it wants it, and to stay current it asks again and again. There are two ways to pull: manually (a user clicks a button, firing a GET request) or automatically at intervals using AJAX, a technique called polling.

AJAX (Asynchronous JavaScript and XML) lets a page fetch fresh data in the background, without a reload, and update just one section via a callback. It uses the browser's built-in XMLHttpRequest object and is often paired with jQuery. News tickers and live sports scores work this way.

πŸ’Έ
The problem with pull

Every request costs bandwidth and server load, even when nothing has changed. The client can't know there's no update, so it keeps hammering the server. Excessive polling can literally take a server down.

πŸ”€
Don't confuse polling with long polling

AJAX polling is pure HTTP Pull. AJAX long polling is a hybrid of pull and push (built on the Bayeux protocol) covered in the push-technologies section. Same family, different mechanics.

HTTP Push, the server calls you back

Push flips the initiative. The client requests once, then the server pushes new updates on its own whenever they become available. No repeated asking, far less bandwidth, far less load. It's a callback: the client phones in, the server says "I don't have it yet, I'll call you back," and later it does. User notifications are the everyday example. Clients still use AJAX to open the initial request in both modes.

HTTP PULL Β· client repeats Client Server empty? …again… …again… HTTP PUSH Β· request once Client Server 1 request server pushes updates Wastes bandwidth on empty responses. Saves bandwidth; server talks only when there's news.
Figure 4 β€” Pull spends requests whether or not data changed; push spends one request and lets the server drive. The bandwidth difference is the whole reason push technologies exist.
11

Keeping the line open

TTL, persistent connections, and heartbeats

Push depends on the connection staying open, but HTTP fights that. Every request has a Time to Live (TTL), roughly 30 to 60 seconds depending on the browser. If no response arrives in that window, the browser kills the connection and the client must retry. TTL exists for a reason: open connections eat resources, and a server can hold only so many, let them pile up and it runs out of memory.

So what if you know a response will take longer than the TTL, or that you want a continuous stream? You need a persistent connection, one that stays open for future requests and responses instead of closing after a single exchange. This is what makes HTTP Push possible.

  1. The TTL threat. The browser will kill any connection that goes quiet for too long.
  2. Heartbeat interceptors. To keep the line alive, client and server exchange tiny blank request-responses, "heartbeats", so the browser sees activity and doesn't cut the cord.
  3. The tradeoff. Persistent connections are resource-intensive compared to plain pull. You accept that cost when the feature demands it, a browser-based multiplayer game has far more request-response activity in a short window than an ordinary web app, so a persistent connection is worth it for the experience.
πŸ”Œ
How persistent connections get built

Long-lived connections are implemented through the techniques in the next section: AJAX long polling, WebSockets, and Server-Sent Events, each keeping the channel open in its own way.

12

The five push technologies

Choosing the right channel for the job

Five techniques establish and use a persistent connection. They differ mainly in direction of data flow and how long the connection lingers.

SERVER β†’ CLIENT (one-way) Client Server Long polling Β· SSE Streaming over HTTP CLIENT ⇄ SERVER (bidirectional) Client Server WebSockets (runs over TCP, not HTTP)
Figure 5 β€” Grouped by data direction. Most push technologies flow one-way from server to client; only WebSockets are truly bidirectional, and they alone leave HTTP for raw TCP.
Technology Direction & behavior Best for
AJAX long polling Sits between polling and WebSockets. The server holds the request open until it has an update, rather than returning empty. Fewer requests than plain polling; if the connection breaks the client reconnects. Simple async fetches where you don't want to poll constantly.
WebSockets Persistent, bidirectional, low-latency. Runs over TCP, not HTTP. Both client and server must support it. Connection stays open as long as you like. Chat, messaging, real-time social streams, browser multiplayer games, high read-write apps.
Server-Sent Events (SSE) Server pushes data to the client automatically once the client opens the connection. Data flows one way only, server to client. UI uses the HTML5 Event-Source API; incoming messages are treated as events. Real-time feeds, stock quotes, live notifications.
Streaming over HTTP Breaks large data into chunks sent over HTTP, using HTML5 and a JavaScript Stream API. Both sides agree on stream start and end. Lets you play a video as it downloads. Streaming multimedia, large images and video.
Message queues Listed by the course as a push mechanism; used to deliver events and notifications reliably (detailed in its own chapter). Decoupled, reliable event delivery between components.
🎯
Pick by direction and volume

Need two-way, high-frequency traffic? WebSockets. Need one-way live updates? SSE. Occasional async data without constant polling? Long polling. Big files? HTTP streaming. The right choice is dictated entirely by what your app has to do.

13

Client-side vs. server-side rendering

Where the HTML gets built, and why it matters

When a browser receives a page, it has to render it, work handled by several internal components (browser engine, rendering engine, JavaScript interpreter, networking, UI backend, storage). The rendering engine builds the DOM tree, then lays out and paints the page. All of that takes time before the user can interact. That's client-side rendering.

Server-side rendering moves that work upstream: the server generates finished HTML and ships it ready-made, so the browser has little to assemble. The page appears faster.

Approach Strengths Weaknesses
Server-side rendering Fast first paint; great for static content like WordPress blogs; SEO-friendly because crawlers read the generated HTML easily. For AJAX-heavy sites it regenerates the whole page per request, wasting bandwidth and load; buckles under many concurrent users.
Client-side rendering Ideal for modern, dynamic, AJAX-driven sites where only a section needs updating on the fly. Slower initial render; the browser does the assembly work.
🀝
You don't have to choose just one

A hybrid gets the best of both: server-render the static content (fast load, good SEO) and client-render the dynamic parts (smooth updates). Match the technique to the content, not the whole app.

14

Recap

The chapter in a dozen chips

Client-server is the baseClient asks, server answers. No request, no response.
Thin vs. thick clientUI-only vs. logic-carrying. Maps to three-tier vs. two-tier.
HTTP is statelessNo memory between calls, so auth rides along every request.
The API decouples everythingA contract that hides the backend and welcomes any client.
REST = the defaultStateless, HTTP-native, JSON, simple, universal.
GraphQL = exact fieldsKills over- and under-fetching; overkill when simple.
RPC = speed + streamingBinary, bidirectional; great for internal, real-time work.
Pull vs. pushClient keeps asking vs. server calls back. Push saves bandwidth.
Persistent connectionsBeat TTL with heartbeats; costly but needed for real-time.
WebSockets are two-wayBidirectional over TCP; SSE and streaming are one-way.
SSR vs. CSRFast/SEO vs. dynamic. Hybrid blends both.
Pick by use caseEvery choice here is a tradeoff, not a winner.
🧠
The single idea underneath it all

Every concept in this chapter is one more answer to a single question: how do two independent machines exchange data efficiently without being chained to each other? The API decouples them, the paradigm (REST/GraphQL/RPC) shapes the exchange, and the transfer mode (pull/push and its technologies) decides who talks when. Master that spectrum and you can reason about any web system's plumbing.

15

Further reading

Every external resource the course links, grouped and verified

Protocol & communication foundations

  1. MDN β€” An overview of HTTP

    The definitive primer on the request-response protocol that carries almost everything in this chapter. [+] Linked from the "Communication" lesson.

  2. MDN β€” The WebSocket API

    Reference for the only truly bidirectional push technology; covers opening, messaging, and closing a socket.

  3. web.dev β€” Introducing WebSockets: Bringing Sockets to the Web

    The classic "bringing sockets to the web" walkthrough from the push-technologies lesson. [+] Flag: the old HTML5 Rocks URL now redirects here, and the article is dated 2012, code and browser-support notes are outdated, so read it for the concept, not the syntax; MDN above is the current source of truth.

  4. MDN β€” Server-Sent Events

    How one-way server-to-client streaming works via the Event-Source API; the practical companion to the SSE row in the table.

  5. MDN β€” Streams API

    The JavaScript Stream API behind "streaming over HTTP," for chunked delivery of large media.

API paradigms

  1. gRPC β€” official site

    Google's high-performance RPC framework and the home of protocol buffers; start here to see RPC's binary approach in practice.

Industry & context

  1. Stack Overflow Developer Survey

    Referenced in the "Client" lesson for popular front-end technologies. [+] Flag: the course pointed at an older year's results; this is the live survey hub, so the popular-framework rankings will differ materially from when the course was written.

πŸ”Ž
A note on the Uber and Facebook mentions

The course cites Uber's gRPC push platform and Facebook's Social Graph API inline as examples rather than as formal links, so they aren't listed above. Both are real and searchable if you want the primary write-ups.