API Gateway Engineering Insights
The trade-offs, comparisons, and judgment calls — when a gateway helps, when it hurts, and how the real products (Kong, Zuul, Envoy, cloud gateways) actually differ.
Gateway vs Direct Service Access
The gateway is not free — it's a deliberate trade of one extra hop for a lot of centralised leverage.
Calling services directly is genuinely simpler when you have two services and one client — no extra component, no extra hop, nothing new to operate. The gateway earns its keep as the system grows: more services, more client types, and more cross-cutting policy that you refuse to copy-paste. The break-even point is when duplicated auth/rate-limiting/logging across services costs more than running and operating the gateway.
Direct wins
Tiny systems, internal service-to-service calls inside a trusted mesh, latency-critical hot paths where the extra hop matters.
Gateway wins
Many public clients, many services, shared policy (auth, limits, versioning), and a need for one control point and one observation point.
API Gateway vs Load Balancer — When You Use Both
The real design question is not "which one wins?" but which layer should own which decision.
If one public endpoint only needs to spread traffic across replicas of a single backend tier, a load balancer is enough. Introduce a gateway when the same entry point must front many services or enforce shared API policy. Most internet-facing microservice systems use both. For balancing mechanics, see Load Balancer Fundamentals.
| Question | Load balancer answer | Gateway answer |
|---|---|---|
| Primary decision | Which healthy instance in this tier should handle the request? | Which service/route should handle the request, and which API policies apply? |
| Enough on its own when | Clients already know the service and you just need scale/HA for that tier. | Clients need one API surface across many services or one place for auth, limits, and versioning. |
| Typical placement | In front of service replicas or in front of a gateway cluster. | At the API edge in front of multiple services. |
| How they compose | External LB spreads traffic across gateway instances or service replicas. | Gateway can then route to services that are themselves load-balanced or discovered dynamically. |
- 01Load balancer: one service, many replicas, 'which replica?'.
- 02API gateway: many services, per-request policy, 'which service and is it allowed?'.
- 03Use both when you need a stable API edge and per-service scale/high availability behind it.
Centralized vs Decentralized Authentication
Putting auth at the gateway is powerful and slightly dangerous — you gain consistency but create a trust boundary you must defend.
Centralized auth at the gateway means one implementation, one place to fix bugs, and services that trust an already-verified identity header. The risk is the confused-deputy / trust boundary problem: if a request can reach a service without passing the gateway (e.g. via internal network), and the service blindly trusts the identity header, an attacker who bypasses the gateway is trusted. The mitigation is network policy (services only accept traffic from the gateway) or signed identity tokens the service re-verifies.
Decentralized auth (each service verifies the token itself) removes the single trust boundary but reintroduces the duplication the gateway was meant to kill. The common hybrid: the gateway does coarse authentication and rejects obvious bad tokens, while sensitive services still re-verify a signed token for defence in depth.
Aggregation vs Multiple Client Calls
Fewer round trips for the client, but a fatter, more coupled gateway — this one's a real judgment call.
Aggregation shines for high-latency clients (mobile on cellular) where each round trip is expensive: one call, parallel fan-out, one response. But it moves response-shaping logic into the edge, couples the gateway to backend schemas, and makes the gateway a bigger, more stateful thing to reason about. Over-aggregation turns your gateway into a monolith with extra steps.
Aggregate when
Chatty mobile/web screens, high per-round-trip latency, a stable BFF-style response shape per client.
Let the client call when
Low-latency clients, rapidly changing needs (GraphQL may fit better), or when coupling the gateway to backend shapes is too costly.
Simplicity vs Latency — The Extra Hop
Every request now pays for one more network hop and one more thing that can fail — is the centralisation worth it?
The gateway adds work on every request, but the cost depends on what the gateway actually does. A thin self-hosted gateway on the same network may add roughly sub-millisecond to low-single-digit milliseconds (illustrative; it varies with hardware, TLS, plugins and load); cross-zone hops, token introspection, large body transforms, aggregation, or managed-gateway control paths can add noticeably more. It also adds an availability dependency — if the gateway tier is down, everything behind it is effectively down. The trade is centralised policy and observability versus extra latency and a new failure domain, so measure the actual p95/p99 overhead instead of assuming it is trivial or fatal.
Latency budget
Measure the gateway's own p99 overhead and keep it a small, known fraction of the total request time.
Availability coupling
The gateway tier's SLA becomes a floor on the whole API's SLA — hence the obsession with clustering it.
Single Gateway vs Gateway Cluster
For customer-facing production APIs, the answer is usually clear — but understanding why frames the whole HA design.
A single gateway is simpler to run and reason about, and fine for a demo or an internal tool. For customer-facing production traffic it is both a single point of failure and a throughput ceiling: one process, one blast radius. The cluster answer — stateless instances behind a load balancer, shared config, and shared rate-limit state with discovery/control-plane data outside the instance — is more moving parts but the standard way to survive an instance dying and to scale past one machine.
Single
Simplest; acceptable for dev, demos, or low-stakes internal use, but not for production customer traffic.
Cluster
Stateless instances + load balancer + shared state. Standard for anything customer-facing.
Kong vs Zuul vs Cloud-Native Gateways, Mistakes & FAQs
The concepts are universal; the products differ in language, extensibility, and how much you operate yourself.
The landscape
Kong
Built on NGINX/OpenResty with a Lua plugin ecosystem. Fast, self-hosted or managed, strong plugin story for auth/rate limiting. You run the data plane.
Zuul (Netflix)
JVM-based, filter-oriented (pre/route/post filters). Zuul 2 is async/non-blocking. Spring Cloud Netflix's Zuul 1 integration is no longer in active development; Spring Cloud Gateway is the usual Spring replacement. Deeply tied to the Netflix/Spring Cloud ecosystem and Eureka discovery.
Spring Cloud Gateway / Traefik / Apache APISIX
Newer options worth knowing: Spring Cloud Gateway (reactive, JVM, the usual Spring-ecosystem choice), Traefik (Go, configuration discovered dynamically from Docker/Kubernetes providers), and Apache APISIX (NGINX/OpenResty-based with etcd-backed configuration).
Envoy
A high-performance C++ proxy that is the data plane for many gateways and meshes (e.g. Istio, Gloo). Config via xDS control plane; the modern building block.
AWS API Gateway / Apigee
Fully-managed, cloud-native. You configure routes, auth, throttling, and pay per request — the platform handles clustering, scaling, and HA for you.
Common mistakes
Business logic in the gateway
The gateway should route and enforce policy, not run domain logic. That belongs in services (or a BFF).
Per-instance rate-limit state
Guarantees wrong limits under scale-out. Use shared state.
Trusting injected identity blindly
Lock down network paths so only the gateway can reach services, or re-verify signed tokens.
One gateway instance
A single point of failure for production traffic. Cluster the data plane instead.
FAQs & real-world architectures
Gateway vs service mesh?
Gateway handles north-south (client → system) traffic and policy at the edge; a mesh handles east-west (service → service) traffic with sidecars. Large systems run both.
One gateway or many?
Often one gateway platform, sometimes a BFF gateway per client type (mobile/web/partner) so each can aggregate and version independently.
Where does TLS terminate?
Usually at the load balancer or the gateway edge; internal hops can be plain or mTLS depending on your trust model.