HTTP/1: The Birth of the Web (0.9 → 1.0 → 1.1)
A technical deep dive into how the web started, why TCP wasn’t enough, and how HTTP/1 shaped everything we use today.
HTTP/1: The Birth of the Web (0.9 → 1.0 → 1.1)
A technical deep dive into how the web started, why TCP wasn’t enough, and how HTTP/1 shaped everything we use today.
The World Before HTTP: A Web Without a Web
Late 1980s. The Internet existed, but it wasn’t the web.
It was a fragmented patchwork of specialized protocols:
- FTP for file transfers
- Gopher for navigating menu systems
- Telnet for remote terminal access
- SMTP for email
Each system required its own custom client software, manual commands, and offered zero interoperability. There was no universal way to share documents across different machines and networks.
Tim Berners-Lee had a deceptively simple idea:
“What if documents could link to other documents, regardless of machine or location?”
Hypertext.
But hypertext needed three fundamental components:
- A universal address → URL
- A universal document format → HTML
- A universal protocol → HTTP
TCP already existed at the transport layer, so why couldn’t we just use that?
Why TCP Alone Wasn’t Enough
TCP provides essential transport capabilities:
- Reliable delivery
- Ordered delivery
- Congestion control
- Flow control
But TCP does not provide:
- Resource identification
- Document type specification
- Status reporting
- Caching mechanisms
- Content negotiation
- Host identification
Think of it this way: TCP is the road. HTTP is the truck carrying structured cargo with a delivery manifest.
TCP moves bytes reliably from point A to point B. HTTP gives those bytes meaning, context, and structure. You can’t build a web with transport alone — you need application-layer semantics.
HTTP/0.9: The 1991 Prototype
HTTP’s first version was shockingly minimal.
Request:
GET /index.html
Response:
<html>…raw HTML…</html>
That’s it. No headers. No status codes. No MIME types. No caching. No cookies. No images.
The protocol supported exactly one resource per connection, and only HTML documents. After sending the document, the server immediately closed the TCP connection.
For 1991, this worked fine. Webpages were pure text — no CSS, no JavaScript, typically just one file. But the moment developers wanted to embed images, HTTP/0.9 collapsed under its own simplicity.
HTTP/1.0: The First Real Web Protocol (1996)
As pages evolved beyond pure text, browsers needed to fetch multiple resources: images, stylesheets, JavaScript files. Developers needed metadata, error handling, and caching.
HTTP/1.0 emerged to meet these needs.
Key Additions in HTTP/1.0
✓ Request and response headers ✓ MIME types via Content-Type ✓ User-Agent for browser identification ✓ Caching headers (Expires, Last-Modified) ✓ Status codes (200, 404, 500, etc.) ✓ Binary file support
This was a massive leap forward. But HTTP/1.0 had a fatal performance flaw:
The Connection Problem
One TCP connection per request.
If a webpage contained 15 images, that meant:
- 15 separate TCP connections
- 15 three-way handshakes
- 15 slow-start phases
Each TCP handshake costs ~1 RTT (round-trip time). Add TLS for HTTPS and you’re looking at 2–3 additional RTTs per connection. Multiply this by dozens of requests and latency becomes catastrophic.
HTTP/1.0 couldn’t scale to the modern web.
HTTP/1.1: The Workhorse That Defined the Web (1999)
HTTP/1.1 ran the web for nearly two decades. It introduced fundamental innovations that are still in use today.
1. Persistent Connections (Keep-Alive by Default)
Instead of closing after each response, HTTP/1.1 keeps the TCP connection open for multiple requests:
GET /index.html
GET /style.css
GET /script.js
All sent over the same TCP connection, dramatically reducing:
- Handshake overhead
- Latency
- Congestion window restarts
This single change was transformative for web performance.
2. Chunked Transfer Encoding
Servers don’t always know content length in advance — think dynamic pages, real-time streaming, or generated content.
Transfer-Encoding: chunked enabled:
- Sending data in variable-sized chunks
- No need to pre-compute Content-Length
- Support for streaming responses, long-polling, and server-sent events
This unlocked a new generation of dynamic web applications.
3. The Host Header: Virtual Hosting Revolution
Before HTTP/1.1, one IP address = one website. Hosting multiple domains required multiple IP addresses — an expensive and unscalable approach.
HTTP/1.1 made the Host header mandatory:
GET /index.html HTTP/1.1
Host: example.com
This single requirement enabled:
- Virtual hosting (thousands of domains on one IP)
- Modern cloud hosting platforms
- The entire shared hosting industry
4. Advanced Caching Model
HTTP/1.1 introduced sophisticated caching controls:
Cache-Controlwith fine-grained directivesETagfor validationIf-Modified-SinceandIf-None-Matchfor conditional requestsVaryfor content negotiation
These mechanisms became the foundation for CDNs like Akamai and modern edge computing.
5. Pipelining: The Feature That Failed
HTTP/1.1 introduced an optimization called pipelining: send multiple requests without waiting for responses.
In theory, this should have been revolutionary. In practice, it was a disaster.
The problem: Head-of-Line Blocking (HOLB)
Servers must respond to pipelined requests in the exact order received. If the first response is slow — maybe it requires a database query or file I/O — every subsequent pipelined request gets blocked, even if their responses are ready.
This made pages slower, not faster. Browsers quickly disabled pipelining entirely.
Why HTTP/1.1 Eventually Hit a Wall
To work around the pipelining failure, browsers resorted to a crude workaround: open multiple parallel TCP connections.
Chrome’s default: 6 connections per domain.
But this created new problems:
❌ Increased congestion — More connections competing for bandwidth ❌ More slow-start overhead — Each connection starts conservatively ❌ Higher packet loss — More streams = more opportunities for drops ❌ Multiplied handshake costs — 6× the TCP/TLS overhead ❌ Greater memory and CPU load — On both client and server
And the fundamental issue remained:
TCP Delivers Data Strictly in Order
If TCP packet #5 is lost, packet #100 can’t be delivered to the application even if it arrived perfectly on time. This is TCP-level head-of-line blocking, a transport-layer constraint that no application protocol can overcome.
As webpages grew to 100+ resources with high-resolution images and JavaScript-heavy applications, HTTP/1.1 couldn’t keep pace. The bottleneck wasn’t the protocol — it was the transport layer underneath.
The HTTP/1 Balance Sheet
Strengths
✓ Simple, readable, text-based format ✓ Easy to debug with basic tools ✓ Persistent connections (major performance win) ✓ Chunked encoding for dynamic content ✓ Robust caching mechanisms ✓ Universal support ✓ Works over standard TCP infrastructure
Limitations
✗ Single request stream per connection ✗ Requires multiple TCP connections for parallelism ✗ No true multiplexing capability ✗ Subject to TCP head-of-line blocking ✗ Pipelining broken in practice ✗ High handshake overhead ✗ Inefficient for mobile and lossy networks ✗ No header compression
HTTP/1.1 represents brilliant evolutionary engineering. But it hit a fundamental wall that TCP’s ordering guarantees couldn’t overcome.
Conclusion: Setting the Stage for HTTP/2
HTTP/1.1 successfully solved:
- Connection reuse
- Resource metadata and typing
- Status reporting
- Virtual hosting
- Caching infrastructure
But it couldn’t solve:
- Latency at scale
- Head-of-line blocking
- Connection inefficiency
- TCP’s strict ordering constraints
The web needed:
- True multiplexing — Multiple streams over one connection
- Header compression — Reducing overhead
- Binary framing — More efficient parsing
- Better bandwidth utilization — Smarter resource loading
These requirements led directly to HTTP/2, which we’ll explore in the next article: binary framing, stream multiplexing, HPACK compression, and the surprising ways TCP continued to be a bottleneck.
메타데이터
- post_id
- 86c42c98a1cb
- slug
- http-1-the-birth-of-the-web-0-9-1-0-1-1-86c42c98a1cb
- url
- https://blog.stackademic.com/http-1-the-birth-of-the-web-0-9-1-0-1-1-86c42c98a1cb
- canonical_url
- https://blog.stackademic.com/http-1-the-birth-of-the-web-0-9-1-0-1-1-86c42c98a1cb
- author_url
- https://medium.com/@jothiprakash888
- status
- ok
- fetched_at
- 2026-06-25 16:53:31