Web Server: What It Is and How It Works

A web server is a system that stores and delivers web content to browsers. When a user visits a website, the web server receives the request and sends back the HTML, CSS, JavaScript, and other files.

Web Server

A web server is software, and the hardware it runs on, that stores, processes, and delivers web content to clients over the internet. Every website you visit is powered by a web server that listens for incoming HTTP requests and returns the appropriate files or data. The term can refer to the physical machine, the software running on it, or both together depending on the context.

In the client-server model, the web server is the server side of every interaction. It waits for connections on specific network ports, port 80 for HTTP and port 443 for HTTPS, receives requests from browsers and other HTTP clients, and responds with HTML pages, images, JSON data, CSS files, video streams, or any other type of content the client has requested.

A web server does not sleep between requests. It runs continuously, handling thousands of simultaneous connections from different clients around the world, each requesting different resources at different moments. The efficiency with which it manages this concurrency is one of the primary factors that determines how many users a website can serve reliably.

How a Web Server Processes Requests

Every HTTP interaction follows the same fundamental sequence, from the moment a client connects to the moment it receives a response. Understanding this sequence helps you diagnose performance problems, configure server software correctly, and understand what happens when something goes wrong.

  1. A client such as a browser sends an HTTP request to the server's IP address on port 80 or 443, having first resolved the domain name through DNS
  2. If HTTPS is used, a TLS handshake is completed before any HTTP data is exchanged, establishing an encrypted channel for the session
  3. The web server software receives and parses the request, examining the HTTP method such as GET or POST, the requested URL path, and the request headers
  4. The server checks its configuration to determine how to handle the requested path, whether to serve a file, forward the request to an application, redirect to a different URL, or return an error
  5. For static content, the server locates the requested file on disk, reads it into memory, and prepares a response directly
  6. For dynamic content, the server passes the request to an application runtime such as PHP, Python, or Node.js, which runs business logic, queries a database if needed, and generates the response body
  7. The server constructs an HTTP response containing an HTTP status code, response headers including content type and caching instructions, and the content body
  8. The response is sent back to the client over the same TCP connection, which may be kept open for subsequent requests under HTTP keep-alive
  9. The client renders the received content, discovers additional resources such as stylesheets and images, and sends further requests for each one
Example HTTP request and response:
Request:
GET /tutorial/web-server HTTP/1.1
Host: example.com
Accept: text/html
Accept-Encoding: gzip, deflate, br

Response:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 12840
Cache-Control: max-age=3600
Content-Encoding: gzip

<!DOCTYPE html>
<html>...page content...</html>

Static vs Dynamic Web Servers

Web servers can be categorised based on whether they serve pre-built files or generate content at request time. The distinction has significant implications for performance, infrastructure complexity, and the types of applications that can be built.

FeatureStatic Web ServerDynamic Web Server
Content SourceServes files exactly as stored on disk, including HTML, CSS, JavaScript, and imagesGenerates content on the fly by executing server-side code on each request
Server-Side LanguagesNone required. The server simply reads and delivers files.PHP, Python, Node.js, Ruby, Go, Java, or any other server-side language
DatabaseNot required. All content exists as files.Often requires MySQL, PostgreSQL, MongoDB, or another database to store and retrieve data
PerformanceVery fast. No computation is needed per request, only file reading and transmission.Slower per request due to code execution, database queries, and template rendering
ScalabilityExtremely scalable. Static files can be cached at CDN edge nodes globally.Requires more infrastructure to scale, including application servers, databases, and caching layers
PersonalisationLimited. Every user receives identical content for the same URL.Full personalisation based on user identity, preferences, and data
Use CasesDocumentation sites, marketing pages, portfolios, blogs, landing pagesE-commerce platforms, social networks, dashboards, APIs, content management systems
ExamplesGitHub Pages, Netlify, Cloudflare Pages serving a Next.js static exportWordPress on Apache, Django on Gunicorn, Express.js on Node

Popular Web Server Software

Several web server software packages dominate the industry, each with different strengths, architecture decisions, and ideal use cases. Most production deployments use one of these or a combination of them.

SoftwareKnown ForTypical Use
Apache HTTP ServerOpen source, highly configurable via .htaccess files, extensive module ecosystem, broad hosting supportShared hosting environments, LAMP stack applications (Linux, Apache, MySQL, PHP)
NginxEvent-driven architecture, very low memory usage, high concurrency, excellent as a reverse proxyHigh-traffic production sites, reverse proxy in front of application servers, load balancing
Microsoft IISDeep Windows Server integration, graphical management interface, native .NET supportASP.NET and .NET Core applications running on Windows infrastructure
LiteSpeedHigh performance, drop-in Apache compatibility, native cPanel support, built-in cacheHosting providers looking for performance improvements over Apache, WordPress acceleration
Node.js http moduleJavaScript on the server, non-blocking event-driven I/O, same language as the front endReal-time applications, REST APIs, WebSocket servers, microservices
CaddyAutomatic HTTPS certificate provisioning via Let's Encrypt, simple declarative configuration, sensible security defaultsPersonal projects, small to medium sites, teams that want automatic TLS without manual certificate management
HAProxySpecialised in TCP and HTTP load balancing, extremely reliable, used by large-scale deploymentsHigh-availability load balancing in front of multiple web server instances

Web Server vs Application Server

In many production setups, a web server and an application server work together in a layered architecture. The two serve distinct but complementary roles, and separating them often improves both performance and maintainability.

The web server sits at the front of the stack. It handles incoming HTTP connections, terminates SSL/TLS encryption, serves static files directly from disk, applies rate limiting and access control, and forwards dynamic requests to the application server running behind it. Because web servers like Nginx are optimised for handling many concurrent connections with low overhead, they can absorb a large volume of traffic without consuming significant resources.

The application server sits behind the web server and focuses entirely on executing business logic. It receives forwarded requests from the web server, runs the application code, interacts with databases and external services, and returns the generated content. Application servers are not optimised for handling raw HTTP connections efficiently, which is why placing a dedicated web server in front of them is a standard architectural pattern.

TypeRoleExamples
Web ServerHandles HTTP connections, serves static files, terminates TLS, applies rate limiting, proxies dynamic requests to the application layerNginx, Apache, Caddy, IIS
Application ServerExecutes server-side application code, implements business logic, queries databases, generates dynamic responsesPHP-FPM, Gunicorn (Python), PM2 (Node.js), Puma (Ruby), Tomcat (Java)
Nginx configuration proxying to a Node.js application server:
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # Serve static files directly from disk
    location /static/ {
        root /var/www;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Forward API requests to the Node.js application server
    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Forward all other requests to the application server
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

In this configuration, Nginx handles TLS termination, serves static assets from disk with long cache headers, and forwards all other requests to a Node.js application running on port 3000. The X-Real-IP and X-Forwarded-For headers pass the client's original IP address to the application so it is not lost during proxying.

Creating a Simple Web Server

You can build a functional web server with minimal code in any server-side language. These examples demonstrate the core request-response cycle running on your local machine.

Node.js web server with routing:
const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
  if (req.url === '/' && req.method === 'GET') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>Home Page</h1><p>Welcome to the web server.</p>');

  } else if (req.url === '/api/status' && req.method === 'GET') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ status: 'ok', uptime: process.uptime() }));

  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 Not Found');
  }
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000');
});
Python web server using the built-in http.server module:
# Serves files from the current directory on port 8000
python3 -m http.server 8000

# Navigate to http://localhost:8000 to browse files

Run the Node.js example with node server.js and open http://localhost:3000 in your browser. The browser sends a GET request and the server returns an HTML response, completing the full client-server cycle on your local machine. The Python command is useful for quickly serving files during development without any setup.

Virtual Hosting

A single web server can host multiple websites simultaneously through a feature called virtual hosting. The server examines the Host header in each incoming HTTP request to determine which website the client is trying to reach, then serves content from the appropriate configuration and file system location for that domain.

Nginx virtual hosting configuration for two domains:
# First website
server {
    listen 80;
    server_name siteone.com www.siteone.com;
    root /var/www/siteone;
    index index.html;
}

# Second website on the same server and IP address
server {
    listen 80;
    server_name sitetwo.com www.sitetwo.com;
    root /var/www/sitetwo;
    index index.html;
}

Both websites share the same IP address and server hardware but serve completely independent content. This is the foundation of shared web hosting, where a single server hosts hundreds or thousands of websites for different customers, each isolated from the others through virtual host configuration.

Frequently Asked Questions

  1. Do you need a web server to build a website?
    For development, you use a local development server running on localhost, such as Node.js, PHP's built-in server, XAMPP, or a framework's development mode. This lets you test your site without deploying it anywhere. For production, your website must be hosted on a web server accessible on the internet so that users can reach it. Web hosting providers manage the server hardware, operating system, and web server software for you, leaving you to focus on your application.
  2. What is the difference between Nginx and Apache?
    Apache uses a process-per-connection or thread-per-connection model and allows directory-level configuration through .htaccess files, which makes it flexible but consumes more memory under high concurrency. Nginx uses an event-driven, non-blocking architecture that handles thousands of simultaneous connections in a single process with very low memory usage. Nginx is often used as a high-performance reverse proxy in front of application servers, while Apache remains widely used in shared hosting environments because of its deep compatibility with existing hosting control panels and the LAMP stack.
  3. What port does a web server use?
    By default, HTTP uses port 80 and HTTPS uses port 443. When a browser makes a request to a URL without specifying a port, it connects to these default ports automatically based on the protocol. Development servers typically use ports like 3000, 5000, or 8080 to avoid requiring administrator privileges, which are needed to bind to ports below 1024 on Linux systems, and to avoid conflicting with any production service that might be running on the standard ports.
  4. Can one physical server run multiple websites?
    Yes. This is called virtual hosting and it is how the vast majority of websites are hosted. The web server reads the Host header from each incoming HTTP request to determine which of its configured virtual hosts should handle the request. Both Apache and Nginx support name-based virtual hosting, allowing hundreds of domains to be served from a single machine with a single IP address. Shared hosting providers use this technique to host thousands of customer websites on the same physical server.
  5. How does a web server handle thousands of simultaneous requests?
    Different web servers use different concurrency models to handle simultaneous connections. Apache traditionally creates a new process or thread for each connection, which provides isolation but consumes significant memory at scale. Nginx uses a single-threaded event loop that handles all connections asynchronously, which allows it to manage tens of thousands of simultaneous connections with very low memory overhead. For high-traffic production deployments, web servers are combined with techniques including load balancing to distribute requests across multiple server instances, HTTP caching to serve repeated requests from memory without application processing, and CDN delivery to offload static asset requests entirely from the origin server.

Conclusion

A web server is the backbone of every website and web application on the internet. It receives HTTP requests, determines how to handle each one, serves static files directly or delegates dynamic requests to an application server, and returns responses with the correct status codes, headers, and content. Choosing the right web server software, understanding the distinction between static and dynamic content, and knowing how to configure virtual hosting and reverse proxying are foundational skills for anyone building or deploying web applications. Continue with the client-server model, reverse proxy, and HTTP vs HTTPS to build a complete understanding of web server architecture.