The Request-Response Cycle
At its core, a web server is a program that listens for incoming network connections, interprets HTTP requests, and sends back HTTP responses. Every time you visit a website, your browser initiates this cycle:
┌──────────┐ HTTP Request ┌──────────────┐
│ │ ─────────────────────────► │ │
│ Browser │ │ Web Server │
│ │ ◄───────────────────────── │ │
└──────────┘ HTTP Response └──────────────┘
│
▼
┌──────────────┐
│ File System │
│ or Backend │
└──────────────┘
The server's job is deceptively simple: receive a request, figure out what the client wants, get or generate that content, and send it back. But between "receive" and "send" lies enormous complexity that we'll explore throughout these tutorials.
Listening on Ports
A web server binds to one or more network ports—numbered endpoints that the operating system uses to route incoming connections to the correct program. By convention:
- Port 80 — Standard HTTP (unencrypted)
- Port 443 — HTTPS (encrypted with TLS)
- Port 8080 — Common alternative for development servers
When you type http://example.com in your browser, it implicitly
connects to port 80. For https://example.com, it connects to port 443.
You can specify a different port explicitly: http://localhost:3000.
Why port 80 and 443? On Unix-like systems, ports below 1024 are "privileged" and require root access to bind. This was a security measure—only trusted system services could listen on well-known ports. Modern servers often start as root to bind these ports, then drop privileges to run as a less privileged user.
The Server as Process
A web server is just a program running on a computer. It interacts with the operating system to:
- Open a socket — Request the OS to listen on a specific port
- Accept connections — Receive incoming TCP connections from clients
- Read data — Parse the HTTP request from the connection
- Access resources — Read files, query databases, call other services
- Write data — Send the HTTP response back through the connection
- Close or reuse — Either close the connection or keep it alive for more requests
┌─────────────────────────────────────────────────────────────┐
│ Operating System │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Network │ │ File │ │ Memory │ │
│ │ Stack │ │ System │ │ Management │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
└─────────┼────────────────┼────────────────────┼────────────┘
│ │ │
▼ ▼ ▼
┌────────────────────────────────────────────────┐
│ Web Server Process │
│ │
│ • Listen on port 80/443 │
│ • Parse HTTP requests │
│ • Read files from disk │
│ • Execute application code │
│ • Format HTTP responses │
└────────────────────────────────────────────────┘
Static vs. Dynamic Content
Web servers handle two fundamentally different types of content:
Static Content
Files that exist on disk and are served exactly as they are: HTML files, images, CSS stylesheets, JavaScript files, PDFs. The server's job is simple—find the file and send its contents.
GET /images/logo.png HTTP/1.1
Host: example.com
→ Server reads /var/www/example.com/images/logo.png
→ Server sends the file contents with appropriate headersDynamic Content
Content generated on-the-fly by application code. The response depends on the request parameters, database state, user session, or other runtime factors.
GET /api/users/123 HTTP/1.1
Host: example.com
→ Server invokes application code
→ Application queries database for user 123
→ Application formats JSON response
→ Server sends the generated content| Aspect | Static | Dynamic |
|---|---|---|
| Speed | Very fast (just file I/O) | Slower (computation required) |
| Caching | Easy (file doesn't change) | Complex (depends on data) |
| Server load | Minimal CPU | CPU and memory intensive |
| Examples | Images, CSS, JS bundles | API responses, user dashboards |
The Server as Gatekeeper
Before your application code ever sees a request, the web server has already done significant work:
- TLS termination — Decrypted the HTTPS connection
- Request parsing — Validated HTTP syntax, extracted headers
- Connection management — Handled TCP connection setup and keepalive
- Access control — Checked IP allowlists, rate limits
- Routing — Determined which backend or file should handle the request
- Header manipulation — Added or removed headers
This is why understanding web servers matters even if you "just write application code." The server's configuration affects security, performance, and behavior in ways that are invisible until something goes wrong.
The debugging principle: If you can't explain what happens between a request arriving at your server and your code executing, you can't effectively debug production issues. The server is not a black box you can ignore.
Common Web Servers
Several web servers dominate the landscape, each with different design philosophies:
| Server | Architecture | Best For |
|---|---|---|
| Nginx | Event-driven, async | High concurrency, reverse proxy, static files |
| Apache | Process/thread per request | Flexibility, .htaccess, module ecosystem |
| Node.js | Event-driven, single-threaded | JavaScript apps, real-time, API servers |
| Caddy | Event-driven | Automatic HTTPS, simple config |
We'll explore these architectural differences in Tutorial 3: Server Architecture Patterns.
What's Next
Now that you understand what a web server does at a high level, the next tutorial explores how servers communicate using HTTP—and how you can observe this communication yourself using command-line tools.