What Is a Web Server? Web Server vs Application Server

A web server accepts HTTP connections, terminates TLS, serves static files from disk and forwards dynamic requests to code running elsewhere. That code runs on an application server: Tomcat, Gunicorn, Puma, Kestrel or a Node.js process. So what is a web server in practice? It is the layer built for connections and bytes, not business logic. A CDN edge server runs the same kind of software, placed in front of your origin to cache content near users.

Apache Tomcat ships with a default of 200 request-processing threads per connector, while the stock nginx configuration allows 1,024 connections per worker process, so a 4-worker nginx accepts 4,096 concurrent connections. That 20x gap in default concurrency, current as of 2026, is the practical reason application servers sit behind a web server instead of facing clients directly.

Verdict first: what is a web server for, and where it stops

This comparison was evaluated November 2026 against the current stable releases of each server. The short verdict by workload:

  • Default reverse proxy and static file server: nginx, unless you have a specific reason to choose otherwise.
  • Small teams that want TLS handled for them: Caddy, because certificate issuance and renewal through ACME is automatic and HTTP/3 is on by default.
  • PHP hosting with per-directory overrides: LiteSpeed Web Server, or Apache httpd if a commercial license is off the table.
  • .NET workloads on Windows Server: Microsoft IIS in front of Kestrel.
  • Terabytes of static files per month: any of the above as origin, with a CDN edge layer serving the traffic.

The web server's job ends where application logic begins. Once a request needs a database query, a session lookup or a template render, it belongs to the application server.

What a web server does on every request

A modern web server runs an event loop on epoll (Linux) or kqueue (BSD). One worker process can hold thousands of idle keep-alive connections at a cost of a few kilobytes each. A request moves through six steps:

  1. Accept the TCP connection and complete the TLS 1.3 handshake.
  2. Parse the HTTP/1.1, HTTP/2 or HTTP/3 request.
  3. Match it against routing rules by host and path.
  4. Serve a static file through the sendfile system call, so bytes move from the page cache to the socket without passing through user space.
  5. For everything else, act as a reverse proxy: forward the request to an upstream pool over HTTP, FastCGI or uWSGI and buffer the response.
  6. Apply compression, cache-control headers and access logging.

Response buffering is the step most teams undervalue. When nginx reads the full upstream response into its buffers, the application server's thread is released in milliseconds. A slow mobile client then drains the bytes from nginx over the next ten seconds. Without buffering, that client holds an application thread hostage for the whole transfer.

Web server vs application server: where the line actually is

A web server manages connections and moves bytes with an event-driven model. An application server executes your code, usually with a thread or process per in-flight request. The web server is cheap per connection and knows nothing about your business logic. The application server is expensive per request and knows everything about it. Production stacks run both.

Many application servers embed an HTTP listener: Tomcat's Coyote connector, Kestrel, Node.js. That makes the line look blurry. The listener is real, but its concurrency model is tuned for executing code, not for holding slow connections. Gunicorn's documentation suggests twice the CPU core count plus one as the worker count, so an 8-core box gets 17 workers. Seventeen concurrent requests is fine for 40 ms database calls and useless for streaming files.

Worked calculation: why application servers should not serve files

Take a 20 MB asset delivered to clients averaging 10 Mb/s. Each transfer takes 160 megabits divided by 10 Mb/s, or 16 seconds. Little's law says throughput equals concurrency divided by time in system:

  • Tomcat with 200 synchronous threads: 200 / 16 = 12.5 downloads per second, and zero threads left for API calls.
  • nginx with 4 workers at 1,024 connections each: 4,096 / 16 = 256 downloads per second. Its ceiling is 2.56 Gb/s of client bandwidth, so the bottleneck becomes the NIC instead of the thread pool.
  • A CDN edge layer at a 96% cache hit ratio in front of that nginx: 4 of every 100 requests reach origin, so 256 requests per second at the edge become about 10 at origin.

Each layer reduces the expensive resource behind it by one to two orders of magnitude. That is the whole argument for the three-tier layout.

Web server vs CDN edge server: same daemon, different job

A CDN edge server is a web server configured as a shared, geographically distributed cache. It runs nginx-derived, Varnish-based or in-house software. The difference is placement and state: your web server sits next to your application and is authoritative for content. An edge server sits near users, holds copies keyed by URL and headers, and fetches from your origin only on a miss.

That placement changes what you tune. On an origin web server you tune upstream keep-alive, buffer sizes and sendfile. On the edge, the levers are different:

  • cache key design and TTLs;
  • origin shield and request coalescing, so a cold object triggers one origin fetch instead of thousands;
  • Anycast routing for failover.

A CDN does not replace your web server. It reduces how much work the web server does.

For the heavy end of that static traffic (installers, game patches, video segments, large archives), BlazingCDN runs pull caching on NVMe SSD servers, accepts objects up to 50 GB and reports a 96%+ average cache hit ratio, so your nginx or Caddy origin only serves the misses. BlazingCDN Files on Demand for large-file delivery covers that workload specifically.

Web server vs application server vs CDN edge server compared

RoleCost driverConcurrency modelHolds stateTypical software
Web serverYour compute plus origin egressEvent loop, thousands of connections per workerStatic files, TLS certificatesnginx, Apache httpd, Caddy, LiteSpeed, IIS
Application serverCPU and memory per in-flight requestThread or process pool, tens to hundredsSessions, connection pools, business logicTomcat, Gunicorn, Puma, Kestrel, PHP-FPM
CDN edge serverPer-TB delivery billingEvent loop across many locationsCached copies keyed by URLVendor-operated nginx, Varnish or in-house stacks

The three roles differ mainly in what each unit of concurrency costs, which is why each one should only handle the traffic the layer behind it handles badly.

Popular web servers compared: nginx, Apache, Caddy, LiteSpeed, IIS

ServerCostLicense modelConcurrencyHTTP/3Config model
nginxNo license fee; NGINX Plus quote-basedBSD 2-clause open source plus commercial tierEvent-driven workersSince 1.25 (2023)Central files, reload to apply
CaddyNo license feeApache 2.0Go goroutinesOn by defaultCaddyfile or JSON admin API, live reload
Apache httpdNo license feeApache 2.0Pluggable MPM: prefork, worker, eventNot in coreCentral files plus htaccess overrides
LiteSpeed Web ServerPer-server license; OpenLiteSpeed has no feeCommercial; OpenLiteSpeed GPLv3Event-drivenSupportedReads Apache-style config
Microsoft IISIncluded with Windows Server licenseProprietaryKernel-mode http.sys plus worker processesWindows Server 2022 and laterXML config, GUI manager

Licensing rarely decides this choice; the configuration model and the application runtime behind the server usually do.

nginx

nginx is the default reverse proxy for good reason. Its event model, sendfile path and upstream keep-alive pooling are mature, and its tuning knowledge is the deepest of any server here. Limitation: active health checks, a live reconfiguration API and dynamic upstreams without a reload are reserved for the commercial NGINX Plus tier.

Caddy

Caddy removes certificate operations from the job: it obtains and renews certificates through ACME automatically and serves HTTP/3 out of the box. Limitation: its third-party module ecosystem is smaller, and there is less large-fleet tuning experience to draw on than for nginx.

Apache httpd

Apache httpd stays relevant because htaccess overrides let tenants change rewrite and access rules without touching the main config. The event MPM closed most of the old concurrency gap. Limitation: that override flexibility costs a filesystem check per directory level on every request, and there is no HTTP/3 in the core server.

LiteSpeed Web Server

LiteSpeed reads Apache configuration and htaccess files on an event-driven core. Its LSAPI integration is a strong fit for PHP applications. Limitation: the enterprise edition is licensed per server, and the open-source OpenLiteSpeed handles htaccess rewrites only partially.

Microsoft IIS

IIS is the natural front end for .NET on Windows, with kernel-mode request queuing in http.sys and tight integration with Windows authentication. Limitation: it runs only on Windows, and cross-platform .NET deployments increasingly put Kestrel behind nginx instead.

Recommendation matrix: which server fits which workload

WorkloadBest fitWhy
Python or Ruby APInginx in front of Gunicorn or PumaBuffering protects a small worker pool from slow clients
Java servicesnginx in front of TomcatKeeps the 200-thread pool for code, not for transfers
Static site or single-page appCaddy, then nginxAutomatic TLS and HTTP/3 with minimal config
Multi-tenant PHP hostingLiteSpeed, then Apache httpdPer-directory overrides tenants already depend on
.NET on WindowsIIS in front of KestrelNative auth and http.sys queuing
Video, installers, game patches at TB scaleCDN edge in front of an nginx originOrigin egress and connection count drop with the hit ratio

The web server choice follows the application runtime, while the CDN decision follows monthly bytes, so the two should be made separately.

Trade-offs and how to verify your setup

Every extra layer adds a hop, a config surface and a failure mode. A reverse proxy in front of an application server adds sub-millisecond latency on loopback but can mask upstream errors as generic 502s. A CDN in front of the web server adds cache invalidation work and can serve stale content after a bad deploy. Embedding everything in one Node.js or Kestrel process is simpler, and it is acceptable until slow clients or file downloads start consuming request slots.

To check where your stack stands, look at four signals:

  • Busy threads: Tomcat's currentThreadsBusy metric over JMX, or busy Gunicorn workers. If they track download traffic, files are hitting the application server.
  • Upstream timing: compare upstream_response_time with request_time in the nginx access log. A large gap means buffering is doing its job.
  • Edge cache status: request a static asset with any HTTP client and read the Age header and the CDN's cache status header to confirm edge hits.
  • Connection count: the active connections figure in nginx stub_status, tracked against your worker_connections ceiling.

FAQ: web server vs application server vs CDN

Is nginx a web server or an application server?

nginx is a web server and reverse proxy, not an application server. It serves static files, terminates TLS and forwards dynamic requests to application servers such as Gunicorn, Puma or PHP-FPM over HTTP or FastCGI. The njs module can run small amounts of logic, but business code with database access belongs in a dedicated application server process.

Do I need a web server in front of Tomcat or Gunicorn?

Yes for any public production traffic. Tomcat defaults to 200 request threads, and Gunicorn typically runs twice the core count plus one workers, so slow clients exhaust both quickly. A web server such as nginx buffers responses, absorbs slow connections, terminates TLS and serves static assets, which leaves the application server's limited pool for executing code.

Can a CDN replace my web server?

No. A CDN edge server caches copies of your content near users, but it still needs an origin web server to fetch from on cache misses. At a 96% cache hit ratio the origin handles roughly 4 of every 100 requests, so a CDN shrinks the web server's load and egress without removing the need for one.

Which web server should I choose for static files and reverse proxying?

nginx is the safest default web server for static files and reverse proxying, thanks to mature sendfile handling, upstream keep-alive pooling and broad tuning knowledge. Caddy suits teams that want automatic TLS and HTTP/3 with little configuration. LiteSpeed and Apache httpd fit PHP hosting that relies on per-directory overrides, and IIS fits .NET on Windows Server.

Measure your origin's static share, then offload it

This week, take seven days of access logs from your web server and group bytes served by content type and object size: under 1 MB, 1 to 100 MB, and over 100 MB. Then set that against application server thread utilization for the same window. If large objects account for most bytes while threads spike during download peaks, you have two fixes in order. First, move file serving from the application server to nginx or Caddy with sendfile. Then put an edge cache in front of that origin and track how origin egress falls as the hit ratio rises.

If the largest bucket is installers, video segments or game builds, the BlazingCDN Anycast CDN for static file delivery page describes pull caching with origin shield and request coalescing included on every plan.

Heavy traffic.
Light bill.

The CDN for video and large traffic