Back to the map

Module 12 · Microservices patterns · Lesson 3 of 8

Backend for frontend

One backend per client type, owned by the client team, that composes the services into exactly the shape each screen needs. Why a single general API serves every client badly, what a BFF does and does not do, GraphQL as an alternative.

CoreShould-knowMid 10 minPro Updated Nov 2026

Why it matters

A mobile home screen wants a compact payload with the five things it shows; the web dashboard wants a rich one; a smart TV wants something else again; and a partner integration wants stable, documented resources. One general-purpose API serves all of them a compromise: too much for mobile, too little for web, and every client change becomes a negotiation with the backend team. The backend-for-frontend pattern gives each client its own thin backend, owned by the people who build that client. It is the structured answer to the aggregation problem that gateways should not solve.

The idea

A backend for frontend (BFF) is a service dedicated to one client type (web app, iOS and Android app, TV app, partner API). It receives that client's requests, calls the downstream services in parallel, composes and shapes the results into exactly what the client's screens need, and returns them. It is owned by the client team, so a screen change is a change in one repository rather than a cross-team request.

MobileWebMobile BFFWeb BFFordersusersrecommendationsmobile BFF: one call → 3 KB; web BFF: one call → 40 KB with details
Each client talks to its own BFF, which composes the shared services into client-shaped responses. Business logic stays in the services; the BFF owns only shaping.

What a BFF does

  1. 1

    Composition

    Fan out to several services in parallel, with timeouts and fallbacks per call, and merge results into one response. A slow recommendations service degrades to an empty strip, not a failed screen.
  2. 2

    Shaping

    Return exactly the fields and structure the screen renders, in the client's preferred format, with formatting already applied where that simplifies the client.
  3. 3

    Client-specific protocol

    Mobile may want long-lived connections and push; web may want server-sent events; a TV may need tiny payloads. The BFF speaks each client's dialect.
  4. 4

    Caching close to the client

    Cache composed responses per user segment where freshness allows, reducing fan-out load on services.
  5. 5

    Session and client auth

    Hold the client's session or token exchange, so the client never handles service-level credentials.

What a BFF must not do

Own business rules. If the mobile BFF decides whether a discount applies and the web BFF decides differently, the business has two truths. Pricing, eligibility, validation and invariants live in the owning services; BFFs call them. Write to data directly: a BFF never touches a service's database. Become shared: a BFF serving several clients is a general API with the problems the pattern exists to solve. The test is whether a rule changed in one BFF would need changing in another; if so, it belongs downstream.

BFF versus GraphQL

 Backend for frontendGraphQL gateway
Who defines the shapeThe client team, in server code per screenThe client, per query, from a shared schema
FlexibilityFixed endpoints per screen; changes are deploysAny shape within the schema; no backend deploy for new screens
Operational complexityN small services, each simpleOne schema with resolvers, data loaders, cost limits, caching challenges
FitFew client types with distinct needs; teams that own full stackMany clients and screens over one connected graph; strong front-end teams
CombineA GraphQL BFF per client is a common hybrid

The API module's GraphQL lesson covers the trade-offs; a BFF that exposes GraphQL to its one client gets both the ownership model and query flexibility.

Operating BFFs

Each BFF is a service: deployed independently, observed with traces that span its fan-out, protected with circuit breakers per downstream and with its own rate limits. Keep them thin and stateless. Share client libraries for the downstream services so that composition code is small. Watch for drift: as BFFs multiply, make sure shared concerns (auth validation, logging) come from a platform library rather than being reimplemented in each.

Backend for frontend · Backplane