caddy vs nginx: I Benchmarked Both Serving Static Files

– min read

A client asked me last week whether Caddy can handle production traffic the same way nginx does. I had opinions but no numbers. So I installed both on the same VM, served the same static files, and ran ApacheBench against each. Here is what I found.

nginx: nginx.org · GitHub
Caddy: caddyserver.com · GitHub


What You Need

  1. A Debian/Ubuntu server (I used Ubuntu 26.04 on a 2 vCPU VM)
  2. sudo access
  3. ApacheBench (apt install apache2-utils) for the benchmark runs


Setup

I created a synthetic 1.5 KB static page and a 10 KB binary file, wrote minimal configs for both servers, and benchmarked with ab -n 5000 -c 100 on loopback. The test data is synthetic and uses RFC 5737-safe addresses for reproducibility.


Nginx Config

worker_processes 1;
events { worker_connections 1024; }
http {
    access_log off;
    server {
        listen 8091;
        root /var/www/bench;
    }
}


Caddy Config

8092 {
    root * /var/www/bench
    file_server
}


Reverse Proxy Config Comparison

Both tools are also commonly used as reverse proxies. Here is the difference in config lines:

# nginx — 5 lines
server {
    listen 127.0.0.1:3000;
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}
# Caddy — 1 line
127.0.0.1:3000 { reverse_proxy 127.0.0.1:8080 }


Benchmark Results

I ran ab -n 5000 -c 100 against each server. The full outputs:

# nginx 1.28.3
Requests per second:  15850.02 [#/sec] (mean)
Complete requests:      5000
Failed requests:           0
Transfer rate:        26839.78 [Kbytes/sec] received

Connection Times (ms)
              min   avg   max
Connect:        0     2    4
Processing:     1     4    7
Total:          4     6    8

Percentage of the requests served within a certain time (ms)
  50%      6
  95%      7
  99%      8


# Caddy v2.11.9
Requests per second:   7524.22 [#/sec] (mean)
Complete requests:      5000
Failed requests:           0
Transfer rate:        12858.77 [Kbytes/sec] received

Connection Times (ms)
              min   avg   max
Connect:        0     1   11
Processing:     0    13   48
Total:          0    13   48

Percentage of the requests served within a certain time (ms)
  50%     12
  95%     23
  99%     29


Metricnginx 1.28.3Caddy v2.11.9
Package size1.6 MB (1593 KB)49.8 MB (49774 KB)
Binary size1.6 MB50.9 MB
Reverse proxy config5 lines1 line
TLS out of boxNo (requires certbot)Yes (built-in ACME)
HTTP/3 supportYes (–with-http_v3_module)Yes (built-in)
Requests/sec15,8507,524
p50 latency6 ms12 ms
p95 latency7 ms23 ms
p99 latency8 ms29 ms
Memory per process (RSS)~2.3 MB (master) + 5.2 MB (worker)~50 MB (full-service) or 2.1 MB (file-server)


Bar chart caddy vs nginx benchmark
Static file serving benchmark: nginx vs Caddy. Chart from real ab runs on a 2 vCPU Ubuntu 26.04 VM.


nginx web server logo
nginx logo (public domain, Wikimedia Commons).
Caddy web server logo
Caddy web server logo (public domain, Wikimedia Commons).


Verdict

Nginx won on raw throughput by a factor of 2x (15,850 vs 7,524 req/s) with lower and more consistent latency. If you are migrating a reverse proxy setup or serving high-traffic static content, nginx is the right choice. Caddy shines where you want minimal config and zero-effort HTTPS — write a one-line reverse proxy, and Let’s Encrypt is automatic. For a homelab or personal site where throughput is not the bottleneck, Caddy’s ergonomics win.


If you are new to Caddy, my install guide walks through the setup. For nginx-based workflows, see my nginx access log analysis script. This is the latest in my tool comparison series — earlier I compared jq vs Python on a 100K-line log.

The numbers above come from a single run on a 2 vCPU VM. Your mileage will vary by hardware, concurrency, and workload shape. Benchmark your own stack before deciding.

Mohamad ZulfahmyCybersecurity · OffSec · Entrepreneur
About me ↗
ON THIS PAGE
On this page