API Gateway Comparison: Kong vs Envoy vs AWS API Gateway
Every microservices architecture needs an API gateway comparison before committing to one, because the gateway is the single entry point that handles routing, authentication, rate limiting, and observability for all your services. Choosing between Kong, Envoy, and AWS API Gateway is a consequential decision that affects performance, operational complexity, and vendor lock-in for years. Therefore, this guide breaks down each option’s strengths, weaknesses, and ideal use cases with practical configuration examples — and an honest look at where each one will frustrate you.
What an API Gateway Actually Does
An API gateway sits between clients and your backend services, handling cross-cutting concerns that every API needs: request routing (directing traffic to the right service), authentication and authorization (validating tokens and API keys), rate limiting (protecting services from overload), request and response transformation (header manipulation, body mapping), load balancing, circuit breaking, and observability (metrics, logging, tracing).
Without a gateway, each service implements these concerns independently — which leads to inconsistent security policies, duplicated code, and no central place to monitor API traffic. Moreover, the gateway provides a stable external interface even as your internal service topology changes. Clients talk to the gateway; the gateway routes to services. Consequently, you can refactor, split, or merge services without changing client code. It is worth distinguishing two roles here, however: a north-south gateway handles traffic entering from outside, while an east-west proxy handles service-to-service calls inside the mesh. Kong and AWS API Gateway are firmly north-south tools, whereas Envoy spans both.
Kong: The Plugin-Powered Gateway
Kong is built on Nginx and OpenResty (LuaJIT), combining Nginx’s battle-tested performance with a flexible plugin architecture. It is the most feature-rich open-source gateway in this comparison and the easiest to extend with custom plugins.
# Kong declarative configuration (kong.yml)
_format_version: "3.0"
services:
- name: user-service
url: http://user-service:8080
routes:
- name: user-api
paths:
- /api/v1/users
strip_path: false
plugins:
- name: rate-limiting
config:
minute: 100
policy: redis
redis_host: redis
- name: jwt
config:
claims_to_verify:
- exp
- name: cors
config:
origins: ["https://myapp.com"]
methods: ["GET", "POST", "PUT", "DELETE"]
headers: ["Authorization", "Content-Type"]
- name: prometheus
config:
per_consumer: true
- name: order-service
url: http://order-service:8080
routes:
- name: order-api
paths:
- /api/v1/orders
plugins:
- name: rate-limiting
config:
minute: 50
- name: request-transformer
config:
add:
headers:
- "X-Request-ID:$(uuid)"
Kong strengths: an extensive plugin ecosystem with hundreds of plugins, an excellent admin API for dynamic configuration, support for both declarative (DB-less) and database-backed modes, and mature enterprise features. Kong weaknesses: higher memory usage than Envoy, a smaller Lua plugin-development community than mainstream languages, and an enterprise tier that gets expensive. Additionally, Kong’s Admin API allows runtime configuration changes without restarts — you can add routes, enable plugins, and update rate limits while the gateway is serving traffic, which is valuable for teams that need to respond quickly to changing requirements.
Rate Limiting Done Right: Why the Policy Field Matters
One detail in the Kong config above carries outsized importance: policy: redis on the user-service rate limiter, versus the bare in-memory limiter on order-service. This distinction trips up many teams. The default local policy counts requests per Kong node, so if you run three replicas behind a load balancer, your “100 requests per minute” limit silently becomes 300 — each node enforces its own counter in isolation.
# Cluster-correct rate limiting across N Kong replicas
plugins:
- name: rate-limiting
config:
minute: 100
policy: redis # shared counter, accurate cluster-wide
redis_host: redis
redis_port: 6379
fault_tolerant: true # allow traffic if Redis is briefly down
hide_client_headers: false
The redis policy keeps one shared counter, so the limit holds no matter how many nodes you scale to. The trade-off is a network hop to Redis on every counted request, which adds a small amount of latency and makes Redis a dependency on the hot path — hence fault_tolerant: true, which lets requests through rather than failing closed if Redis blips. This same local-versus-shared problem exists in every gateway: AWS API Gateway handles it for you, while Envoy needs an external rate-limit service for exactly this reason.
Envoy: The Cloud-Native Proxy
Envoy is a high-performance C++ proxy designed for cloud-native architectures. It is the backbone of service meshes like Istio and Linkerd, and it excels at advanced traffic management, observability, and protocol support. Envoy is more a programmable proxy than a traditional API gateway — it is extremely powerful but requires more configuration effort up front.
# Envoy configuration (envoy.yaml)
static_resources:
listeners:
- name: api_listener
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.
filters.network.http_connection_manager.v3.
HttpConnectionManager
stat_prefix: api_gateway
route_config:
name: local_routes
virtual_hosts:
- name: api
domains: ["*"]
routes:
- match:
prefix: "/api/v1/users"
route:
cluster: user-service
timeout: 5s
retry_policy:
retry_on: "5xx,reset"
num_retries: 3
- match:
prefix: "/api/v1/orders"
route:
cluster: order-service
timeout: 10s
http_filters:
- name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.
filters.http.ratelimit.v3.RateLimit
domain: api_gateway
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: rate_limit_service
- name: envoy.filters.http.router
clusters:
- name: user-service
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: user-service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: user-service
port_value: 8080
health_checks:
- timeout: 2s
interval: 10s
unhealthy_threshold: 3
healthy_threshold: 2
http_health_check:
path: /health
Envoy strengths: the lowest latency and highest throughput of the three thanks to its C++ core, native gRPC and HTTP/2 support, built-in circuit breaking and outlier detection, L4 and L7 protocol support, and the xDS API for dynamic configuration from a control plane. Envoy weaknesses: verbose YAML configuration, a steeper learning curve, reliance on external services for features Kong includes built-in (auth, rate limiting), and harder extensibility — you write C++ or WASM filters rather than Kong’s Lua plugins.
AWS API Gateway: The Managed Option
AWS API Gateway eliminates operational overhead entirely — there are no servers to manage, no scaling to configure, and no patches to apply. It integrates natively with AWS services like Lambda, IAM, Cognito, and CloudWatch, and it offers two variants: REST API (feature-rich, with WebSocket support) and HTTP API (simpler, cheaper, and faster).
# AWS SAM template for API Gateway
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
ApiGateway:
Type: AWS::Serverless::HttpApi
Properties:
StageName: prod
CorsConfiguration:
AllowOrigins: ["https://myapp.com"]
AllowMethods: ["GET", "POST", "PUT", "DELETE"]
AllowHeaders: ["Authorization", "Content-Type"]
Auth:
DefaultAuthorizer: CognitoAuthorizer
Authorizers:
CognitoAuthorizer:
AuthorizationScopes:
- email
IdentitySource: "$request.header.Authorization"
JwtConfiguration:
issuer: !Sub "https://cognito-idp.us-east-1.amazonaws.com/${UserPool}"
audience:
- !Ref UserPoolClient
UserFunction:
Type: AWS::Serverless::Function
Properties:
Handler: handlers/users.handler
Runtime: nodejs20.x
Events:
GetUsers:
Type: HttpApi
Properties:
ApiId: !Ref ApiGateway
Path: /api/v1/users
Method: GET
CreateUser:
Type: HttpApi
Properties:
ApiId: !Ref ApiGateway
Path: /api/v1/users
Method: POST
AWS API Gateway strengths: zero operational overhead, automatic scaling, native AWS integration, built-in usage plans and API keys, and WebSocket API support. AWS API Gateway weaknesses: meaningful vendor lock-in, higher per-request latency than self-hosted options, costs that can spike with high traffic (priced per million requests plus data transfer), less customization than Kong or Envoy, and a hard 30-second integration timeout that makes long-running synchronous calls impossible.
REST API vs HTTP API: Choosing the Right Variant
The single most common AWS API Gateway mistake is reaching for REST API by default when HTTP API would do. HTTP API was introduced as a leaner successor for the common case, and the AWS docs note it can be substantially cheaper while delivering lower latency. Therefore, the decision deserves a moment of thought rather than copy-pasting last project’s template.
Choose HTTP API (default for most workloads) when:
+ Proxying to Lambda or any HTTP backend
+ JWT auth via Cognito / OIDC is enough
+ You want the lowest cost and latency
Choose REST API only when you actually need:
+ API keys + usage plans for monetized/partner APIs
+ Request/response validation and mapping templates
+ Private endpoints via VPC + resource policies
+ AWS WAF integration or edge-optimized CloudFront
+ Caching at the gateway tier
In short, start with HTTP API and upgrade to REST API only when a specific feature forces your hand. Reaching for REST API reflexively means paying more for capabilities you may never use — the kind of avoidable cost that compounds quietly as traffic grows.
Performance, Cost, and the Honest Trade-offs
On raw performance, the ordering is well established: Envoy’s C++ data plane sets the latency floor, Kong on Nginx sits a small step behind, and AWS API Gateway adds the most per-request overhead because requests traverse the managed AWS fabric. For most CRUD applications that difference is negligible against database time; for latency-sensitive, high-fan-out, or gRPC-heavy systems it is decisive. Always benchmark with your own payloads, since published numbers rarely match real traffic shapes.
Cost models differ in kind, not just degree. AWS API Gateway is pure pay-per-request with no idle cost, which is ideal for spiky or low-volume APIs and punishing at sustained high volume. Kong and Envoy are self-hosted, so you pay for compute and the engineers who operate them whether traffic flows or not — cheaper per request at scale, but only once you absorb the operational burden. That operational burden is the real hidden cost: someone must patch CVEs, manage upgrades, run the Redis or rate-limit service, and stay on call. A managed gateway trades flexibility and money for never getting paged about the gateway itself.
When NOT to Add a Gateway at All
It is worth saying plainly: not every system needs a dedicated API gateway, and adding one prematurely is its own anti-pattern. For a small application with one or two services, a gateway introduces an extra hop, an extra deployment, and an extra failure domain in exchange for features you are not yet using — your framework’s built-in middleware or a simple reverse proxy may be entirely sufficient. Similarly, if you already run a service mesh, the mesh’s ingress (typically Envoy-based) may cover your north-south needs, making a second standalone gateway redundant. Introduce the gateway when the cross-cutting concerns genuinely repeat across services, not before.
To summarize the selection: choose Kong when you need a feature-rich gateway with minimal custom development, prefer declarative configuration, want freedom to run on any infrastructure, and value the plugin ecosystem — it is the best all-around choice for most teams. Choose Envoy when you need the absolute lowest latency, are building or already run a service mesh, need advanced traffic management like canary and fault injection, or have gRPC-heavy workloads. Choose AWS API Gateway when you are all-in on AWS, your APIs are serverless and Lambda-backed, traffic is moderate, or you need rapid prototyping without any infrastructure to manage.
Related Reading:
- Saga Pattern for Distributed Transactions
- Event-Driven Architecture Guide
- gRPC and Protobuf for Microservices
Resources:
In conclusion, there is no universal best gateway, and this API gateway comparison deliberately resists naming one. The right choice depends on your infrastructure, team expertise, and requirements: Kong offers the best balance of features and simplicity, Envoy delivers unmatched performance for cloud-native architectures, and AWS API Gateway eliminates operations entirely at the cost of flexibility. Evaluate based on your specific traffic patterns, latency budget, cost model, and operational capacity — then benchmark before you commit.