← Back to posts
kubernetes ingress comparison · · 13 min read

Traefik vs NGINX Ingress Controller vs Contour: Best Kubernetes Ingress 2026

Compare the top 3 Kubernetes ingress controllers — Traefik, NGINX Ingress Controller, and Contour. Learn which one fits your cluster for routing, TLS, and middleware in 2026.

OS
Editorial Team

When you expose services running inside a Kubernetes cluster to the outside world, you need a way to route external HTTP/HTTPS traffic to the correct internal pods. That is exactly what a Kubernetes ingress controller does. While the native Kubernetes Ingress resource defines how traffic should be routed, it is the ingress controller that actually implements those rules.

Choosing the right ingress controller matters because it becomes the single entry point for all external traffic to your cluster. It handles TLS termination, path-based routing, load balancing, rate limiting, and often serves as the first line of defense for your applications.

In this guide, we compare the three most popular open-source Kubernetes ingress controllers — Traefik, NGINX Ingress Controller, and Contour — with real deployment examples, a detailed feature comparison, and practical guidance to help you pick the right one.

For a broader look at how these tools compare outside of Kubernetes, see our NGINX vs Caddy vs Traefik web server guide and our self-hosted load balancers comparison.

Why Use a Dedicated Ingress Controller?

Kubernetes provides a basic Service type called LoadBalancer that can expose a single service externally. But in practice, you rarely want to provision a cloud load balancer for every service. An ingress controller solves this by acting as a reverse proxy that multiplexes many services through a single entry point:

  • Single IP address — one load balancer fronts dozens or hundreds of services
  • TLS termination — manage certificates centrally instead of per-pod
  • Path-based routing — route /api to one service, /web to another, all on the same domain
  • Host-based routing — serve app.example.com and api.example.com from the same controller
  • Middleware and plugins — add authentication, rate limiting, request rewriting, and headers without touching application code
  • Observability — access logs, metrics, and distributed tracing at the cluster edge

If you are running a self-hosted Kubernetes cluster on bare metal, you will also need a way to expose services without a cloud provider’s load balancer. Tools like MetalLB or Kube-VIP provide a virtual IP that your ingress controller can bind to. For full cluster setup guidance, check our k3s vs k0s vs Talos Linux comparison.

How Ingress Controllers Work

The Kubernetes Ingress API is a declarative resource. You define an Ingress object with rules like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 3000

The ingress controller watches these resources via the Kubernetes API and configures its internal proxy (NGINX, Envoy, or its own engine) accordingly. Each controller has its own set of annotations that extend the basic Ingress spec with controller-specific features like rate limits, authentication, and custom headers.

Traefik — The Cloud-Native Application Proxy

AttributeValue
GitHub Stars62,808
Last UpdatedApril 2026
LanguageGo
LicenseMIT
Proxy EngineBuilt-in (Go)

Traefik is a modern HTTP reverse proxy and load balancer designed specifically for dynamic environments like Kubernetes and Docker. It was built from the ground up with service discovery in mind, making it a natural fit for container orchestration.

Key Features

  • Automatic service discovery — watches Kubernetes APIs and Docker providers in real-time, no restarts needed
  • Built-in Let’s Encrypt — automatic HTTPS certificate provisioning and renewal with zero configuration
  • CRD support — Traefik defines custom resource definitions (IngressRoute, Middleware, ServersTransport) that go far beyond standard Ingress capabilities
  • Middleware pipeline — chain authentication, rate limiting, request modification, and retry logic declaratively
  • Dashboard — built-in web UI showing all routers, services, and middlewares in real time
  • Multiple providers — supports Kubernetes, Docker Swarm, Docker Compose, Consul, etcd, and file-based configuration

Traefik Deployment via Helm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Add the Traefik Helm repository
helm repo add traefik https://helm.traefik.io/traefik
helm repo update

# Install Traefik with Let's Encrypt enabled
helm install traefik traefik/traefik \
  --namespace traefik-system \
  --create-namespace \
  --set ingressRoute.dashboard.enabled=true \
  --set providers.kubernetesIngress.enabled=true \
  --set logs.general.level=INFO \
  --set ports.web.redirectTo=websecure \
  --set certificatesResolvers.letsencrypt.acme.email=admin@example.com \
  --set certificatesResolvers.letsencrypt.acme.storage=/data/acme.json \
  --set certificatesResolvers.letsencrypt.acme.tlsChallenge.enabled=true

Traefik IngressRoute CRD Example

Traefik’s custom IngressRoute resource provides features that standard Ingress cannot express:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: web-app
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`) && PathPrefix(`/api`)
      kind: Rule
      services:
        - name: api-service
          port: 8080
      middlewares:
        - name: rate-limit
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: web-service
          port: 3000
  tls:
    certResolver: letsencrypt
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit
  namespace: default
spec:
  rateLimit:
    average: 100
    burst: 50

NGINX Ingress Controller — The Battle-Tested Standard

AttributeValue
GitHub Stars19,498
Last UpdatedMarch 2026
LanguageGo (controller) + NGINX (proxy)
LicenseApache 2.0
Proxy EngineNGINX

The NGINX Ingress Controller is the official Kubernetes-maintained ingress implementation. It uses NGINX as the reverse proxy and load balancer, making it the most widely adopted ingress controller in production environments. It is essentially a control plane that watches Kubernetes resources and translates them into NGINX configuration.

Key Features

  • NGINX under the hood — leverages one of the most proven and performant web servers ever built
  • Extensive annotation support — over 50 annotations for fine-grained control over timeouts, rewrites, CORS, auth, and more
  • Stable and mature — used by millions of clusters; edge cases are well documented and understood
  • Community plugins — rich ecosystem of third-party modules and integrations
  • Custom snippets — embed raw NGINX configuration directly in annotations for unsupported features
  • Prometheus metrics — built-in metrics endpoint compatible with Grafana dashboards

NGINX Ingress Controller Deployment via Helm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Add the official ingress-nginx Helm repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# Install NGINX Ingress Controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.metrics.enabled=true \
  --set controller.service.type=LoadBalancer \
  --set controller.config.use-forwarded-headers="true" \
  --set controller.config.ssl-redirect="true" \
  --set controller.config.proxy-body-size="10m"

NGINX Ingress with Annotations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://app.example.com"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - app.example.com
    secretName: app-tls-secret
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 3000

Contour — The Envoy-Powered Ingress

AttributeValue
GitHub Stars3,927
Last UpdatedApril 2026
LanguageGo
LicenseApache 2.0
Proxy EngineEnvoy

Contour is a Kubernetes ingress controller developed by VMware and donated to the CNCF. It uses Envoy as its data plane proxy, giving it access to Envoy’s advanced traffic management capabilities. Unlike NGINX Ingress, Contour separates the control plane (Contour) from the data plane (Envoy), allowing for dynamic configuration updates without proxy restarts.

Key Features

  • Envoy proxy — industry-leading data plane with gRPC, HTTP/2, and advanced load balancing out of the box
  • HTTPProxy CRD — Contour’s custom resource provides a more expressive alternative to standard Ingress with support for header matching, timeouts, retries, and external authentication
  • Graceful degradation — Envoy continues serving traffic even when the Contour control plane is unavailable
  • Observability — native support for distributed tracing (Jaeger, Zipkin) and Prometheus metrics
  • External authorization — integrate with OAuth2-proxy, OPA, or custom auth services via Envoy’s ext_authz filter
  • Multi-cluster support — can route traffic across multiple Kubernetes clusters

Contour Deployment via Helm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Add the Bitnami Helm repository (official Contour charts)
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Install Contour
helm install contour bitnami/contour \
  --namespace contour \
  --create-namespace \
  --set envoy.kind=daemonset \
  --set contour.config.incluster=true \
  --set envoy.service.type=LoadBalancer \
  --set envoy.metrics.enabled=true

Contour HTTPProxy CRD Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: web-app
  namespace: default
spec:
  virtualhost:
    fqdn: app.example.com
    tls:
      secretName: app-tls-secret
  routes:
    - conditions:
      - prefix: /api
      services:
        - name: api-service
          port: 8080
      timeoutPolicy:
        response: 30s
        idle: 60s
      retryPolicy:
        count: 3
        perTryTimeout: 10s
    - conditions:
      - prefix: /
      services:
        - name: web-service
          port: 3000

Feature Comparison Table

FeatureTraefikNGINX IngressContour
Proxy EngineBuilt-in (Go)NGINXEnvoy
GitHub Stars62,80819,4983,927
LicenseMITApache 2.0Apache 2.0
LanguageGoGo + C (NGINX)Go + C++ (Envoy)
Auto TLS (Let’s Encrypt)Built-inVia cert-managerVia cert-manager
Custom ResourcesIngressRoute, MiddlewareStandard Ingress + annotationsHTTPProxy
gRPC SupportYesYesYes (native via Envoy)
HTTP/3 (QUIC)YesExperimentalYes (via Envoy)
Rate LimitingBuilt-in middlewareVia annotationsVia Envoy filters
Dashboard/Web UIYes (built-in)No (use Grafana)No
Prometheus MetricsYesYesYes
Distributed TracingJaeger, Zipkin, DatadogVia annotationsJaeger, Zipkin (native)
External AuthForwardAuth middlewareAuth-url annotationext_authz filter
WebSocketYesYesYes
TCP/UDP RoutingYesYesLimited
Configuration Hot-ReloadYesPartial (nginx reload)Yes (Envoy xDS)
Multi-ClusterLimitedLimitedYes

Choosing the Right Ingress Controller

Pick Traefik When

  • You want automatic HTTPS without setting up cert-manager
  • You need a single binary that works both inside and outside Kubernetes
  • The built-in dashboard is valuable for your team’s workflow
  • You prefer declarative CRDs over annotation-heavy configurations
  • You want the simplest possible setup for a small to medium cluster

Traefik is the easiest to get started with. Its Let’s Encrypt integration works out of the box, and its CRD-based configuration is cleaner and more maintainable than annotation-heavy approaches. The web dashboard is a significant productivity booster for teams that do not use external monitoring tools.

Pick NGINX Ingress Controller When

  • You need maximum stability and community support
  • Your team already has deep NGINX expertise
  • You want the widest annotation ecosystem for edge-case configurations
  • You need compatibility with tools that expect standard Ingress resources
  • You run a large-scale production cluster where battle-tested software matters

NGINX Ingress Controller is the default choice for most production Kubernetes deployments. Its massive user base means any issue you encounter has likely been solved and documented. The annotation system, while verbose, covers virtually every configuration need.

Pick Contour When

  • You want Envoy’s advanced data plane capabilities
  • You need multi-cluster traffic management
  • gRPC and HTTP/2 are first-class requirements
  • You want the control plane and data plane decoupled for resilience
  • You plan to integrate with service mesh architectures later

Contour is the best choice for teams that want Envoy’s capabilities without running a full service mesh. Its separation of control and data planes means that configuration updates do not disrupt active connections.

TLS and Certificate Management

All three controllers support TLS termination, but their approaches differ significantly.

Traefik has built-in ACME (Let’s Encrypt) support. You configure a certificate resolver once, and Traefik automatically requests, stores, and renews certificates for every domain in your IngressRoute resources:

1
2
3
4
5
6
7
# Traefik handles everything internally — no external cert-manager needed
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /data/acme.json
      tlsChallenge: {}

NGINX Ingress Controller and Contour rely on external certificate management, typically cert-manager. cert-manager is a Kubernetes-native solution that automatically provisions and renews certificates from Let’s Encrypt or internal PKIs. For a deeper dive into self-hosted certificate management, see our PKI and certificate management guide.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# cert-manager Certificate + Ingress (works with NGINX and Contour)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-cert
  namespace: default
spec:
  secretName: app-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - app.example.com

Performance Considerations

Benchmarks vary by workload, but here are the general performance characteristics:

  • Traefik — good for moderate traffic loads; the Go-based proxy is efficient but does not match NGINX or Envoy at extreme scale
  • NGINX Ingress Controller — excellent throughput and low latency; NGINX handles hundreds of thousands of concurrent connections with minimal memory overhead
  • Contour (Envoy) — excellent for high-throughput scenarios with complex routing; Envoy’s connection pooling and load balancing algorithms are industry-leading

For most self-hosted clusters serving internal or moderate external traffic, any of the three will perform well. The decision should be driven by feature requirements and operational preferences, not raw performance.

Migration Between Controllers

Migrating from one ingress controller to another is straightforward because the Ingress API is a Kubernetes standard. The process typically involves:

  1. Install the new ingress controller alongside the existing one
  2. Update your Ingress resources with the appropriate ingressClassName or annotations
  3. Verify routing works with the new controller
  4. Update your DNS or load balancer to point to the new controller’s service
  5. Remove the old ingress controller

Traefik users will need to migrate IngressRoute CRDs to standard Ingress resources (or vice versa) if switching away from Traefik. Contour users will need to migrate HTTPProxy resources. NGINX Ingress users have the easiest migration path since they already use standard Ingress resources.

FAQ

What is the difference between Kubernetes Ingress and an Ingress Controller?

The Kubernetes Ingress is an API resource that defines HTTP/HTTPS routing rules — which hostnames and paths map to which backend services. The Ingress Controller is the actual software that runs in your cluster, watches these Ingress resources, and implements the routing rules by configuring a reverse proxy. Without an ingress controller, Ingress resources are ignored.

Can I run multiple ingress controllers in the same cluster?

Yes. Kubernetes supports multiple ingress controllers simultaneously. Each controller is identified by its ingressClassName. You can route specific Ingress resources to specific controllers by setting spec.ingressClassName. This is useful for testing a new controller before fully migrating, or for routing different traffic types through different controllers.

Do I need cert-manager if I use Traefik?

No. Traefik has built-in ACME/Let’s Encrypt support and can automatically provision and renew TLS certificates without any external tool. NGINX Ingress Controller and Contour do not have built-in ACME support, so they require cert-manager or manual certificate management.

Which ingress controller is best for beginners?

Traefik is generally considered the easiest to set up and configure. Its built-in Let’s Encrypt integration means you get HTTPS with zero additional components. The web dashboard also provides immediate visibility into how your routes are configured, which is invaluable when learning Kubernetes networking.

Can these controllers handle TCP and UDP traffic?

Traefik and NGINX Ingress Controller both support TCP and UDP routing through custom configurations. Traefik uses EntryPoints for TCP/UDP, while NGINX Ingress uses TCP/UDP ConfigMaps. Contour’s Envoy data plane can handle TCP, but the HTTPProxy CRD is primarily designed for HTTP/HTTPS traffic. If you need extensive TCP/UDP routing, Traefik or NGINX Ingress Controller are the better choices.

How do I choose between the three?

Use this decision guide:

  • Simplest setup with auto-HTTPS: Traefik
  • Maximum stability and community: NGINX Ingress Controller
  • Envoy features and multi-cluster: Contour
  • Already using NGINX extensively: NGINX Ingress Controller
  • Want a web dashboard: Traefik
  • Need gRPC as a first-class citizen: Contour

Is Kong Ingress Controller a viable alternative?

Yes. Kong Ingress Controller (43,238+ stars on the core Kong project) is built on the Kong API gateway and offers an extensive plugin ecosystem for authentication, rate limiting, logging, and transformation. It is an excellent choice if you need API gateway features alongside ingress routing. For a broader look at API gateways, see our self-hosted API gateway guide.

Advertise here
Advertise here