Skip to main content
K8sCalc
networking26 May 2026

Kubernetes Ingress Controllers in 2026: Nginx, Traefik, HAProxy, and Caddy

A technical comparison of the four most popular Kubernetes ingress controllers — what they do well, where they fall short, and which to pick for your workload.

The ingress controller is one of the most traffic-critical components in your cluster. A misconfigured or undersized ingress is the first place things break under load. Choosing the right one upfront saves a painful migration later.

This post covers the four controllers that matter in 2026: Nginx Ingress (ingress-nginx), Traefik, HAProxy Ingress, and Caddy (via ingress-caddy). Gateway API implementations are out of scope — that's a separate topic.

Feature Comparison

FeatureNginx IngressTraefik v3HAProxy IngressCaddy
TLS terminationYes (cert-manager)Yes (built-in ACME)Yes (cert-manager)Yes (built-in ACME)
Automatic TLS (ACME)No (needs cert-manager)YesNo (needs cert-manager)Yes
HTTP/2YesYesYesYes
HTTP/3 (QUIC)Yes (experimental)YesNoYes
WebSocket supportYesYesYesYes
gRPC supportYesYesYesYes
Auth middlewareBasic, OAuth (annotations)BasicAuth, ForwardAuthBasicAuthBasicAuth, ForwardAuth
Rate limitingYes (annotations)Yes (middleware CRD)Yes (annotations)Yes (handler)
Circuit breakerNoYesYesNo
Dashboard / UINoYes (built-in)NoNo
CRD-based configNo (annotations)Yes (IngressRoute)No (annotations)No (annotations)
Memory (idle, 3 replicas)~180 MB~120 MB~90 MB~75 MB
CPU (idle)LowLowVery lowVery low

Nginx Ingress (ingress-nginx)

Nginx Ingress is the de facto standard. It's what most tutorials assume, what most helm charts test against, and what most teams reach for by default — for good reason.

Strengths:

  • Enormous annotation surface for fine-tuning behavior
  • Mature, battle-tested at scale
  • Works with every cert-manager issuer
  • Excellent documentation and community

Weaknesses:

  • Config reload on every Ingress change (uses nginx -s reload)
  • No native dashboard
  • Annotation hell at scale — configuration becomes unreadable

Install:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.resources.requests.cpu=100m \
  --set controller.resources.requests.memory=90Mi

Basic Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
spec:
  ingressClassName: nginx
  tls:
    - hosts: [myapp.example.com]
      secretName: myapp-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp
                port:
                  number: 3000

Use the Kubernetes Ingress Generator to scaffold this for your service.

Traefik v3

Traefik takes a different philosophy: it watches Kubernetes resources dynamically and reconfigures without reloads. This makes it operationally smoother for clusters with frequent Ingress changes (feature branches, preview environments, CI).

Traefik's built-in ACME client means you can skip cert-manager entirely for simple setups. Its IngressRoute CRD gives you much cleaner config than annotation-packed Ingress objects.

Strengths:

  • Zero-downtime config reloads
  • Built-in Let's Encrypt — no cert-manager needed for basic TLS
  • Excellent dashboard for debugging routing rules
  • Clean middleware CRDs (rate limit, auth, redirect, headers)

Weaknesses:

  • Two config systems (Ingress annotations AND IngressRoute CRDs) creates confusion
  • ACME cert storage in a flat file by default — needs a Kubernetes Secret backend for HA
  • Less battle-tested at very high traffic (>50k req/s) compared to Nginx

Install:

helm repo add traefik https://helm.traefik.io/traefik
helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  --set persistence.enabled=true \
  --set persistence.size=1Gi \
  --set additionalArguments[0]="--certificatesresolvers.letsencrypt.acme.email=ops@example.com" \
  --set additionalArguments[1]="--certificatesresolvers.letsencrypt.acme.storage=/data/acme.json" \
  --set additionalArguments[2]="--certificatesresolvers.letsencrypt.acme.tlschallenge=true"

IngressRoute example:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`myapp.example.com`)
      kind: Rule
      services:
        - name: myapp
          port: 3000
      middlewares:
        - name: rate-limit
  tls:
    certResolver: letsencrypt

See also: Traefik vs Nginx Ingress comparison.

HAProxy Ingress

HAProxy Ingress uses HAProxy as the data plane, which has the best raw throughput and lowest latency of any option here. If you're running >100k requests per second or need sub-millisecond p99 latency, this is your controller.

HAProxy also has the most mature TCP and Layer 4 capabilities — useful if you need to proxy non-HTTP traffic through your ingress layer.

Strengths:

  • Best single-core performance of any L7 proxy
  • Excellent TCP/SSL passthrough
  • Very low memory footprint
  • No config reloads for backend changes (uses HAProxy runtime API)

Weaknesses:

  • Smaller ecosystem — fewer tutorials, less helm chart compatibility testing
  • No built-in ACME; requires cert-manager
  • Limited middleware ecosystem compared to Traefik

Install:

helm repo add haproxy-ingress https://haproxy-ingress.github.io/charts
helm install haproxy-ingress haproxy-ingress/haproxy-ingress \
  --namespace ingress-controller \
  --create-namespace

Basic config:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  annotations:
    haproxy-ingress.github.io/timeout-connect: "5s"
    haproxy-ingress.github.io/timeout-server: "60s"
    haproxy-ingress.github.io/balance-algorithm: leastconn
spec:
  ingressClassName: haproxy
  tls:
    - hosts: [myapp.example.com]
      secretName: myapp-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp
                port:
                  number: 3000

Caddy (ingress-caddy)

Caddy is the simplest option for teams that want TLS to just work. Its automatic HTTPS is the smoothest of any controller here — point it at a domain and it handles cert issuance, renewal, and OCSP stapling automatically. It also has native HTTP/3 support enabled by default, which neither Nginx nor HAProxy have production-ready.

Strengths:

  • Simplest TLS story — automatic HTTPS out of the box
  • HTTP/3 / QUIC enabled by default
  • Clean, readable Caddyfile configuration
  • Very low resource usage

Weaknesses:

  • Kubernetes integration is less mature than Nginx or Traefik
  • Smaller annotation surface — less fine-grained control
  • Not battle-tested at high scale in Kubernetes contexts

Install:

helm repo add ingress-caddy https://caddyserver.github.io/ingress
helm install caddy-ingress ingress-caddy/caddy-ingress-controller \
  --namespace caddy-system \
  --create-namespace

When to Choose Which

ScenarioRecommendation
Default cluster, standard appsNginx Ingress — maximum compatibility
Many services, frequent deploys, preview environmentsTraefik — dynamic reload, built-in ACME, dashboard
High-throughput API gateway, >50k req/sHAProxy — best raw performance
Simple cluster, want TLS without cert-manager hassleCaddy — easiest TLS story
Mixed HTTP + TCP routingHAProxy or Traefik — both handle TCP well
Team already knows NginxNginx Ingress — no learning curve

Resource Planning

At idle with 2 replicas, expect these memory figures:

ControllerMemory (2 replicas)Notes
Nginx Ingress~180 MB totalGrows with number of Ingress objects
Traefik~120 MB totalStable across Ingress count
HAProxy~90 MB totalVery efficient
Caddy~75 MB totalLowest baseline

Under load, Nginx and HAProxy scale horizontally cleanly. Use the Kubernetes Node Sizing Calculator to account for ingress controller overhead when sizing your nodes.