Network & delivery
8 min readUpdatedWhat is HTTP? The Hypertext Transfer Protocol explained
Quick answer
The Hypertext Transfer Protocol (HTTP) is the request-response protocol that browsers, apps and APIs use to fetch web pages and data. A client sends a method such as GET, a target and headers; the server replies with a three-digit status code, headers and usually a body. HTTP is stateless, so every request stands on its own. The same meaning travels in three formats: HTTP/1.1 and HTTP/2 over TCP, and HTTP/3 over QUIC.
01What is HTTP?
HTTP is the language of the web's client-server conversation. RFC 9110, its current definition, calls it "a stateless application-level protocol for distributed, collaborative, hypertext information systems": a client asks for a resource by name, a server answers, and each exchange is complete in itself.
It sits at the application layer, layer 7 of the OSI model. HTTP/1.1 and HTTP/2 run over TCP; HTTP/3 runs over QUIC, which runs over UDP, as the TCP vs UDP guide explains. HTTPS is the same protocol inside a TLS connection, covered in the SSL/TLS guide. Unless a URL names another port, http:// means TCP port 80 and https:// TCP port 443.
Statelessness means the server needs nothing from earlier requests to understand the current one. Logins and baskets still work because the client sends state back with every request, usually as a cookie the server set earlier.
02What does an HTTP request and response look like?
The quickest way to see HTTP is curl -v, which prints what it sends after > and what it receives after <. The transcript below is HTTP/1.1, where messages are plain text lines, from a small test server.
- Request line: the method (GET), the target (/) and the version (HTTP/1.1).
- Request headers: Host names the site, so one server can host many, and RFC 9112 makes it mandatory in HTTP/1.1. User-Agent and Accept describe the client.
- A blank line ends the headers. A GET normally carries no body; a POST would send one here.
- Status line: the version, the status code 200 and the reason phrase OK.
- Response headers describe the body: type, length, last change, and an ETag the client can send back to ask whether it changed.
- Then the body itself, here 74 bytes of HTML.
$ curl -v --http1.1 https://example.test/
* ALPN: offers http/1.1
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted http/1.1
> GET / HTTP/1.1
> Host: example.test
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.22.1
< Date: Sat, 24 Oct 2026 12:14:52 GMT
< Content-Type: text/html
< Content-Length: 74
< Last-Modified: Sat, 24 Oct 2026 12:11:23 GMT
< Connection: keep-alive
< ETag: "6adca06b-4a"
< Accept-Ranges: bytes
<
<!doctype html>
<title>Test page</title>
<p>Hello from a test server.</p>03What are the HTTP methods?
The method says what the client wants done. RFC 9110 defines eight and requires every general-purpose server to support GET and HEAD. PATCH comes from RFC 5789, and QUERY, published as RFC 10008 in June 2026, adds a safe way to send a query in a request body. Three properties decide how a method may be treated.
- Safe: the client asks for no change on the server, so crawlers and prefetchers may send it freely.
- Idempotent: sending it twice has the same intended effect as sending it once, so a client may retry it automatically after a dropped connection.
- Cacheable: a cache may store the response and reuse it.
| Method | Typical use | Safe | Idempotent | Cacheable |
|---|---|---|---|---|
| GET | Fetch a page, file or API resource | Yes | Yes | Yes |
| HEAD | Like GET, but headers only | Yes | Yes | Yes |
| POST | Submit a form, create a resource, run an action | No | No | Only with explicit freshness and a matching Content-Location |
| PUT | Replace a resource with the request body | No | Yes | No |
| DELETE | Remove a resource | No | Yes | No |
| PATCH | Change part of a resource | No | No | Only with explicit freshness and a matching Content-Location |
| OPTIONS | Ask which methods and features are allowed, as in a CORS preflight | Yes | Yes | No |
| QUERY | Run a query sent in the request body | Yes | Yes | Yes |
| TRACE | Loop-back test of the request path | Yes | Yes | No |
| CONNECT | Open a tunnel through a proxy | No | No | No |
04What do HTTP status codes mean?
Every response carries a three-digit status code, and the first digit is its class. RFC 9110 requires clients to understand the class even when they do not know the code, treating an unknown code as the x00 code of its class: an unknown 471 is handled like a 400.
| Class | Meaning in RFC 9110 | Common examples | Guide |
|---|---|---|---|
| 1xx Informational | The request was received, processing continues | 100 Continue, 103 Early Hints | Rarely visible to users |
| 2xx Successful | Received, understood and accepted | 200 OK, 201 Created, 204 No Content | HTTP status codes explained |
| 3xx Redirection | Further action is needed to complete the request | 301, 302, 304, 307, 308 | Redirect loops |
| 4xx Client error | The request has bad syntax or cannot be fulfilled | 400, 401, 403, 404, 429 | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 429 Too Many Requests |
| 5xx Server error | The server failed to fulfil an apparently valid request | 500, 502, 503, 504 | 502 Bad Gateway, 504 Gateway Timeout |
05Which HTTP headers matter most?
Headers carry everything except the content: who is asking, what they accept, how long a response may be cached and what state to send back. Header names are case-insensitive, and HTTP/2 and HTTP/3 send them in lower case. A separate group of response headers tells the browser how to protect a page; the security headers guide lists them.
| Header | Sent by | What it does |
|---|---|---|
| Host | Client | Names the site, so one address can serve many sites |
| User-Agent | Client | Identifies the software making the request |
| Accept, Accept-Encoding | Client | Formats and compressions the client can handle |
| Cookie, Set-Cookie | Client, server | Carries state between stateless requests (RFC 6265) |
| Authorization | Client | Credentials, such as a bearer token |
| Content-Type, Content-Length | Both | The type and size of the body |
| Cache-Control, ETag, Last-Modified | Server | How long a response may be cached and how to revalidate it (RFC 9111) |
| Location | Server | Where a redirect points |
| Alt-Svc | Server | Advertises the same site over another protocol, such as HTTP/3 |
| X-Forwarded-For, X-Forwarded-Proto | Proxy | The visitor's address and scheme, added by a reverse proxy |
06How do HTTP/1.1, HTTP/2 and HTTP/3 differ?
All three versions carry the same methods, status codes and headers, defined once in RFC 9110. What differs is the wire format and the transport, which changes performance and failure modes, not meaning.
The HTTP/2 transcript of the same request shows it: curl negotiates h2 in the TLS handshake, sends pseudo-headers such as :method and :path, and prints header names in lower case. The status line has no reason phrase, because HTTP/2 has no field for one.
There is no HTTP/3 transcript: the curl 7.88.1 package in Debian 12 is built without HTTP/3. Sites that offer it advertise it in a header such as alt-svc: h3=":443"; ma=86400, which example.com sent on 24 October 2026, and a client that supports HTTP/3 may then try QUIC for later requests.
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Specification | RFC 9112 (2022); first RFC 2068 (1997) | RFC 9113 (2022); first RFC 7540 (2015) | RFC 9114 (2022) |
| Transport | TCP | TCP | QUIC over UDP |
| Message format | Text lines | Binary frames | Binary frames on QUIC streams |
| Parallel requests | One response at a time per connection, so clients open several | Many streams on one connection | Many streams on one connection |
| Head-of-line blocking | A slow response holds up the ones behind it | A lost TCP packet stalls every stream | A lost packet stalls only its own stream |
| Header compression | None | HPACK (RFC 7541) | QPACK (RFC 9204) |
| Encryption | Optional: http or https | In practice TLS; the cleartext h2c upgrade is deprecated | Always: TLS 1.3 is built into QUIC |
| How a client picks it | The default | Negotiated in the TLS handshake (ALPN h2) | Advertised by Alt-Svc or a DNS HTTPS record |
$ curl -v --http2 https://example.test/
* ALPN: offers h2,http/1.1
* ALPN: server accepted h2
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: example.test]
> GET / HTTP/2
< HTTP/2 200
< server: nginx/1.22.1
< content-type: text/html
< content-length: 74
< etag: "6adca06b-4a"07What happens to an HTTP request behind a reverse proxy?
On most production sites the browser never talks to the application server directly. A reverse proxy, load balancer or CDN edge accepts the connection, terminates TLS and opens a second, separate connection to the origin, which can use a different HTTP version and scheme.
The test below sends an HTTP/2 request over TLS to a proxy whose origin echoes what it received. The origin got HTTP/1.1 over plain HTTP, saw the proxy as the connecting address, and learnt the visitor's address and scheme only from headers the proxy added. RFC 7239 standardised this as the Forwarded header; many proxies still send the older X-Forwarded names.
# visitor to proxy: HTTP/2 over TLS
> GET /hello HTTP/2
> Host: example.test
< HTTP/2 200
# proxy to origin, as echoed back by the origin
protocol: HTTP/1.1
host: example.test
x-forwarded-for: 127.0.0.1
x-forwarded-proto: https08A short history of HTTP, with dates
HTTP has changed its wire format three times but kept its core model, a method, a target, headers and a status code, since the mid-1990s.
| Date | Version or document | What changed |
|---|---|---|
| 1991 | HTTP/0.9, the original HTTP documented by the W3C | One-line GET requests, HTML responses, no headers or status codes |
| May 1996 | HTTP/1.0, RFC 1945 | Headers, status codes, HEAD and POST |
| January 1997 | HTTP/1.1, RFC 2068 | Required Host header, persistent connections, chunked transfer |
| June 1999 | RFC 2616 | The HTTP/1.1 revision used for 15 years |
| June 2014 | RFC 7230 to 7235 | HTTP/1.1 rewritten as six documents |
| May 2015 | HTTP/2, RFC 7540 | Binary framing, multiplexing, HPACK |
| May 2021 | QUIC, RFC 9000 | The UDP-based transport under HTTP/3 |
| June 2022 | RFC 9110 to 9114 | Semantics separated from wire formats; HTTP/3 standardised |
| June 2026 | QUERY method, RFC 10008 | A safe, idempotent request with a body |
Questions
Frequently asked questions
Sources
Sources and verification
Transcripts captured with curl 7.88.1 (nghttp2 1.52.0) against a local nginx 1.22.1 test server and test reverse proxy on Debian 12, October 2026; the Alt-Svc header was observed on example.com on 24 October 2026.
- 01RFC 9110: HTTP Semantics · RFC Editor
- 02RFC 9111: HTTP Caching · RFC Editor
- 03RFC 9112: HTTP/1.1 · RFC Editor
- 04RFC 9113: HTTP/2 · RFC Editor
- 05RFC 9114: HTTP/3 · RFC Editor
- 06RFC 9000: QUIC · RFC Editor
- 07RFC 10008: The HTTP QUERY Method · RFC Editor
- 08RFC 5789: PATCH Method for HTTP · RFC Editor
- 09RFC 1945: HTTP/1.0 · RFC Editor
- 10RFC 2068: HTTP/1.1 (January 1997) · RFC Editor
- 11RFC 7540: HTTP/2 (May 2015) · RFC Editor
- 12RFC 7838: HTTP Alternative Services · RFC Editor
- 13RFC 7239: Forwarded HTTP Extension · RFC Editor
- 14The Original HTTP as defined in 1991 · W3C
- 15Hypertext Transfer Protocol (HTTP) Method Registry · IANA
Last updated