Course outline

1.1

Client–Server Architecture and the Request–Response Cycle

Who asks, who answers, and exactly what travels in an HTTP request and response.

30 min Reading + animations

Tip: tap or hover any dotted-underlined term to see what it means.

By the end of this lesson you will be able to

  • Explain the client–server model: who starts a conversation, who holds the data, and why it is called centralised.
  • Walk through the request–response cycle in five phases, from a click to a rendered page.
  • Take a URL apart (scheme, host, port, path, query, fragment) and say who uses each part.
  • Read a raw HTTP request and response: request line, status line, headers, blank line, body.
  • Choose the right method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) and say which are safe and which are idempotent.
  • Interpret status codes from 1xx to 5xx, including the ones interviewers love: 201, 204, 304, 401 vs 403, 409, 429, 502, 503, 504.
  • Explain keep-alive, HTTP/1.1 vs HTTP/2 vs HTTP/3, and how a client should handle timeouts and retries without doing anything twice.

#What client–server means

Client–server architecture is the foundation of web networking. It is a centralised model in which the work is split into two roles:

  • Client: the side that asks for a service or data. Examples: your web browser, a mobile app, Postman, the curl command.
  • Server: the side that holds the data, the logic and the resources in one central place, and answers clients’ requests. Examples: Nginx, Apache, a Node.js/Express app, a Spring Boot server. What a server really is (machine, program, port) is the next lesson; how Nginx, Apache and app servers work inside is in Web Servers and App Servers.
  +-----------------+                          +-----------------+
  |                 | ──── 1. HTTP Request ──► |                 |
  |     Client      |                          |     Server      |
  |  (Browser/App)  | ◄─── 2. HTTP Response ── | (Node/Nginx/…)  |
  +-----------------+                          +-----------------+

The client always speaks first. The server waits, listening on a known address and port (443 for HTTPS), and only ever replies. Clients talk to each other through the server, never directly, and only the server touches the database.

Client and server: who talks to whom

Clients start every conversation. The server sits in one central place and owns the data and the logic.

Scenario

BrowserChromeGET /products
Mobile appAndroid / iOS
Postman / curldeveloper tool
Home router
ISP + internetmany routers
Server203.0.113.10:443
Database
Step 1 of 8
1

You click a link. The browser is the client: it is the side that asks. A server never contacts a browser out of the blue in plain HTTP.

Why build it this way?

  • One source of truth. Data and business rules live in one place, so every client (web, Android, iOS) sees the same thing.
  • Control and security. The server checks every request before acting on it. A client is any program on someone else’s device and can never be trusted.
  • Thin clients. Phones and browsers do not need the whole database or all the logic.

The price is that the server is a bottleneck and a single point of failure (SPOF): if it is slow or down, every client suffers. Real systems therefore run many copies of the server behind a load balancer, which brings its own problems (the next lesson).

#The request–response cycle

Every exchange between client and server follows the same cycle, the HTTP request–response cycle:

  1. 1. Request creation

    The user does something (enters a URL, clicks a button) and the client builds an HTTP request. It contains:

    • HTTP method: what the client wants to do (GET = fetch data, POST = send new data, PUT = update, DELETE = remove).
    • URL / endpoint: the exact destination on the server, for example https://api.example.com/users.
    • Headers: extra metadata about the request, for example Content-Type: application/json or Authorization: Bearer <token>.
    • Body (payload): the actual data sent with POST, PUT or PATCH, such as form data or JSON.
  2. 2. Network transmission

    The request travels over TCP/IP through routers and ISPs to the server’s IP address and port (443 for HTTPS, 80 for plain HTTP). Before the first byte of HTTP, the client must find the IP (DNS, lesson 1.8) and open a connection (TCP and TLS, lesson 1.9), unless it can reuse one.

  3. 3. Server processing

    The server’s router (the code kind, not the network box) looks at the method and path and calls the matching handler. The handler checks who is asking, validates the input, runs the business logic, and reads or writes the database if needed.

  4. 4. Response generation

    The server builds an HTTP response:

    • Status code: the outcome (200 OK = success, 201 Created = a new resource was made, 400 Bad Request = the client made a mistake, 401 Unauthorized = authentication needed, 404 Not Found = no such resource, 500 Internal Server Error = the server failed).
    • Headers: metadata from the server, such as Content-Type: text/html or application/json, or Set-Cookie.
    • Body: the actual content: an HTML page, JSON data, an image…
  5. 5. Rendering or consumption

    The response returns to the client. A browser renders it and shows it to the user; a mobile app processes the data and updates its screens. A page usually needs more: after reading the HTML, the browser sends further requests for CSS, JavaScript, images and fonts, each its own request–response cycle.

The request–response cycle

Five phases: create the request, send it, process it, build the response, render it.

Scenario

You
Clientbrowser / app
ServerNode.js / Nginx
Database
click “Products”
Step 1 of 13
1

A user action (typing a URL, clicking a link or a button) starts every cycle.

#Anatomy of a URL

A URL (Uniform Resource Locator) tells the client which protocol to speak, which machine to contact, on which port, and which resource to ask for.

https://shop.example.com:443/products/42?color=red&size=m#reviews
└─┬─┘   └──────┬───────┘ └┬┘└────┬────┘ └──────┬───────┘ └──┬──┘
scheme        host      port   path         query       fragment
PartExampleWho uses it, and how
SchemehttpsThe client: speak HTTP inside TLS. http means unencrypted
Hostshop.example.comDNS turns it into an IP; it is also sent in the Host header, because one IP can serve many sites
Port443Usually left out: 443 is the default for https, 80 for http. Written only when different, e.g. localhost:3000
Path/products/42The server’s router: which resource (here product 42)
Query?color=red&size=mThe handler: key=value pairs joined by &, for filters, search, pagination
Fragment#reviewsOnly the browser: it is never sent to the server; the page scrolls to that element

Anatomy of a URL: who uses each part

A URL is a set of instructions. Each part is used by a different player.

Scenario

Browser
DNS resolver
shop.example.com203.0.113.10:443
Route handler/products/:id

https://shop.example.com/products/42?color=red&size=m#reviews

Scheme

https

Host

shop.example.com

Port

443 (implied)

Path

/products/42

Query

?color=red&size=m

Fragment

#reviews

Step 1 of 7
1

The whole URL (Uniform Resource Locator) answers four questions: which protocol, which machine, which port, which resource.

#Inside an HTTP message

HTTP (Hypertext Transfer Protocol) is the language clients and servers use for web requests and responses. HTTPS (HTTP Secure) is the same HTTP carried inside an encrypted TLS connection, so nobody on the path can read or change it.

In HTTP/1.1 a message is plain text with a fixed shape: a first line, headers, a blank line, then an optional body.

Inside an HTTP request and response

Every HTTP/1.1 message has the same shape: a first line, headers, a blank line, then an optional body.

Scenario

TCP connection (inside TLS for HTTPS)198.51.100.7:51544 → 203.0.113.10:443
Step 1 of 4
1

First a connection exists: a TCP connection from your port 51544 to the server’s port 443, wrapped in TLS for HTTPS. HTTP text travels inside it.

A real request, as it travels in HTTP/1.1:

POST /api/orders HTTP/1.1
Host: shop.example.com
User-Agent: Mozilla/5.0 (…) Chrome/130
Accept: application/json
Content-Type: application/json
Content-Length: 31
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.k3…

{"productId": 42, "quantity": 2}

And the server’s reply:

HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 52
Location: /api/orders/981
Cache-Control: no-store

{"id": 981, "productId": 42, "quantity": 2, "paid": false}

The very simplest request a browser makes when you open Google looks like this (simplified):

GET / HTTP/2
Host: www.google.com
HTTP/2 200
content-type: text/html

#HTTP methods

The method says what the client wants to do with the resource named by the URL.

MethodMeaningBody?SafeIdempotentTypical success
GETFetch a resourceNo✅✅200 OK
HEADSame as GET, but headers onlyNo✅✅200 OK
OPTIONSWhich methods/origins are allowed here? (CORS preflight)No✅✅204 No Content
POSTSend data to be processed; usually create a new resourceYes❌❌201 Created
PUTReplace the resource at this URL with this full version (or create it there)Yes❌✅200 / 204
PATCHChange only some fieldsYes❌not guaranteed200 / 204
DELETERemove the resourceRarely❌✅204 No Content

Two words in that table matter enormously in system design:

  • Safe: the request does not change anything on the server. Browsers can prefetch it, crawlers can follow it, caches can store the answer.
  • Idempotent: doing it once or ten times leaves the server in the same state. That makes it safe to retry after a timeout. Note that the response may differ: a second DELETE returns 404, but the resource is gone either way.

HTTP methods and what they do to data

Watch the badge under the database: it shows the stored resource after each request.

Scenario

Read. Safe and idempotent.

Client
API server/users
Databaseusers/42 = {name: Rahim, city: Dhaka}
stored
Step 1 of 4
1

The database holds user 42.

There are two rarer methods you may see in references: CONNECT (asks a proxy to open a tunnel, used for HTTPS through proxies) and TRACE (echoes the request back for debugging, normally disabled for security).

Self-checkQuestion

A mobile app times out while sending a request and wants to retry automatically. Which request is safe to retry as-is?

#Status codes

Every response starts with a three-digit status code. The first digit is the class:

ClassMeaningWho should act
1xx Informational“Got it, carry on”Rare in daily work
2xx SuccessIt workedNobody
3xx RedirectionLook elsewhere (or use your cached copy)The client follows automatically
4xx Client errorThe request was wrongThe client must change something
5xx Server errorThe server failedThe server team; the client may retry later

The codes you must know:

CodeNameWhen you see it
100ContinueServer agrees to receive a large body the client asked about (Expect: 100-continue)
101Switching ProtocolsAnswer to a WebSocket upgrade
200OKSuccess, with a body
201CreatedA new resource was created; Location header says where
202AcceptedQueued; will be processed later
204No ContentSuccess, empty body (common for DELETE, PUT)
301Moved PermanentlyResource moved for good; browsers remember it (http → https, old URLs)
302 / 307Found / Temporary RedirectTemporarily elsewhere (e.g. to /login); 307 keeps the method
308Permanent RedirectLike 301 but keeps the method and body
304Not ModifiedYour cached copy is still valid; no body sent
400Bad RequestMalformed or invalid input
401UnauthorizedReally “unauthenticated”: who are you? Log in
403ForbiddenI know who you are; you are not allowed
404Not FoundNo resource at this URL (also used to hide things you may not see)
405Method Not AllowedE.g. DELETE on an endpoint that only allows GET
409ConflictClashes with current state: duplicate, or edited by someone else
413Content Too LargeBody exceeds the server’s limit
422Unprocessable ContentWell-formed but fails validation (some APIs prefer it to 400)
429Too Many RequestsRate limited; check Retry-After
500Internal Server ErrorUnhandled bug or exception on the server
502Bad GatewayA proxy/load balancer got no valid answer from the server behind it
503Service UnavailableOverloaded or in maintenance; temporary, often with Retry-After
504Gateway TimeoutA proxy waited too long for the server behind it

Status codes: what the server is telling you

The first digit is the class: 1xx info, 2xx success, 3xx go elsewhere, 4xx your fault, 5xx our fault.

Scenario

Client
Proxy / load balancerNginx
App server
Database
GET /orders
Step 1 of 7
1

Most traffic first hits a proxy or load balancer, which forwards it to an app server.

#Headers you will meet every day

Headers are Name: value lines (names are case-insensitive). The important ones:

HeaderSent byPurpose
HostClientWhich site on this IP (mandatory in HTTP/1.1)
User-AgentClientWhich browser/app is asking
AcceptClientFormats the client can handle, e.g. application/json
Content-TypeBothFormat of the body, e.g. application/json, text/html; charset=utf-8
Content-LengthBothBody size in bytes, so the receiver knows where the message ends
AuthorizationClientCredentials, e.g. Bearer <token>
CookieClientCookies the browser stored for this site
Set-CookieServerAsk the browser to store a cookie
Cache-ControlBothCaching rules, e.g. max-age=60, no-store
ETag / If-None-MatchServer / ClientA version tag, and the conditional request that gets a 304 if nothing changed
LocationServerWhere to go (redirects), or the URL of a newly created resource (201)
Retry-AfterServerHow long to wait before retrying (429, 503)

You can also invent your own (X-Request-Id for tracing, Idempotency-Key for safe retries). The next lesson is about two of these, Set-Cookie and Cookie, and why they exist at all.

#Connections and HTTP versions

HTTP needs a connection underneath, and opening one is expensive: a TCP handshake costs one round trip, and TLS adds one more (TLS 1.3). The history of HTTP is mostly the story of reusing connections better.

VersionYearTransportWhat changed
HTTP/1.01996TCPOne request per connection, then close
HTTP/1.11997TCPKeep-alive by default: many requests on one connection, but one at a time; Host header mandatory
HTTP/22015TCP + TLSBinary frames, multiplexing many requests at once on one connection, header compression
HTTP/32022QUIC over UDPSame ideas as HTTP/2, but a lost packet only delays its own stream; faster setup; survives network changes

How requests share a connection

Opening a connection costs round trips. Each HTTP version found a better way to reuse it.

Scenario

Browser
Server203.0.113.10
SYN
Step 1 of 8
1

A TCP handshake opens the connection…

  • Keep-alive (persistent connections) avoids a new handshake per request. Servers close idle connections after a timeout to save memory.
  • Head-of-line blocking: in HTTP/1.1 a slow response holds up the ones behind it, so browsers open about six connections per host. HTTP/2 fixes this at the HTTP level, but one lost TCP packet still stalls all streams; HTTP/3 fixes that too by using QUIC.
  • Clients and servers negotiate the version: HTTP/2 during the TLS handshake (ALPN), HTTP/3 when the server advertises it with an Alt-Svc header. Everything else (methods, status codes, headers) is the same in all versions.

#When things go wrong on the client side

A client must assume the network will fail. The common cases:

FailureWhat the client seesWhat to do
DNS failsName not resolvedShow an error; maybe retry later
Server down / port closedConnection refused (fast) or connect timeout (slow)Retry with backoff; try another server
Request or response lostRead timeout: silenceRetry only if idempotent or protected by an idempotency key
4xxAn answer saying the request is wrongDo not retry blindly; fix the input. For 401, get a new token and retry once
429 / 503“Slow down / try later”Wait (Retry-After, or exponential backoff with jitter)
500 / 502 / 504Server-side failureRetry a few times if safe, then show an error

When the answer does not come: timeouts and retries

Networks lose messages. A good client sets a timeout, retries the right things, and never pays twice.

Scenario

Mobile app
Payment API
Payments database
GET /orders/981
Step 1 of 5
1

The request is lost on a weak mobile signal.

The key insight: when a request times out, the client cannot know whether the server never received it or processed it and the answer got lost. That is why:

  1. Always set timeouts (a connect timeout and a read timeout). The default in many libraries is “wait forever”.
  2. Retry only idempotent requests automatically (GET, PUT, DELETE, HEAD).
  3. Make important non-idempotent requests idempotent with an idempotency key: the client sends a unique ID with the request, and the server remembers the result for that ID and replays it instead of doing the work twice.
  4. Use exponential backoff with jitter (wait 1 s, 2 s, 4 s… plus randomness) and a maximum number of attempts, so a struggling server is not crushed by a retry storm.

#Client–server in system design

  • Most of the internet is client–server. Websites, REST APIs, mobile backends, and the services inside a company calling each other (where one service is the client of another).
  • APIs are the contract. Methods, URLs, status codes and headers form the interface between client and server teams. Using them correctly (201 for creation, 409 for conflicts, idempotent PUT) lets proxies, caches and client libraries behave correctly without special code.
  • Scaling the server side means many identical servers behind a load balancer. That works smoothly only if any server can answer any request, which is why HTTP being stateless matters so much: next lesson.
  • Caching uses the same protocol: Cache-Control, ETag and 304 let browsers and CDNs answer requests without reaching your server at all.
  • Failure handling is part of the design: timeouts, retries, idempotency keys and backoff on the client; 503 with Retry-After and rate limits (429) on the server.

#Try it yourself

curl is a command-line HTTP client available on Windows, macOS and Linux.

# See the whole conversation: request headers (>) and response headers (<)
curl -v https://example.com/

# HEAD request: headers only
curl -I https://example.com/

# Follow redirects (-L) and print only the final status code
curl -s -o /dev/null -w "%{http_code}\n" -L http://github.com/

# POST JSON to a test API that echoes back what it received
curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"productId": 42, "quantity": 2}'

# Ask for a status code on purpose
curl -i https://httpbin.org/status/404

# Force HTTP/2 or HTTP/3 (if your curl supports it)
curl -sI --http2 https://www.google.com/ | head -1

On Windows PowerShell, use curl.exe instead of curl (the bare name is an alias for a different command). In a browser, open developer tools (F12), go to the Network tab and reload a page: every row is one request–response cycle, with its method, status, headers, size, protocol (h2, h3) and timing.

#Summary

Key takeaways

  • In client–server architecture the client asks and the server answers; the server holds the data and logic centrally, and only it talks to the database. It is simple and controllable, but the server is a bottleneck and a single point of failure.
  • The request–response cycle: create the request (method, URL, headers, body) → transmit over TCP/IP → server routes, validates, runs logic → builds a response (status, headers, body) → client renders it. One page usually means many cycles.
  • A URL is scheme + host + port + path + query + fragment; the fragment never reaches the server, and secrets never belong in the URL.
  • Methods: GET/HEAD/OPTIONS are safe; GET, HEAD, OPTIONS, PUT and DELETE are idempotent; POST is neither, PATCH is not guaranteed. Idempotent means safe to retry.
  • Status codes: 2xx success, 3xx redirect or cached (301, 302, 304), 4xx client error (400, 401 unauthenticated, 403 forbidden, 404, 409, 429), 5xx server error (500 code bug, 502/504 from the proxy, 503 temporary).
  • Connections: HTTP/1.1 keep-alive reuses a connection one request at a time; HTTP/2 multiplexes; HTTP/3 uses QUIC so packet loss only delays one stream.
  • Clients must handle failure: timeouts always, retries with backoff and jitter, and idempotency keys for anything that must not happen twice.