Network & delivery

8 min readUpdated

What 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 over HTTP/1.1 against a local nginx 1.22.1 test server (abridged: routing options, connection and TLS handshake lines removed)
$ 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.
MethodTypical useSafeIdempotentCacheable
GETFetch a page, file or API resourceYesYesYes
HEADLike GET, but headers onlyYesYesYes
POSTSubmit a form, create a resource, run an actionNoNoOnly with explicit freshness and a matching Content-Location
PUTReplace a resource with the request bodyNoYesNo
DELETERemove a resourceNoYesNo
PATCHChange part of a resourceNoNoOnly with explicit freshness and a matching Content-Location
OPTIONSAsk which methods and features are allowed, as in a CORS preflightYesYesNo
QUERYRun a query sent in the request bodyYesYesYes
TRACELoop-back test of the request pathYesYesNo
CONNECTOpen a tunnel through a proxyNoNoNo

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.

ClassMeaning in RFC 9110Common examplesGuide
1xx InformationalThe request was received, processing continues100 Continue, 103 Early HintsRarely visible to users
2xx SuccessfulReceived, understood and accepted200 OK, 201 Created, 204 No ContentHTTP status codes explained
3xx RedirectionFurther action is needed to complete the request301, 302, 304, 307, 308Redirect loops
4xx Client errorThe request has bad syntax or cannot be fulfilled400, 401, 403, 404, 429400 Bad Request, 401 Unauthorized, 403 Forbidden, 429 Too Many Requests
5xx Server errorThe server failed to fulfil an apparently valid request500, 502, 503, 504502 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.

HeaderSent byWhat it does
HostClientNames the site, so one address can serve many sites
User-AgentClientIdentifies the software making the request
Accept, Accept-EncodingClientFormats and compressions the client can handle
Cookie, Set-CookieClient, serverCarries state between stateless requests (RFC 6265)
AuthorizationClientCredentials, such as a bearer token
Content-Type, Content-LengthBothThe type and size of the body
Cache-Control, ETag, Last-ModifiedServerHow long a response may be cached and how to revalidate it (RFC 9111)
LocationServerWhere a redirect points
Alt-SvcServerAdvertises the same site over another protocol, such as HTTP/3
X-Forwarded-For, X-Forwarded-ProtoProxyThe 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.1HTTP/2HTTP/3
SpecificationRFC 9112 (2022); first RFC 2068 (1997)RFC 9113 (2022); first RFC 7540 (2015)RFC 9114 (2022)
TransportTCPTCPQUIC over UDP
Message formatText linesBinary framesBinary frames on QUIC streams
Parallel requestsOne response at a time per connection, so clients open severalMany streams on one connectionMany streams on one connection
Head-of-line blockingA slow response holds up the ones behind itA lost TCP packet stalls every streamA lost packet stalls only its own stream
Header compressionNoneHPACK (RFC 7541)QPACK (RFC 9204)
EncryptionOptional: http or httpsIn practice TLS; the cleartext h2c upgrade is deprecatedAlways: TLS 1.3 is built into QUIC
How a client picks itThe defaultNegotiated in the TLS handshake (ALPN h2)Advertised by Alt-Svc or a DNS HTTPS record
The same request over HTTP/2 (curl 7.88.1 with nghttp2 1.52.0, local nginx 1.22.1 test server, abridged)
$ 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.

One request, two connections: what the visitor sent and what the origin received (local nginx 1.22.1 proxy and echo origin, abridged)
# 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: https

08A 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.

DateVersion or documentWhat changed
1991HTTP/0.9, the original HTTP documented by the W3COne-line GET requests, HTML responses, no headers or status codes
May 1996HTTP/1.0, RFC 1945Headers, status codes, HEAD and POST
January 1997HTTP/1.1, RFC 2068Required Host header, persistent connections, chunked transfer
June 1999RFC 2616The HTTP/1.1 revision used for 15 years
June 2014RFC 7230 to 7235HTTP/1.1 rewritten as six documents
May 2015HTTP/2, RFC 7540Binary framing, multiplexing, HPACK
May 2021QUIC, RFC 9000The UDP-based transport under HTTP/3
June 2022RFC 9110 to 9114Semantics separated from wire formats; HTTP/3 standardised
June 2026QUERY method, RFC 10008A safe, idempotent request with a body

Questions

Frequently asked questions

HTTPS is HTTP sent inside an encrypted TLS connection. Requests, headers and status codes are identical; TLS adds encryption, integrity protection and a certificate that proves which server you reached. Plain HTTP uses TCP port 80 by default and can be read or altered by anyone on the path, while HTTPS uses port 443. HTTP/3 has no unencrypted form.

Because the protocol does not require the server to remember anything between requests: each request carries everything needed to understand it. Applications add state on top, most often with cookies the server sets and the browser sends back, or with tokens in the Authorization header. Statelessness makes it easy to spread requests across several servers and caches.

GET asks for a resource and should not change anything on the server, so it is safe, idempotent and cacheable, and its parameters travel in the URL. POST sends data in the body for the server to process, such as a form or an order, and is neither safe nor idempotent, which is why browsers warn before resending one.

A method is idempotent when sending the same request several times has the same intended effect as sending it once. GET, HEAD, PUT, DELETE, OPTIONS, TRACE and QUERY are idempotent; POST and PATCH are not. It matters when a connection drops: a client may retry an idempotent request automatically, while repeating a POST could place an order twice.

Yes. Every HTTP request asks the server to do some work, so huge numbers of valid-looking requests can exhaust an application's workers, database or bandwidth; this is called an HTTP flood. Malformed requests also target bugs in parsers and protocol features, as HTTP/2 Rapid Reset did. A reverse proxy with a WAF filters such traffic before it reaches the origin.

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.

  1. 01RFC 9110: HTTP Semantics · RFC Editor
  2. 02RFC 9111: HTTP Caching · RFC Editor
  3. 03RFC 9112: HTTP/1.1 · RFC Editor
  4. 04RFC 9113: HTTP/2 · RFC Editor
  5. 05RFC 9114: HTTP/3 · RFC Editor
  6. 06RFC 9000: QUIC · RFC Editor
  7. 07RFC 10008: The HTTP QUERY Method · RFC Editor
  8. 08RFC 5789: PATCH Method for HTTP · RFC Editor
  9. 09RFC 1945: HTTP/1.0 · RFC Editor
  10. 10RFC 2068: HTTP/1.1 (January 1997) · RFC Editor
  11. 11RFC 7540: HTTP/2 (May 2015) · RFC Editor
  12. 12RFC 7838: HTTP Alternative Services · RFC Editor
  13. 13RFC 7239: Forwarded HTTP Extension · RFC Editor
  14. 14The Original HTTP as defined in 1991 · W3C
  15. 15Hypertext Transfer Protocol (HTTP) Method Registry · IANA

Last updated