How HTTP works under the hood?

Published on: Updated on: Category: Guides

Every time you browse a website (including the very post you’re reading), you’re using HTTP under the hood. HTTP is an underlying protocol used by websites that allows sending and receiving webpages and more. It’s also the foundation of the modern Web.

Understanding how HTTP works under the hood is useful, because it helps you at troubleshooting, optimizing, and securing websites. In this post, you’ll explore the basics of HTTP, including its request-response model and how it works under the hood.

The basics

HTTP (HyperText Transfer Protocol) is an underlying protocol used by websites. It allows browsers to send requests and receive responses from servers, transferring files and other data.

HTTP uses a request-response model, which means the web client (often a web browser) sends a request and receives a response from a web server afterwards.

HTTP is also stateless, which means that with the HTTP protocol itself, the server doesn’t retain state from previous requests. In practice, each request is independent, meaning no request carries information about what happened before. To maintain state (like a logged-in session), applications must use additional mechanisms such as cookies or tokens.

The HTTP protocol had some significant changes since it was first introduced:

  • HTTP/0.9, introduced in 1991, allowed for simple file transfers and basic web browsing, but it didn’t support uploads.
  • HTTP/1.0, introduced in 1996, introduced the concept of HTTP requests and responses, basic error handling, and allowed uploads.
  • HTTP/1.1, introduced in 1997, improved by HTTP/1.0 by introducing presistent connections, which allows multiple requests to be sent over a single connection; this improves the website performance, because it might take some time to open a connection.
  • HTTP/2, introduced in 2015, introduced multiplexing, which allows many requests to be sent over a single connection simultaneously; this improves the website performance even more.
  • HTTP/3, introduced in 2022, uses QUIC (a transport layer protocol built on top of UDP) instead of TCP; this can improve the website performance even more than the previous HTTP version. This can be thought to be similar to HTTP/2, but with QUIC instead of TCP.

What happens when you enter a URL in the browser?

When you enter a URL in the browser, first the web browser needs to know what server to connect to. The domain name (for example ferron.sh) is extracted from the URL (for example https://ferron.sh/), and it then gets translated to an IP address (for example 145.239.87.234) through DNS. An IP address identifies a server the web browser will connect to.

Next, the web browser establishes a TCP (or QUIC, if using HTTP/3) connection with the server. After establishing the connection, if the URL is an HTTPS one, it performs a TLS handshake to set up data encryption between the web browser and the web server.

After the connection is established, the web browser sends an HTTP request containing data, such as the resource path (like /), the HTTP method (often GET) and headers.

After the server receives the request, it responds with an HTTP response containing a status code (such as 200 for success), response headers, and a response body (the data used to render the webpage).

After receiving the response, the web browser renders the webpage from the received data. The web browser can also ask the web server for additional resources (such as images, stylesheets, scripts), making additional requests.

Inside the HTTP request

Inside the HTTP request, there are several elements, such as the HTTP method, headers, and the request body.

Here’s an example HTTP request (for HTTP/1.x):

GET / HTTP/1.1
Host: example.com

The lines in the HTTP/1.x requests end with two control characters - carriage return (CR) and line feed (LF).

The request specifies the HTTP method (such as GET), request path (such as /), and HTTP version (such as HTTP/1.1). The method indicates the desired action, and the path identifies the resource.

Requests also include headers like Host (the server’s hostname, typically a domain name) and User-Agent (identifying the client software used to make the request).

Optionally, for POST and PUT methods, there is also a body containing data to be sent to the server.

Inside the HTTP response

Inside the HTTP response, there are several elements too (like HTTP request), such as the HTTP status code, headers, and the response body.

Here’s an example HTTP response (for HTTP/1.x):

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 12

Hello World!

Lines in HTTP/1.x responses terminate with a carriage return (CR) and line feed (LF) sequence.

The response specifies the HTTP version (such as HTTP/1.1), status code (such as 200), and status phrase (for example “OK”). The status code indicates the result of the request.

The list of some HTTP response status codes is as follows:

  • 200 OK - the request succeeded
  • 201 Created - the request succeeded, and a new resource was created
  • 301 Moved Permanently - the resource was moved permanently to another location
  • 302 Found - the resource was moved temporarily to another location
  • 400 Bad Request - the request is invalid
  • 401 Not Authorized - authorization is required to access the resource
  • 403 Forbidden - the access to the resource is denied
  • 404 Not Found - the resource wasn’t found
  • 405 Method Not Allowed - the server doesn’t allow the method used to access the resource
  • 429 Too Many Requests - there were too many requests send to the server
  • 500 Internal Server Error - the server has encountered an unexpected error
  • 502 Bad Gateway - the server received an invalid response when acting as a proxy
  • 503 Service Unavailable - the service provided by the server isn’t available

Responses also include headers like Content-Type (specifying the body format, such as text/plain) and Content-Length (the body size in bytes).

For many HTTP responses, there is also a body containing data received by the client.

HTTP headers: more than metadata

HTTP headers aren’t just metadata, they also specify caching, content negotiation, authentication, and compression.

Common request headers include:

  • Accept, which specifies the format of the response data (like text/plain for plaintext)
  • Authorization, which provides credentials for authentication (like Bearer <token>)
  • Content-Type, which specifies the format of the request body (like application/json for JSON data)
  • Host, which specifies the server hostname (often a domain name)
  • User-Agent, which identifies what client made the request (like curl/8.5.0)

Common response headers include:

  • Content-Length, which specifies the response body size in bytes
  • Content-Type, which specifies the format for the response body (like text/html for HTML data)
  • Location, which specifies the URL to redirect to
  • Set-Cookie, which specifies a cookie to be set on client’s browser
  • Server, which is used to identify used server software (for example, Ferron or nginx)

Connection management

In HTTP/1.1, TCP connections can be reused (called “keep-alive”). This is enabled by sending a Connection: keep-alive header with requests. Reusing connections improves performance, as establishing a new TCP connection takes time.

In HTTP/2, requests are multiplexed, that means that many requests can be sent to the server at once. This can improve the website performance even more.

In HTTP/3, the QUIC transport-layer protocol (which uses UDP under the hood) is used instead of TCP. This can improve the website performance even more, as in TCP a single lost packet can delay all subsequent packets (this can be also called “head-of-line blocking”).

Cookies and sessions

Cookies are set by sending Set-Cookie headers from a web server. A Set-Cookie header contains a cookie name, a cookie value, and cookie flags.

A Set-Cookie header can look like this: Set-Cookie: session_id=1234567890abcdef; Expires=Wed, 21 Oct 2025 07:28:00 GMT; Domain=example.com; Path=/. This example specifies a session_id cookie set to 1234567890abcdef, with a specified expiry time, for the example.com domain and its subdomains and for paths containing / at the beginning.

The web browser will then receive and store the cookie in its storage.

When making a request, the browser retrieves cookies from its storage and sends them via the Cookie header, such as Cookie: session_id=1234567890abcdef.

Cookies maintain state, such as authentication or tracking.

Cookies introduce security considerations. The SameSite flag restricts cross-domain sending. The HttpOnly attribute prevents client-side script access, and the Secure attribute ensures cookies are only sent over HTTPS.

HTTPS and TLS

HTTPS extends HTTP with encryption via TLS (Transport Layer Security). The handshake proceeds in these steps:

  1. The client sends a “Client Hello” with the TLS version, a random number, and a list of supported cipher suites.
  2. The server responds with a “Server Hello” containing the TLS version, a random number, and a chosen cipher suite.
  3. The server then sends a digital certificate containing its public key and identity information.
  4. The client verifies the certificate’s validity, checks that it was issued by a trusted CA, and confirms it matches the expected identity.
  5. After verification, the client and server perform a key exchange using the chosen cipher suite, such as Diffie-Hellman (DH) or Elliptic Curve Diffie-Hellman (ECDH).
  6. Next, both sides send a “change cipher spec” message, indicating they’re switching to the newly established keys.
  7. Finally, both sides send a confirmation that the handshake is complete.

TLS encryption ensures data integrity and protects against eavesdropping. TLS certificates are also critical for chain of trust; reputable CAs shouldn’t issue certificates for domains they don’t own.

Inspecting HTTP

There are many ways to inspect data to learn how HTTP protocol works, such as using web browser’s developer tools, or using curl to make HTTP requests.

To make a basic HTTP request with protocol information shown using curl, you can run this command:

# Replace "https://example.com" with the desired URL.
curl -v https://example.com

The -v flag indicates verbose output (that includes HTTP protocol data).

The example output (for curl -v http://ferron.sh command), can look like this:

* Host ferron.sh:80 was resolved.
* IPv6: 2001:41d0:601:1100::2df
* IPv4: 145.239.87.234
*   Trying 145.239.87.234:80...
* Established connection to ferron.sh (145.239.87.234 port 80) from 192.168.1.68 port 58936
* using HTTP/1.x
> GET / HTTP/1.1
> Host: ferron.sh
> User-Agent: curl/8.22.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 308 Permanent Redirect
< location: https://ferron.sh/
< strict-transport-security: max-age=31536000; includeSubDomains; preload
< x-frame-options: deny
< x-content-type-options: nosniff
< content-security-policy: default-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https://analytics.internal.ferron.sh https://replay.internal.ferron.sh https://platform.twitter.com; connect-src 'self' https://analytics.internal.ferron.sh https://replay.internal.ferron.sh; frame-src 'self' https://platform.twitter.com https://www.youtube.com https://status.ferron.sh
< server: Ferron
< date: Fri, 18 Sep 2026 19:22:12 GMT
< content-length: 0
<
* Connection #0 to host ferron.sh:80 left intact

In this example, the domain resolves, the client connects to the server, sends a request, and receives a 308 response indicating a permanent redirect to https://ferron.sh/ via the Location header.

Conclusion

Understanding how HTTP works under the hood helps you debug connectivity issues, optimize performance through connection reuse and protocol choices, and improve security with HTTPS, headers, and cookies.

Though web technologies evolve (newer versions like HTTP/3 and underlying protocols like QUIC), understanding HTTP fundamentals still matters for developers, network engineers, and anyone interested in how the internet works.

Update (August 5, 2026): updated ferronweb.org domain to ferron.sh one

Update (September 18, 2026): improved readability of the post and updated examples