API Design

Backend for Frontend (BFF)

A pattern that creates a dedicated backend service per user interface type — one BFF for mobile, one for web, one for third-party — enabling each UI team to own the aggregation, transformation, and response shaping logic tailored to their client's exact needs.

⏱ 11 min read

What it is

The Backend for Frontend (BFF) pattern, coined by Sam Newman, is an architectural pattern where you create a separate backend service for each distinct frontend or client type. Instead of a single general-purpose API consumed by all clients, each client type (mobile app, single-page web application, third-party partners, voice assistants) has its own dedicated backend that provides exactly the data shapes and protocols that client needs.

The BFF sits between the API gateway and the downstream microservices. It aggregates calls to multiple services, transforms data into the shape the UI needs, applies client-specific business rules, and returns a single, optimised response. The BFF is owned and deployed by the team that builds the corresponding frontend — creating end-to-end product team ownership.

Why it exists

A single generic API inevitably serves no client well. Mobile clients operating on constrained networks need minimal, flat payloads; web dashboards need rich, aggregated data across multiple domains; third-party partners have entirely different authentication and data shape requirements. A team maintaining one API for all these consumers makes every change a negotiation and every response a compromise.

Without BFFs, frontend teams are blocked by backend teams whenever they need a new field or a different response shape. With BFFs, the product team owns the full vertical slice — frontend, BFF, and the integration with downstream services — enabling faster iteration.

When to use

  • Multiple distinct client types with meaningfully different data and protocol requirements (mobile vs web vs partner).
  • Frontend teams need to iterate independently of the core service teams.
  • Aggregation of multiple microservice calls is required to assemble a single screen view.
  • Per-client optimisation is needed: mobile needs smaller payloads, web needs richer data, partner needs bulk export formats.
  • Teams are structured around product verticals (each team owns a feature end-to-end).

When not to use

  • Single client type — if you only have one frontend, a BFF is just an extra layer with no benefit; the API can serve that client directly.
  • Highly similar clients — if your mobile and web apps require essentially the same data, a BFF-per-client creates duplication without value; parameterise the single API instead.
  • Small teams — the BFF model requires the frontend team to own backend code; if the team lacks backend skills, this creates a maintenance burden.

Typical architecture

                    [API Gateway]
                   (auth, rate limit, TLS)
                  /         |          \
                 /          |           \
        [Mobile BFF]  [Web BFF]   [Partner BFF]
         (owned by    (owned by    (owned by
         mobile team) web team)    partner team)
              |             |              |
       ┌──────┴──────┐      │         ┌───┴───┐
       ▼             ▼      ▼         ▼       ▼
  [Users Svc]  [Orders Svc] [Products Svc] [Reports Svc]

Mobile BFF optimisations:
  - Aggregates user + 3 most recent orders in one call
  - Returns minimal fields (id, name, status only)
  - Caches product catalogue with short TTL
  - Converts images to mobile-appropriate sizes/formats

Web BFF optimisations:
  - Returns full order history with line items
  - Aggregates dashboard metrics from analytics service
  - Supports richer filtering and sorting options
  - Returns paginated data with cursor tokens

GraphQL as BFF alternative:
  Mobile Client → GraphQL BFF (shared)
  Web Client    → GraphQL BFF (shared)
  Each client requests exactly its required fields via query
  BFF = single GraphQL server acting as aggregation layer

Pros and cons

Pros

  • Frontend teams own their full delivery pipeline — no blocking dependencies on backend teams for response shaping.
  • Optimised payloads per client — mobile gets what it needs; web gets what it needs; no compromise.
  • Isolates client-specific complexity (session management, push notifications, OAuth flows) away from core services.
  • Each BFF can be independently deployed and scaled according to its client's traffic patterns.
  • Simplifies downstream services — they expose clean domain APIs; BFFs handle composition.

Cons

  • BFF proliferation — each new channel (watch app, TV app, voice assistant) spawns another BFF; 10 BFFs × similar logic = significant duplication.
  • Cross-cutting logic (auth token exchange, retry policies) can drift between BFFs without a shared library.
  • Frontend teams must maintain backend code, including tests, deployments, and on-call responsibilities.
  • Increased infrastructure: N BFFs = N deployable services with their own CI/CD pipelines, containers, and monitoring.
  • Aggregation logic can become complex in the BFF, approaching the complexity of a general-purpose API.

Implementation notes

Scope of the BFF

A BFF should handle: aggregating calls to multiple downstream services for a single screen, response shaping and field filtering, caching strategies specific to the client's usage patterns, and client-specific authentication flows (e.g., mobile device registration, session token management). It should not contain core business logic (pricing rules, inventory management), which belongs in domain services.

Shared library strategy

As BFFs multiply, extract common concerns into shared libraries: downstream service clients, retry/circuit-breaker logic, logging middleware, and auth token validation. Version the shared libraries carefully — a breaking change in the common client library can break all BFFs simultaneously. Consider a monorepo to keep BFFs and shared libraries in sync.

GraphQL as a BFF

GraphQL is a natural fit for the BFF role: the schema defines the available data graph, resolvers aggregate downstream service calls, and clients query exactly the fields they need. A single GraphQL BFF can serve both mobile and web clients with different query shapes rather than running two separate BFFs. Trade-off: the BFF becomes more complex to maintain (schema evolution, resolver optimisation), but the client-flexibility benefit is high. Apollo Federation extends this to multiple subgraph-owning teams.

Team ownership model

The BFF model works best when aligned with Conway's Law: the team that builds the web frontend owns the web BFF. This means the frontend team needs full-stack capability (JavaScript/TypeScript Node.js BFFs are a natural fit for web teams). Mobile teams typically own their BFF in the same language as their backend lingua franca (Node.js, Go, Java). Establish clear boundary contracts between the BFF and downstream services — the BFF must treat those services as external dependencies, not internal code to modify.

BFF proliferation control

To avoid a BFF-per-feature sprawl: (1) merge BFFs that serve very similar clients (e.g., iOS and Android into one "mobile BFF"), (2) promote a shared "experience API" for common functionality across BFFs, or (3) adopt GraphQL Federation so all client-specific queries route to a single shared supergraph. Set a policy: a new BFF must be justified by meaningfully different requirements, not just a different team preference.

Common failure modes

  • BFF as a pass-through proxy — the BFF simply forwards requests with no aggregation or transformation; this is overhead without value; use the API gateway directly instead.
  • Business logic migration — pricing, discount, and eligibility rules gradually migrate into BFFs; they become domain services in disguise without the governance.
  • Synchronous fan-out without timeout — a BFF that calls 6 services sequentially will be as slow as the slowest service; use parallel calls with aggregate timeouts.
  • No contract between BFF and downstream services — BFF breaks every time a downstream service changes its response shape; use contract testing.
  • Undifferentiated BFFs — building a separate BFF for iOS and Android that contain identical logic; merge them into a single mobile BFF.

Decision checklist

  • Is there a genuinely different data requirement between client types that justifies a dedicated BFF?
  • Does the owning team have the skills to maintain backend code?
  • Are downstream service calls made in parallel where possible, not sequentially?
  • Is core business logic excluded from the BFF (in downstream domain services)?
  • Are contract tests in place between the BFF and each downstream service?
  • Is there a shared library for common infrastructure concerns (retry, auth, logging) across all BFFs?
  • Is GraphQL being considered as a single flexible BFF alternative to multiple BFFs?
  • Is there a policy to prevent uncontrolled BFF proliferation?

Example use cases

  • Streaming platform — mobile BFF returns compressed thumbnails, minimal metadata, and offline download tokens; web BFF returns full resolution images, extended credits, and social sharing metadata; TV BFF returns HDMI-optimised assets and remote-control-friendly navigation structures.
  • Banking application — retail mobile BFF handles touch-ID auth flow and push notification registration; branch teller web BFF handles high-detail transaction history and account management; open banking partner BFF handles OAuth2 consent flows and bulk data exports.
  • E-commerce — the web BFF aggregates product details, pricing, inventory, and reviews in a single call; the mobile BFF returns a stripped-down product card suitable for list rendering on small screens with a separate detail call on demand.
  • API Gateway — the gateway sits in front of BFFs and handles cross-cutting concerns.
  • GraphQL — a single GraphQL BFF can replace multiple REST BFFs.
  • REST API Design — BFF exposes a REST API optimised for its client.

Further reading

  • Sam Newman — Backends for Frontends (original pattern description, samnewman.io).
  • Sam Newman — Building Microservices (2nd ed., chapter on user interfaces and BFFs).
  • Phil Calçado — Pattern: Backends for Frontends (soundcloud.com engineering blog, 2015).
  • ThoughtWorks Technology Radar — BFF entries across multiple editions.