Skip to content

HTTP: Requests, Status Codes, and How the Protocol Evolved

HTTP is the protocol every web request runs on: how the stateless request-response cycle works, what status codes mean, and what HTTP/2 and HTTP/3 changed.

Tuan Tran Van
11 min read
Contents (10 sections)
  1. What is HTTP?
  2. How a request travels from your browser to the server
  3. What is inside an HTTP request?
  4. What the HTTP methods actually mean
  5. Responses and the status code families
  6. How HTTP evolved from 0.9 to HTTP/2
  7. What HTTP/3 and QUIC change
  8. HTTP in practice: the foundation of APIs, and its security downside
  9. How much HTTP is enough?
  10. References

HTTP is a TCP/IP-based application layer protocol that standardizes how clients and servers talk to each other.

It is the foundational abstraction layer of the web, defining the syntax and semantics for requesting and transmitting content across distributed networks. Without it, standardized resource linking and universal data exchange would not exist.

You work with a high-level standard that leans on lower-level transport protocols to actually move the bits. It lets browsers and servers exchange data packets, so what a client asks for arrives at its destination and the receiving host reads it correctly. It is the delivery system of the internet, directing the flow of HTML, images, and data across the protocol stack.

HTTP data flowing between a browser and a server across the internet — the article's theme image

What is HTTP?

HTTP is the abstraction layer at the top of the protocol stack. It does not handle the physical transmission of data; instead, it sets the standard for how hosts—clients and servers—identify resources and exchange messages. Standard HTTP traffic runs on port 80 by default, while the encrypted variant, HTTPS, uses port 443 for secure transmission over TLS.

Client-server model: the browser sends a request over port 80, while HTTPS encrypts traffic over port 443

The protocol is stateless: the server keeps no information about the client between separate requests. Every request is an isolated event. That choice means each request has to include all the metadata — authentication tokens, session identifiers — the server needs to carry out the command without looking back at earlier interactions.

Communication follows a strict request-response cycle: the client opens the exchange by asking for a resource, and the server sends back a matching answer. That cycle is the web's delivery system. It is also the baseline for how modern applications retrieve HTML documents, images, and JSON payloads across different networks.

Because HTTP leans on TCP/IP to carry its messages, a lower layer handles connection reliability. What usually decides your application's performance, though, is the overhead of setting those connections up. You have to manage these sessions to optimize throughput and minimize latency, especially under the constraints of high-scale systems.

How a request travels from your browser to the server

Before any application data moves, you have to open a connection with the TCP three-way handshake, which synchronizes client and server. The client picks a random sequence number x and sends a SYN packet. The server picks its own random number y and answers with a SYN-ACK packet carrying y and x+1. The client replies with an ACK packet carrying y+1, and the connection is live.

TCP three-way handshake: the client sends SYN, the server replies SYN-ACK, the client sends ACK

The server cannot fulfill the request until that final ACK arrives. The connection is also subject to slow start, a congestion-control strategy where the server limits how many packets it sends at first, until it confirms the network path can handle more. For small resources, the handshake overhead can cost more time than sending the data itself.

Once the connection is live, your browser sends the HTTP message. The server reads it, looks up the requested resource, and generates the metadata and payload. That processing time stacks on top of network latency, so server-side efficiency drives the total round-trip time.

The response then travels back over the established TCP path. In the original protocol specification, the connection closed after a single resource was delivered. Modern implementations use persistent connections to keep the pipe open, skipping the repeated SYN/ACK sequence for the rest of the resources the page needs.

What is inside an HTTP request?

An HTTP request has five main parts: the method, the URL, the version, the headers, and the body. The method states the intent, the URL identifies the target, and the version (HTTP/1.1, say) tells the server which protocol features are available. Headers carry the metadata needed for processing; the body carries the data payload, for the request types that have one.

The parts of an HTTP request — method, URL, version, headers and body — alongside the segments of a URL

Take the URL https://learning.postman.com/docs/introduction/overview/#getting-started. The scheme is https, the domain is learning.postman.com, the path to the resource is /docs/introduction/overview, and the anchor is #getting-started. Each segment routes the request — to the right server, then to the right logic path.

Headers are key-value pairs that give the server context. User-Agent identifies the client's browser or tool; Accept lists the media types the client can handle. Host is mandatory in HTTP/1.1 — it names the specific domain the client wants on a server that might host many sites.

The body of a request carries the information being sent to the server, such as a JSON-formatted payload in a POST request. GET and DELETE requests usually leave it out and pass parameters in the query string instead. A raw GET request for a standard index page looks like this:

http
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
Connection: keep-alive

What the HTTP methods actually mean

The verbs in an HTTP request tell the server what the client wants done. GET is the most common, used strictly to retrieve a resource without changing server state. POST submits data for processing, which often creates a new resource. GET requests are designed to be bookmarkable and cached; POST requests are not, because they change server data.

PUT updates an existing resource, or creates it if nothing lives at that URL yet. Unlike POST, PUT is idempotent: send the same PUT again and again and you get the same result, with no duplicate resources. DELETE removes a specified resource. HEAD is what you use when you only need the status or size of a resource, not the payload itself.

Idempotency matters for system reliability. A method is idempotent when the side effects of making the request many times are identical to making it once. GET, HEAD, PUT, and DELETE are designed to be idempotent. POST is not — repeat a POST and you can end up with several records created in a database.

You must include a request body with POST or PUT when you send data: JSON user details, or multi-part form data for a file upload. GET and DELETE leave the body out. In those cases any parameters ride along as query strings in the URL itself, which keeps retrieval and removal stateless as intended.

Responses and the status code families

The HTTP response is the server's answer: a status line, headers, and an optional message body. The status line carries the protocol version and a 3-digit status code. Response headers describe the payload — Content-Length, Server type. The body holds the actual data, which the browser renders based on those headers.

The five HTTP status code families: 1xx informational, 2xx success, 3xx redirection, 4xx client error, 5xx server error

Status codes come in five families, which is what makes an outcome easy to diagnose. 1xx is informational: the request arrived and the process is continuing. 2xx means success — 200 OK for a standard fetch, 201 Created after a POST generates a new resource. 3xx is redirection: the resource has moved.

Error codes split into client-side and server-side. 4xx, such as 404 Not Found, is a client error: bad syntax, or a URL that does not exist. 5xx, like 500 Internal Server Error, means the server failed on a valid request. That split tells you whether you are chasing a bad endpoint or a crashing backend service.

The browser leans on the Content-Type header to interpret the response body. text/html gets rendered as a webpage; application/json gets parsed as data by the client application. Get that header wrong and the client may render the payload incorrectly, or download the file instead of showing it.

How HTTP evolved from 0.9 to HTTP/2

HTTP/0.9, released in 1991, was the one-liner. It supported GET and nothing else, and had no headers at all. The server sent the HTML and closed the connection immediately. Responses were textual HTML only — no way for the client to attach metadata, no way for the server to return a status code.

Timeline of HTTP's evolution from version 0.9 in 1991 to HTTP/2 in 2015

HTTP/1.0 followed in 1996 with headers, status codes, and support for non-HTML content types. Its main flaw was that it was connectionless: every resource on a page needed a new TCP connection. A page with 20 resources meant 20 separate three-way handshakes, and slow start plus handshake overhead turned that into a heavy performance penalty.

HTTP/1.1 arrived in 1999 to attack those latency problems with persistent connections (Keep-Alive) and pipelining, which let multiple sequential requests share one connection. It also added chunked transfer encoding, so a server can send a dynamic response in pieces before it knows the total Content-Length — the basis for streaming data.

HTTP/2 was a major overhaul in 2015: the protocol went from text to a binary framing layer. It introduced frame types including HEADERS, DATA, RST_STREAM, SETTINGS, and PRIORITY. Multiplexing let asynchronous requests share one TCP connection. Client-initiated streams use odd stream IDs, while server responses and pushes use even ones. HPACK compression came in to squeeze redundant header metadata.

What HTTP/3 and QUIC change

HTTP/3 is a sharper break: it moves off TCP onto UDP through the QUIC protocol. Reliability no longer comes from the standard TCP stack — QUIC handles packet loss and recovery itself. That removes head-of-line blocking, where one lost packet stalls every data stream. In HTTP/3, a packet lost for one file does not hold up the other streams on the same connection.

HTTP/2 over TCP compared with HTTP/3 over QUIC, where one lost packet stalls only its own stream

Connection identifiers are another significant QUIC feature. A traditional TCP connection is tied to an IP address, so switching from Wi-Fi to cellular data drops it and forces a renegotiation. QUIC ties the session to a unique ID instead, so the stream survives while your device's IP address changes during a physical move.

QUIC also pushes security deeper into the stack: encryption is always on, and TLS 1.3 is folded into the transport handshake. Combining the transport and cryptographic handshakes cuts the round trips needed to set up a secure connection. Security becomes a mandatory part of the transport layer instead of an optional add-on.

QUIC runs in user space (application space) rather than the operating system kernel, so congestion-control work can move faster. Protocol updates ship with application updates, without waiting for an OS-level patch. That leaves more room to tune high-scale web applications running over lossy or congested mobile networks.

HTTP in practice: the foundation of APIs, and its security downside

HTTP is the main transport for modern API architectures. REST uses the standard HTTP verbs to manage resources; GraphQL queries complex data schemas through a single HTTP endpoint; SOAP moves XML-based messages. The data structures differ, but all three ride on the same HTTP request-response mechanics.

The big downside of raw HTTP is that it sends data in plaintext, which leaves it open to man-in-the-middle (MITM) attacks. An attacker can intercept sensitive data like passwords or session cookies. The fix is TLS (Transport Layer Security), wrapped around the protocol to create the HTTPS standard, which gives you data integrity and confidentiality.

You also have to account for application-layer, or Layer 7, DDoS attacks. These flood a server with syntactically valid HTTP requests until its processing power runs out. Because the requests look legitimate, they often slip past lower-level network filters. Persistent connections are efficient, but an attacker can hold them open as attack vectors at the application layer.

In production, you use tools to capture and inspect this traffic, confirming connections are working, secure, and optimized. Monitoring headers and status codes is the only way to debug failures in a distributed system effectively. As an engineer, you are responsible for managing these connections against the specific constraints of your network architecture.

How much HTTP is enough?

You do not need to memorize every RFC. You do need to understand connection management and binary framing to build high-scale applications. The web just works for the average user; an engineer's job is to manage the complexity underneath — TCP handshakes, multiplexing, protocol versions.

Optimizing for latency and throughput takes a grounded sense of how headers, status codes, and transport layers interact. HTTP is the foundational abstraction layer. Ignore how framing and session management work underneath, and you will hit performance bottlenecks that no amount of extra hardware or bandwidth will solve.

References

Share this article