Caddy vs nginx: HTTPS, Config and Which to Pick

The headline difference is certificates. Caddy serves every site over HTTPS by default, fetching and renewing certificates from Let's Encrypt or ZeroSSL and redirecting HTTP for you. nginx needs certificate files you supply, from an ACME client or its separate acme module. Caddyfiles are shorter; nginx offers finer control and a much longer track record.

Caddy and nginx compared on everyday jobs
JobCaddynginx
HTTPS certificatesAutomatic for any public domain in the configYou point ssl_certificate at files, or add the separate ngx_http_acme_module
HTTP to HTTPS redirectAutomaticA port 80 server block that returns 301
Compressionencode zstd gzipgzip on
Reverse proxyreverse_proxy localhost:3000proxy_pass in a location, plus headers
WebSockets through the proxyHandled automaticallyForward Upgrade and Connection headers
Load balancing defaultrandomround robin
Active health checkshealth_uri in reverse_proxyhealth_check in the commercial edition only
Config check and reloadcaddy validate, caddy reloadnginx -t, nginx -s reload

Updated

Most comparisons stop at features. Here you can type a domain and an app port and get both configs, so you can see exactly how much each server asks you to write for the same result. Below the builder are side-by-side snippets for the jobs that come up most, then honest notes on where each one fits.

Caddyfile and nginx config builder

Type a domain, pick static files or a reverse proxy, and compare the two configs line for line.

The nginx version expects certificate files at the paths shown; get them from your ACME client first.

Load balancing three app servers

Caddyfile

Round robin across three backends, with background health checks against /healthz.

app.example.com {
    reverse_proxy 10.0.0.11:8080 10.0.0.12:8080 10.0.0.13:8080 {
        lb_policy round_robin
        health_uri /healthz
    }
}

nginx

Round robin is the default. Open source nginx only checks health passively, through failed requests.

upstream app {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
    server 10.0.0.13:8080;
}

server {
    listen 443 ssl;
    server_name app.example.com;
    ssl_certificate     /etc/ssl/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/ssl/app.example.com/privkey.pem;

    location / {
        proxy_pass http://app;
    }
}

Proxying WebSockets

Caddyfile

reverse_proxy performs the upgrade and keeps a two-way tunnel open with no extra lines.

example.com {
    reverse_proxy /ws/* localhost:8080
}

nginx

The Upgrade and Connection headers must be passed on explicitly; proxy_http_version 1.1 is needed before nginx 1.29.7.

location /ws/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

What automatic HTTPS really covers

When a Caddyfile names a public domain, Caddy obtains a certificate through ACME, serves the site on 443, redirects port 80 to HTTPS and renews the certificate in the background. If one issuer fails it retries and can fall back to another. Nothing in the config mentions TLS unless you want to change the defaults.

nginx leaves this to you. The usual setup is an ACME client that writes certificate files and reloads nginx after renewing them, or the newer acme module that you install on purpose.

When nginx is the better fit

nginx is everywhere: in distributions, container images and hosting panels, with documentation and answers for nearly every situation. Teams that already run it, rely on particular modules, or need fine control over buffering and caching have little reason to move.

When Caddy is the better fit

Small teams, side projects and many domains benefit most from not managing certificates. Its native config format is JSON, which caddy adapt produces from a Caddyfile, and caddy reload pushes a new config to the running process through its admin API without downtime.

How it works

  1. Enter your domain and choose whether the server should hand out static files or forward requests to an app.
  2. Toggle compression and the www redirect to see which lines each server needs.
  3. Copy the Caddyfile next to the caddy binary and run caddy run, or copy the nginx block into a file under your sites folder.
  4. For nginx, get a certificate first with your ACME client and update the two certificate paths before reloading.

Tips

Frequently asked questions

Is Caddy a drop-in replacement for nginx?

For static sites, reverse proxies and simple load balancing, usually yes, and the config gets shorter. Large nginx setups using many third-party modules, complex map and rewrite logic, or tuned caching may not have a one-to-one Caddy equivalent, so translate and test one site at a time.

Does nginx do automatic HTTPS now?

nginx has an ngx_http_acme_module that implements ACME, but it is not built by default. You install it as a separate dynamic module (the nginx-module-acme package) and configure an issuer. Without it, certificates come from an external client.

Can Caddy give me HTTPS on localhost?

Yes. For localhost and internal names Caddy creates its own local certificate authority and issues certificates from it. Your system may ask once to trust its root certificate.

Which has better performance?

We do not publish speed numbers because they swing with hardware, TLS settings and workload. Both handle typical websites and APIs comfortably. If raw throughput matters for you, benchmark your own traffic pattern on your own servers.

Does Caddy support load balancing and health checks?

Yes. List several upstreams in reverse_proxy, choose an lb_policy such as round_robin or least_conn, and add health_uri for active checks or fail_duration for passive ones. Without a policy, Caddy picks upstreams at random.

Related: Apache vs nginx, nginx load balancing, SSL certificate types, DNS record types, Deploy a React app.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap