Decision guide
API Gateway vs BFF vs Service Mesh
Where should cross-cutting concerns and client-specific logic live?
Side by side
| Criterion | API gateway | Backend for Frontend (BFF) | Service mesh |
|---|---|---|---|
| Traffic | North-south (edge) | Client → backends | East-west (internal) |
| Main jobs | AuthN, quotas, routing, WAF | Aggregation, shaping, client auth flows | mTLS, retries, timeouts, telemetry |
| Owned by | Platform team | Client/product team | Platform team |
| Business logic | None | Presentation/aggregation only | None |
| Examples | Kong, Envoy Gateway, Apigee, AWS API Gateway | Node/Go/Kotlin service per app | Istio, Linkerd, Cilium |
When to choose each
API gateway
Edge proxy for external traffic: TLS, auth, rate limits, routing.
Choose when
- External/north-south traffic
- Central rate limiting and key management
- Routing and canaries
Avoid when
- Client-specific aggregation
- Business logic
Backend for Frontend (BFF)
A service per client type that aggregates and shapes data.
Choose when
- Web and mobile need different payloads
- Reducing chatty mobile calls
- Keeping tokens server-side for browser apps
Avoid when
- One generic client
- Shared BFF for every client (defeats the purpose)
Service mesh
Sidecar/ambient proxies for internal traffic: mTLS, retries, telemetry.
Choose when
- Many internal services needing mTLS and uniform telemetry
- Zero-trust east-west traffic
Avoid when
- Few services (operational overhead)
- External API concerns like API keys and developer portals
Verdict
They're complementary: a gateway at the edge, BFFs owned by client teams behind it, and (if you have many services) a mesh for internal traffic. Avoid putting business logic in gateways or meshes, and avoid a single BFF shared by all clients.