Skip to content

Gateway Selection Report

Overview

This report evaluates 8 API gateway candidates for the BANA POS system. The gateway serves as the single entry point for all external traffic, routing requests to the correct backend microservice while providing resilience and observability.

Routing Strategy: Service-Owned Prefix — each service sets APP_ENV_SERVER_BASE_PATH=/v1/api/<service>. Docker label/annotation self-registration — each service declares its own route. Zero central route config.

Architecture: Host-level Nginx (TLS + domains) → Traefik (Docker, :30080, service routing + resilience + observability) → Backend Services.

Candidates

#GatewayLanguageLicenseFirst ReleaseGitHub Stars
1Nginx (OSS)CBSD-2200426k+
2HAProxyCGPL-220015k+
3TraefikGoMIT201553k+
4CaddyGoApache-2201560k+
5EnvoyC++Apache-2201625k+
6Kong (OSS)Lua/NginxApache-2201540k+
7Apache APISIXLua/NginxApache-2201914k+
8KrakenD (CE)GoApache-220172k+

Performance Benchmarks

Based on independent K8s Ingress Controller tests:

GatewayRPSP99 LatencyCPU UsageMemoryErrors Under Stress
HAProxy~42,000Lowest~50%~50MB0
Nginx~15,200LowMedium~80MBLow
Traefik~19,000MediumStable~100MB1,342
Envoy~18,500Low-Medium~73%~150MBLow
KrakenD~70,000*Lowest4-6%~30MBN/A
Kong~15,000High (1032ms avg)High~200MB+Medium
APISIX~18,000Medium (1025ms avg)Medium~100MBLow
Caddy~12,000MediumMedium~60MBLow

*KrakenD 70k RPS is their own benchmark (stateless, no K8s overhead). Take with grain of salt vs independent tests.

Feature Matrix

FeatureNginx OSSHAProxyTraefikCaddyEnvoyKong OSSAPISIXKrakenD CE
Docker Label DiscoveryNo3rd-partyNativeNoNoNoNoNo
K8s Ingress ControllerYes (EOL Mar 2026!)YesYesWIPYesYesYesYes
K8s Gateway APINoYesYes (native)NoYes (native)YesYesNo
Circuit BreakerNoNoYesNoYesPluginPluginYes
Rate Limiting3rd-partyBasicYesNoYesPluginPluginYes
Active Health ChecksNo (paid)YesYesNoYesYesYesNo
Retry/TimeoutLimitedYesYesNoYes (advanced)PluginPluginYes
WebSocketYesYesYesYesYesYesYesEnterprise only!
gRPCYesYesYesYesYesYesYesYes
HTTP/3 (QUIC)YesYesYes (exp.)YesYesNoYesNo
Auto TLS (ACME)NoNoYesYes (best)NoNoNoNo
Built-in MetricsNoStatsYes (Prometheus)YesYesPluginPluginYes
Dashboard/UINoStats pageYes (built-in)NoAdmin APIPaidFreeNo
Security HeadersManualManualYes (middleware)ManualYes (filter)PluginPluginYes
Hot Reloadnginx -s reloadreloadAutomaticAutomaticxDS APIDB-drivenetcd/YAMLFile reload
Stateless (no DB)YesYesYesYesYesNo (PostgreSQL)Needs etcdYes
Config ComplexityMediumMediumLow (labels/YAML)LowHighMediumMediumLow
Learning CurveLowMediumLowVery LowHighMediumMediumLow

Critical Disqualifiers for BANA

CandidateDisqualifierSeverity
Nginx OSSK8s Ingress Controller EOL March 2026. No circuit breaker, no active health checks, no rate limiting, no metrics in OSS. No Docker label discovery.CRITICAL
CaddyK8s Ingress Controller is WIP/immature. No circuit breaker, no rate limiting, no active health checks. No Docker label discovery.HIGH
KrakenD CEWebSocket support is Enterprise-only (paid). Required for signal service. No Docker label discovery. No K8s Gateway API support.CRITICAL
Kong OSSRequires PostgreSQL database (operational overhead). Heaviest resource footprint (~200MB+). Plugin-dependent for most features.MEDIUM
Apache APISIXRequires etcd cluster (or standalone YAML mode). No Docker label discovery. More complex setup than needed.MEDIUM
EnvoyHighest config complexity (xDS, YAML clusters/listeners). No Docker label discovery. Designed for service mesh, overkill for gateway-only use.MEDIUM

Finalist Analysis

After eliminating candidates with critical/high disqualifiers, three strong candidates remain:

Traefik

Strengths:

  • Native Docker label discovery (exactly matches service-owned prefix pattern)
  • Native K8s Gateway API support (future-proof for K8s migration)
  • Built-in circuit breaker, rate limiting, retry, health checks (no plugins needed)
  • Built-in Prometheus metrics + dashboard
  • Auto TLS with Let's Encrypt
  • WebSocket native support
  • Lowest config complexity for Docker-first workflow
  • MIT license, huge community (53k stars)
  • CNCF graduated project

Weaknesses:

  • Not the fastest (19k RPS vs HAProxy's 42k)
  • 1,342 errors under extreme stress test
  • No advanced L4 load balancing features

HAProxy

Strengths:

  • Absolute best raw performance (42k RPS, zero errors)
  • Lowest latency at P99
  • Lowest CPU/memory footprint
  • K8s Gateway API support
  • Advanced L4/L7 load balancing (sticky sessions, connection draining)
  • 24 years of battle-tested stability
  • Active health checks, retry

Weaknesses:

  • No native Docker label discovery (requires 3rd-party EasyHAProxy)
  • No built-in circuit breaker
  • No auto TLS (ACME)
  • No built-in Prometheus metrics endpoint (needs exporter)
  • No built-in dashboard (just stats page)
  • Config files are more verbose
  • EasyHAProxy is a community project, not HAProxy official

Envoy

Strengths:

  • Most powerful feature set overall
  • Real-time config via xDS API (zero-downtime changes)
  • Powers Istio, Consul Connect, AWS App Mesh
  • Best for service mesh if you go that route
  • Native K8s Gateway API (Envoy Gateway)
  • Advanced circuit breaking, outlier detection, retry

Weaknesses:

  • Highest config complexity (steep learning curve)
  • Highest memory usage (~150MB)
  • No Docker label discovery
  • Overkill if you don't need service mesh
  • Requires significant Envoy expertise

Scoring Matrix

Weighted scoring (1-5, higher = better for BANA):

Criteria (Weight)TraefikHAProxyEnvoy
Docker-first workflow (25%)521
K8s Gateway API ready (20%)545
Built-in resilience (15%)535
Performance/efficiency (15%)354
Operational simplicity (15%)531
Observability built-in (10%)525
Weighted Total4.603.153.10

Migration Path Comparison

PhaseTraefikHAProxyEnvoy
Docker Compose (now)Labels → auto-discoverEasyHAProxy labels or manual cfgManual envoy.yaml per service
K8s MigrationLabels → IngressRoute CRDs (mechanical)Labels → annotations (OK)YAML → Gateway API CRDs (complex)
Service Mesh (future)Traefik Mesh (optional)No mesh storyIstio/Consul (native)

Decision

Selected: Traefik v3.6 (score 4.60/5)

Traefik is the clear winner for BANA because:

  1. Docker label self-registration is a native feature — services declare their own routes via Docker labels, achieving zero central route configuration
  2. K8s Gateway API is natively supported — when migrating from Docker Compose to Kubernetes, the conversion from labels to IngressRoute CRDs is mechanical
  3. All resilience features built-in — circuit breaker, rate limiting, retry, health checks work out of the box without plugins or external dependencies
  4. Prometheus metrics and dashboard are built-in — no additional exporters or sidecars needed
  5. Operational simplicity — the entire gateway configuration fits in a single traefik.yml file plus Docker labels on each service

The performance gap (19k vs 42k RPS for HAProxy) is acceptable at BANA's current scale. If performance becomes a bottleneck, HAProxy can be considered as a future L4 load balancer in front of Traefik.

DocumentDescription
Gateway OverviewIdentity card + service catalog
ArchitectureC4 views, request-routing flows
RoutingDocker label routing, 3 routing patterns
ADR-0001Traefik label-based dynamic routing decision
DecisionsAll ADRs

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.