Kong vs Tyk vs Envoy for microservices
Choosing between Kong Gateway, Tyk, and Envoy Proxy is rarely about raw throughput — all three handle tens of thousands of requests per second on commodity hardware. The real divergence appears in three operational dimensions: how each gateway is configured and version-controlled, how it handles gRPC and HTTP/2 natively, and how its failure-recovery primitives — circuit breakers, retry budgets, outlier detection — integrate with your upstream topology. Getting this choice wrong at service-mesh inception means either a painful migration later or a gateway that becomes the bottleneck in your resilience story.
Prerequisite concepts
This comparison assumes familiarity with gateway selection criteria — specifically capability matrices for data-plane vs control-plane separation — and with the broader API gateway fundamentals and architecture that governs how gateways sit relative to upstream services. If you are evaluating gRPC specifically, read protocol translation patterns first, as the gRPC-to-REST translation overhead discussed below has its own architectural implications.
Execution model: how each gateway processes a request
Kong relies on an Nginx core extended via LuaJIT, executing routing logic in a worker-per-core model. Plugin phases (access, header_filter, body_filter, log) are synchronous with the request lifecycle — policy decisions happen in LuaJIT before the proxy hop. Tyk is written in Go, using a goroutine scheduler that handles concurrent streams in a single-process architecture; middleware runs inline in the same goroutine as the request handler, making it straightforward to write custom plugins in Go without a separate IPC channel. Envoy operates as a C++ proxy using an event-driven reactor pattern with epoll, optimised for asynchronous I/O and zero-copy networking. Routing policy is delegated to xDS-compliant control planes, enabling hot-reloading of routing tables without dropping active connections.
Declarative routing syntax
Path-based routing with header rewriting requires precise, version-controllable configuration. Below are production-ready snippets for each gateway targeting the same upstream service.
Kong 3.x (db-less YAML)
_format_version: "3.0"
services:
- name: user-service
url: http://user-svc:8080
routes:
- name: user-route
paths: ["/api/v1/users"]
strip_path: true
plugins:
- name: request-transformer
config:
add:
headers: ["X-Internal-Source:api-gateway"]
Kong’s declarative YAML is GitOps-native: deck sync applies the diff, and deck diff previews changes in CI without a running gateway. The strip_path: true flag removes the matched prefix before forwarding, which is the most common source of 404s when migrating monolith routes.
Tyk 5.x (JSON API definition)
{
"name": "user-service",
"api_id": "user_svc_01",
"proxy": {
"listen_path": "/api/v1/users/",
"target_url": "http://user-svc:8080/",
"strip_listen_path": true
},
"version_data": {
"not_versioned": true,
"default_version": "default",
"versions": {
"default": {
"global_headers": {
"X-Internal-Source": "api-gateway"
}
}
}
}
}
Tyk’s JSON definition aligns with its REST management API. The global_headers block injects headers on every request before forwarding to the upstream. Tyk also supports global_headers_remove to strip inbound headers from untrusted clients — important for zero-trust security boundaries.
Envoy 1.32+ (static xDS YAML)
static_resources:
listeners:
- name: ingress_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
route_config:
name: local_route
virtual_hosts:
- name: user_service
domains: ["*"]
routes:
- match: { prefix: "/api/v1/users" }
route:
cluster: user_cluster
prefix_rewrite: "/"
request_headers_to_add:
- header:
key: "X-Internal-Source"
value: "api-gateway"
keep_empty_value: false
Envoy’s xDS structure gives the most granular control but requires strict schema validation in CI/CD pipelines. The @type URL must exactly match the installed Envoy version’s proto registry — a mismatch produces a silent no-op rather than an error in some control-plane implementations.
Circuit breaker and retry logic
Preventing cascading 503s during upstream latency spikes requires strict error thresholds, consecutive failure limits, and half-open probe intervals. The three gateways express these concepts through fundamentally different abstractions.
Kong: Uses the circuit-breaker plugin (Kong Gateway Enterprise or community plugin). Configuration lives in the plugin object attached to a service:
plugins:
- name: circuit-breaker
config:
threshold: 50 # error percentage to open circuit
timeout_sec: 10 # half-open probe interval
window_size: 60 # rolling window in seconds
Kong’s circuit breaker state is local to each worker process by default. Under multi-worker deployments, circuit state diverges across workers unless you enable the cluster_events bus and a Redis-backed shared dictionary.
Tyk: Defines thresholds inline in the API definition under circuit_breaker:
{
"circuit_breaker": {
"threshold_percent": 0.5,
"samples": 100,
"return_to_service_after": 10
}
}
threshold_percent is a ratio (0.5 = 50%), and samples sets the minimum observation window before the breaker evaluates state. Because Tyk is single-process, circuit state is consistent across all goroutines within one instance — but requires external coordination across multiple Tyk nodes.
Envoy: Combines outlier_detection at the upstream level with retry_policy at the route level. This separation is Envoy’s key design advantage: outlier detection ejects individual upstream hosts from the load-balancing set rather than opening a global circuit:
clusters:
- name: user_cluster
outlier_detection:
consecutive_5xx: 3
interval: 10s
base_ejection_time: 30s
circuit_breakers:
thresholds:
- max_connections: 1024
max_pending_requests: 512
max_retries: 10
route_config:
virtual_hosts:
- routes:
- match: { prefix: "/" }
route:
cluster: user_cluster
retry_policy:
retry_on: "5xx,reset,connect-failure"
num_retries: 2
per_try_timeout: 1s
retry_budget:
budget_percent: 20.0
min_retry_concurrency: 3
Envoy’s retry_budget field caps retry traffic as a fraction of active requests, preventing thundering-herd scenarios during partial outages. This approach is unique to Envoy and is the most operationally sound mechanism for high-availability topologies under sustained upstream degradation.
Protocol translation and gRPC handling
Protocol translation overhead varies significantly across implementations.
Envoy natively speaks gRPC over HTTP/2: it handles grpc-status codes, grpc-message trailers, and content-type: application/grpc negotiation in its C++ core without any plugin. Health-check probes can use grpc.health.v1.Health/Check directly. For gRPC-to-REST translation at scale, Envoy’s grpc_json_transcoder filter performs protobuf-to-JSON conversion without a sidecar.
Kong requires the grpc-gateway plugin (for gRPC upstream with REST ingress) or the grpc-web plugin (for browser gRPC clients). Both plugins operate in the LuaJIT access phase and add measurable overhead at high QPS — typically 2–5 ms additional latency per request on a loaded instance.
Tyk’s gRPC support routes HTTP/2 frames transparently but does not perform transcoding natively. JSON-to-protobuf conversion requires a custom plugin written in Go or a sidecar proxy upstream of Tyk.
For authentication proxying and token validation on gRPC streams, JWT validation latency is lowest in Envoy due to compiled C++ crypto libraries. Kong’s jwt plugin and Tyk’s jwt middleware execute in interpreted or managed runtimes, adding 0.5–2 ms per validation depending on key size.
Connection pool tuning and capacity planning
Connection pool exhaustion is the primary failure mode during latency spikes, not CPU saturation.
- Kong: The
upstreamobject controlsslots,hash_on, andkeepalivepool size. Defaultkeepaliveis 60. Setmax_failsto3andfail_timeoutto10s. Under 10k+ RPS, Kong’s LuaJIT overhead manifests as increased CPU utilisation during plugin execution — profile withwrkbefore production rollout. See scaling limits and capacity planning for upstream thread pool sizing guidance. - Tyk: Uses
max_idle_connections,max_idle_connections_per_host, andresponse_timeoutin the upstream configuration block. Tunemax_idle_connections_per_hostto match upstream thread pool capacity (typically 100–500 per instance). Go GC pauses during burst traffic are mitigated by settingGOGC=200and pre-allocating connection pools at startup. - Envoy: Cluster definitions expose
max_connections,max_pending_requests,max_retries, andhttp2_protocol_options.max_concurrent_streams. Envoy’s zero-copy networking and epoll-based reactor maintain linear memory scaling under high concurrency — monitorenvoy_cluster_upstream_cx_activeandenvoy_cluster_upstream_rq_pending_activeas early saturation signals.
Horizontal scaling requires stateless control-plane replication with consistent hashing for sticky sessions. Expose Prometheus metrics (kong_upstream_latency_ms, tyk_request_duration_seconds, envoy_cluster_upstream_latency_ms), OpenTelemetry distributed traces, and structured JSON access logs for post-mortem analysis.
Decision matrix
| Criterion | Kong 3.x | Tyk 5.x | Envoy 1.32+ |
|---|---|---|---|
| Routing config format | Declarative YAML, GitOps-native (deck) |
JSON API definition, UI or CLI | xDS YAML/Protobuf, strict schema |
| Plugin / middleware | Lua phases, large catalogue | Go functions, easy custom authorship | C++ filter chain, Wasm extensions |
| Circuit breaker | Plugin-based, per-worker state | Inline JSON, per-process state | Outlier detection + retry budget (host-level) |
| gRPC / HTTP/2 | Plugin-mediated, moderate overhead | Transparent proxy, no transcoding | Native: zero-copy, trailers, transcoder filter |
| Control plane needed | Built-in (Kong Manager / Admin API) | Built-in (Tyk Dashboard) | External (Istio, Gloo, custom xDS server) |
| Best fit | REST APIs, GitOps teams, plugin ecosystem | Mixed REST/gRPC, Go-native teams | gRPC-heavy, service mesh, performance-critical |
For monolith-to-microservice migrations, Kong or Tyk provide lower initial configuration friction and familiar HTTP routing patterns. Greenfield gRPC-heavy architectures should default to Envoy for native protocol support and deterministic retry budgets. If your team has no prior service-mesh experience, Envoy’s dependency on an external control plane is the largest operational cost to budget for.
Gotchas and failure signals
Kong: If strip_path is misconfigured and the upstream does not expect the gateway prefix in the URL, you will see consistent 404s from upstreams that are otherwise healthy. The circuit breaker plugin’s per-worker state divergence under multi-worker deployments causes asymmetric open/closed states — monitor kong_upstream_target_health per worker PID to detect this. The deck sync command in CI will succeed even if the gateway is unreachable when --skip-ca-certificates is set — never suppress TLS validation in pipelines.
Tyk: The return_to_service_after timer in the circuit breaker starts from the moment the circuit opens, not from the last failure — this means a brief upstream recovery can cause the half-open state to be skipped if the timer expires while the upstream is still flapping. JSON API definitions are not validated on load in Tyk OSS; a missing "proxy" block produces a running but non-functional API with no error log.
Envoy: Listener drain on SIGTERM waits for drain_time_s (default 600 s) before rejecting new connections — set this to a value matching your upstream health check interval, or rolling deployments will stall. The consecutive_5xx outlier detector counts only exact 5xx responses, not connection resets or timeouts; configure consecutive_gateway_failure separately to eject hosts that time out without returning an HTTP status.
Validation checklist
- Routing config is stored in version control and applied via CI (not manual admin API calls)
- Circuit breaker thresholds tested against a controlled upstream fault injection (e.g.
tc netem delay 500ms) - gRPC
content-type: application/grpctraffic verified end-to-end withgrpcurlthrough the gateway -
strip_path/strip_listen_path/prefix_rewriteconfirmed against upstream URL expectations - Connection pool limits (
max_connections,keepalive,max_idle_connections_per_host) set above baseline steady-state RPS - Retry budget or
num_retriescap validated to prevent traffic amplification during upstream degradation - Prometheus metrics scraped and dashboarded before production traffic
- Horizontal scaling tested with at least two gateway instances and upstream sticky-session behaviour confirmed
FAQ
Should I use Kong or Envoy for a gRPC-heavy microservices platform?
Envoy is the stronger choice for gRPC-heavy workloads. It handles grpc-status trailer propagation, HTTP/2 multiplexing, and content-type negotiation natively in its C++ core with no plugin overhead. Kong requires the grpc-gateway or grpc-web plugin, which adds a LuaJIT processing hop per request. If your team already operates an xDS-compatible control plane (e.g. Istio, Gloo), Envoy integrates without friction. For mixed REST/gRPC fleets where the team has no prior service-mesh experience, Kong’s simpler declarative YAML and mature plugin ecosystem are often the faster path.
What is the key operational difference between Kong’s plugin model and Tyk’s middleware?
Kong plugins execute as Lua phases (access, header_filter, body_filter, log) within an Nginx worker process, which makes them synchronous with the request lifecycle but bounded by LuaJIT memory limits. Tyk middleware runs as Go functions in the same goroutine as the request handler, offering lower memory overhead per connection and straightforward custom-plugin authorship in Go — but without Kong’s large catalogue of community plugins.
Can Envoy replace Kong or Tyk as a standalone API gateway?
Envoy is a data-plane proxy, not a full API gateway product. It lacks a built-in developer portal, out-of-the-box OAuth2/OIDC flows, and a management UI. Teams use Envoy as a gateway by pairing it with a control plane such as Istio, Gloo Edge, or Ambassador — or by writing their own xDS server. Kong and Tyk ship management planes, admin APIs, and portals out of the box, making them lower-friction choices for teams that need a complete gateway platform without building control-plane tooling.
Parent: Gateway Selection Criteria
Related
- How API Gateways Differ from Load Balancers — understand the architectural boundary before choosing a gateway product
- Implementing mTLS at the Gateway Edge — zero-trust certificate validation patterns applicable to all three gateways
- Handling gRPC-to-REST Translation at Scale — deep-dive on transcoding options when Envoy’s
grpc_json_transcoderis not sufficient