“BFF vs API Gateway” is one of the most confused matchups in microservices architecture. The two patterns look similar on a diagram. Both sit in front of your services. Both take a client request and hand it off to backends. So teams assume they are competing choices, pick one, and end up cramming the wrong responsibilities into it.
They are not competitors. A Backend for Frontend (BFF) and an API gateway solve different problems, are owned by different teams, and very often run together in the same system. The BFF sits behind or alongside the gateway, not instead of it.
This guide draws the line cleanly. You will learn what each pattern actually is, where they overlap, when to use one or both, and the mistakes that come from blurring them. Throughout, the API contract is the constant: whether a request flows through a gateway, a BFF, or both, each layer exposes an API you still have to design, test, mock, and document.
What Is an API Gateway?
An API gateway is a centralized entry point that sits between clients and your backend services. Every request comes in through the gateway, which applies a consistent set of cross-cutting concerns before routing the call onward.
Those concerns are the same for every client and every service:
- Routing: match an incoming path to the right upstream service.
- Authentication and authorization: validate tokens, reject unauthorized callers.
- Rate limiting and throttling: protect backends from overload and abuse.
- Observability: log requests, emit metrics, trace calls across services.
- TLS termination, caching, and request transformation: handle the plumbing once, in one place.
The gateway’s defining trait is that it is general purpose and centrally owned. A platform or infrastructure team runs it, and it serves all clients equally. It does not care whether the caller is a mobile app, a web SPA, or a partner integration; it applies the same policies to everyone.
This makes the gateway the natural home for organization-wide rules. If you want every request authenticated the same way, or every API rate limited consistently, the gateway enforces it without each service reimplementing the logic. For how this differs from broader platform tooling, see API management vs API gateway.
What Is a Backend for Frontend (BFF)?
A Backend for Frontend, introduced by Sam Newman, flips the orientation. Instead of one general-purpose backend serving every client, you build one backend per user experience. The web app gets a web BFF. The mobile app gets a mobile BFF. Each BFF is tailored to exactly one frontend. The pattern grew out of microservices work, where a single shared backend serving many clients becomes the same kind of bottleneck a monolith does.
Newman’s rule of thumb is “one experience, one BFF.” Significantly different frontends get their own BFF; similar ones (an iOS and an Android app maintained by the same team) can share one.
The defining trait here is ownership and shape. A BFF is “tightly coupled to a specific user experience, and will typically be maintained by the same team as the user interface,” in Newman’s words. The frontend team owns its BFF. They evolve the client and its backend together, without waiting on a separate backend team to approve every change.
What does a BFF actually do? It shapes data for one client:
- Aggregation: a mobile screen needs data from five microservices. The mobile BFF calls all five and returns one combined response, so the phone makes one round trip instead of five.
- Trimming and reshaping: the mobile client only needs three fields out of forty. The BFF strips the rest to save bandwidth.
- Client-specific formatting: the desktop app fetches multiple pages at once for a rich view; the mobile app fetches one page to stay light. Each BFF serves its client’s pattern.
The BFF is a kind of API aggregator with a personality: it composes downstream calls, but always in service of one specific frontend rather than as a neutral, shared layer.
Where BFF and API Gateway Overlap
The confusion is understandable because the two patterns share surface behaviors. Both intercept client requests. Both can route to backends. Both can call multiple services and combine results. A diagram of either looks like a box between clients and services.
The overlap is real but shallow. The difference is in intent and ownership:
- An API gateway aggregates and routes generically, for all clients, to centralize policy.
- A BFF aggregates and routes specifically, for one frontend, to optimize that client’s experience.
Microsoft’s own guidance is blunt about which jobs belong where. Cross-cutting features like monitoring, authorization, and rate limiting should be abstracted out of the BFF and handled separately by gateway-style patterns. The BFF should only hold client-specific logic. Put auth and throttling in a BFF and you have just rebuilt half a gateway, badly, and you have to do it again in every BFF you write.
So the practical boundary is this: if a responsibility is the same for every client, it belongs in the gateway. If it changes per frontend, it belongs in the BFF.
BFF and API Gateway Working Together
In real microservices systems, you rarely choose one. You run both, layered. The gateway sits at the edge. The BFFs sit behind it.
A typical request flow looks like this:
- The mobile client sends a request with its auth token.
- The API gateway validates the token, enforces rate limits, logs the request for observability, then routes it to the mobile BFF.
- The mobile BFF calls the product service, the inventory service, and the pricing service, aggregates the results, trims the payload to what the mobile screen needs, and returns one response.
- The gateway streams the response back to the client.
Microsoft’s reference architecture for this pattern does exactly that: an API management gateway handles authorization, monitoring, caching, and routing, then forwards to client-specific BFF services running as serverless functions, which call the underlying microservices.
Each layer does what it is good at. The gateway owns the policies that must be uniform. The BFF owns the shape that must be specific. The frontend team ships changes to its BFF without touching gateway config, and the platform team tightens a rate limit without redeploying any BFF.
This layering relationship is similar to how a gateway coexists with other infrastructure rather than replacing it. A gateway is not a load balancer (API gateway vs load balancer) and not a service mesh (service mesh vs API gateway) either; each handles a distinct layer of the request path, and a BFF is simply one more distinct layer. It is the same principle behind API-led connectivity: give each layer a clear job and let it do only that.
Decision Table: BFF vs API Gateway
| Question | API Gateway | BFF |
|---|---|---|
| Who owns it? | Platform / infrastructure team | The frontend team that consumes it |
| Serves whom? | All clients, uniformly | One specific frontend |
| Primary job | Cross-cutting concerns: auth, rate limiting, routing, observability | Client-specific aggregation and data shaping |
| How many do you run? | Usually one (per edge) | One per distinct user experience |
| Coupling | Loose, client-agnostic | Tight, client-specific by design |
| Change cadence | Stable, platform-governed | Fast, follows the frontend’s roadmap |
| Belongs in it | Anything identical for every client | Anything unique to one client |
Read it as a routing question for responsibilities. Same for everyone goes in the gateway. Different per frontend goes in the BFF. When a responsibility is both (you want central auth but also per-client payload shaping), that is your signal to run both layers, not to pick a side.
When to Use Which
Use an API gateway when you have multiple services and need a single, consistent place to enforce authentication, rate limiting, and routing. Almost every microservices system benefits from one. If you have more than a handful of services exposed to clients, you want a gateway before you want anything else.
Use a BFF when different clients have meaningfully different needs from the same backend, and a shared general-purpose API has become a bottleneck. Common triggers, per Microsoft’s guidance:
- A shared backend requires heavy effort to maintain because it serves competing frontends.
- You keep customizing a general-purpose backend to accommodate multiple interfaces.
- Mobile and web have genuinely divergent data and performance needs.
Skip the BFF when all your interfaces make the same or similar requests, or only one interface talks to the backend. A BFF adds a network hop, more services to deploy, and likely some code duplication across BFFs. If a single shared API serves every client well, a BFF is overhead you do not need. Microsoft notes that a GraphQL layer with per-frontend resolvers can also remove the need for a separate BFF, since clients request exactly the fields they want.
Use both when you are running microservices at scale: the gateway for uniform policy at the edge, BFFs behind it for client-specific shaping. This is the common end state, not an exotic one.
Common Mistakes
Putting auth and rate limiting in the BFF. This is the headline error. Cross-cutting concerns belong in the gateway. Duplicate them across BFFs and you get drift: the mobile BFF enforces one policy, the web BFF another, and your security posture is now inconsistent by accident.
Letting the BFF become a second monolith. A BFF is meant to be small and focused on one experience. When teams pile shared business logic into it, it grows into a general-purpose backend again and you have reintroduced the exact bottleneck the pattern was supposed to remove.
Using a gateway as a BFF. Some teams add per-client request transformation rules directly in gateway config to avoid building a BFF. This works at small scale, but the gateway is centrally owned, so now the frontend team files tickets against the platform team for every client-specific tweak. You have coupled the wrong teams.
Building a BFF when one client exists. If you have a single web app and no other client on the horizon, a BFF is premature. Ship the shared API. Add the BFF when a second, divergent client actually arrives.
Forgetting the contract. Every BFF and every gateway route exposes an API. Each one needs a defined contract, tests, and docs, the same as any other API. Skip this and your “thin” BFF layer becomes an undocumented black box that no one outside the owning team can integrate against. See what is an API contract for why this matters.
Where Apidog Fits
Whether a request flows through an API gateway, a BFF, or both, each layer exposes an API contract. Apidog is where you design, test, mock, and document those contracts. It does not build, host, or replace a gateway or a BFF; it gives you a single workspace for the API surfaces they expose.

Concretely:
- Design: model the BFF’s aggregated response or the gateway’s routed endpoints schema-first in the visual designer, then generate OpenAPI for both your frontend and backend teams to build against.
- Mock: spin up a smart mock of the BFF so the mobile team can develop their screens before the BFF’s downstream services exist. This is the API-first workflow that makes parallel frontend and backend work possible.
- Test: build automated test scenarios that hit the gateway-fronted endpoints exactly as a real client would, validating auth, status codes, and the aggregated payload shape.
- Document: publish interactive docs for each BFF and gateway route so every consuming team knows the contract without reading the implementation.
The pattern you choose is an architecture decision. The contract each layer exposes is a constant. Apidog handles the constant, so your BFFs and gateways stay designed, tested, mocked, and documented no matter how you wire them.
Try Apidog free to design and mock your BFF and gateway contracts before you write a line of backend code.
FAQ
Is a BFF a type of API gateway? No. They overlap in that both can route and aggregate, but a BFF is owned by a frontend team and tailored to one client experience, while an API gateway is centrally owned and serves all clients uniformly. A BFF typically sits behind a gateway.
Can I use a BFF without an API gateway? Yes, but you usually should not at scale. Without a gateway, each BFF has to reimplement cross-cutting concerns like auth and rate limiting, which leads to inconsistency. The gateway centralizes those so each BFF only handles client-specific shaping.
How many BFFs should I have? Follow Sam Newman’s “one experience, one BFF.” Build a separate BFF for each significantly different frontend. Similar clients maintained by the same team, such as iOS and Android apps, can share one BFF.
Does a BFF replace my API gateway? No. They are complementary layers. The gateway enforces uniform policy at the edge; the BFF shapes data for a specific client behind it. Most real microservices systems run both.
When should I not build a BFF? Skip it when all clients make similar requests, when only one client exists, or when a GraphQL layer with per-frontend resolvers already lets clients fetch exactly the data they need.
Where do auth and rate limiting belong, BFF or gateway? The gateway. These are cross-cutting concerns that should be uniform across all clients. Putting them in the BFF duplicates logic across every BFF and invites policy drift.



