Why this matters
Your web team ships a dashboard that needs forty fields. Your mobile team needs six
fields over a shaky 3G connection. Your partner's integration needs a rock-stable
contract that never changes. All three hit the same /api/everything endpoint —
and somebody's experience is suffering right now. The backend-for-frontend pattern
is the industry's answer: stop serving every client from one generic API, and give
each client type a backend shaped exactly for it.
Video: Why Backend for Frontend Is Key for Microservices • Brian Grant & Krishnan Ramanathan • GOTO 2017 — GOTO Conferences
A Morningstar case study making the business case for BFFs in microservices.
The hotel concierge
This lesson's running analogy: a grand hotel with three kinds of guests. The business traveler wants everything in one envelope, fast, before her taxi leaves. The family wants the full brochure — pool hours, kids' menus, all of it. The travel agent wants a contract that never, ever changes wording. One concierge desk can't serve all three well, so the hotel puts a concierge on each floor, trained for that floor's guests. Every concierge calls the same hotel services — kitchen, housekeeping, spa — but each packages the answers in the shape their guests need.
Mapping, stated plainly:
- Each concierge is a BFF — a backend owned by one frontend team, serving one client type.
- The hotel services (kitchen, housekeeping, spa) are your downstream microservices — catalog, pricing, reviews, identity.
- The guests are your clients: web app, mobile app, third-party partners.
- The one-desk-fits-all lobby is the generic API this pattern replaces.
Video: Backend for Frontend (BFF) with Angular and tRPC — Christian Lydemann
Plain-language tour of what a BFF is and why frontends need one.
Why one generic API fails three clients
The lobby desk starts innocent: one API, every client calls it, no duplication. Then the clients' needs diverge, and the single API gets pulled in three directions at once:
Payload size. The mobile app shows six fields on a phone screen; the endpoint returns sixty "just in case." On a flaky connection, every extra kilobyte is battery, parse time, and a user staring at a spinner. The web dashboard genuinely wants all sixty. One payload can't be both lean and complete.
Screen real estate. A desktop shows forty rows with filters; a watch shows three. The API that returns "everything, you figure it out" pushes presentation work onto the weakest device — the one least able to afford it.
Network conditions. The web app sits on office Wi-Fi and can afford eight chatty round trips to assemble a page. The mobile app on a subway can't. An API designed for chatty composition punishes the client with the worst network — exactly backwards.
Release coupling. The web team needs a new field today; the backend team ships monthly. Worse: the web team wants to delete a field, but Android v3.2 still reads it, so the field lives forever. Every client becomes a veto on every change. SoundCloud hit this wall with a monolithic mobile API that blocked three platform teams — it's why Phil Calçado named the pattern in the first place.
The lobby desk ends up as a 400-dish menu where nobody can remove a dish because someone might still order it.
Video: microXchg 2016 - Bora Tunca : BFF Pattern in Action: SoundCloud’s Microservices — microXchg
SoundCloud's origin story: one API buckled under web, mobile, and partner needs.
The pattern: a concierge per floor
A backend for frontend is a thin server-side layer per client type — a web BFF, a mobile BFF, a partner BFF — each owned by the frontend team that consumes it. The BFF's job is aggregation and translation: it fans out to the downstream services, then collapses their responses into one screen-shaped payload the client can render without further calls.
flowchart LR
W[Web app]:::client --> WB[Web BFF<br/>full payload]:::service
M[Mobile app]:::client --> MB[Mobile BFF<br/>lean payload]:::service
P[Partner]:::client --> PB[Partner BFF<br/>stable contract]:::service
WB --> C[Catalog]:::service
WB --> R[Pricing]:::service
MB --> C
MB --> R
MB --> V[Reviews]:::service
PB --> C
PB --> R
Notice what's shared and what isn't. The downstream services stay generic and reusable — the kitchen still just cooks. The per-client shaping lives in the BFF layer, where the team that feels the pain owns the code. The mobile team adds a field to their BFF on Tuesday without asking the backend team for a release train. That ownership flip is the real point: as Calçado put it, the BFF isn't an API used by the application — it's part of the application.
Watch the mobile concierge work a single request:
Interactive diagram: PacketFlow (loads in the app)
One call leaves the phone. The BFF fans out to three services in the datacenter — where bandwidth is free and latency is microseconds — then hands the phone one lean, screen-shaped response. The chattiness moved to where chattiness is cheap.
Here's the same idea as a conversation:
sequenceDiagram
participant Phone as Mobile app
participant BFF as Mobile BFF
participant Cat as Catalog
participant Price as Pricing
Phone->>BFF: GET /home-screen (one call)
BFF->>Cat: product details
BFF->>Price: current prices
Cat-->>BFF: 60 fields
Price-->>BFF: price + currency
Note over BFF: Pick 6 fields,<br/>convert currency,<br/>shape for the screen
BFF-->>Phone: one lean payload
Compare the two shapes of the world:
Interactive diagram: VsToggle (loads in the app)
Video: Meet Your New BFF: Backend to Frontend without the Duct Tape • Noam Honig • Devoxx Poland 2023 — Devoxx Poland
Shows the pattern live in a modern stack: one dedicated backend per frontend.
Where BFFs sit
A BFF is not an API gateway and it's not a microservice. The gateway (there's a whole lesson on API gateways) handles cross-cutting concerns for everyone: auth, rate limiting, TLS termination. The BFF sits behind the gateway and in front of the domain services, and it knows things a gateway never should — what the home screen looks like, which six fields the phone needs, how prices get formatted for this client.
client → API gateway (auth, rate limits) → BFF (shaping, aggregation) → domain services
Keep that layering honest and the architecture stays legible: the gateway protects, the BFF translates, the services compute.
Video: Backends for frontends with GraphQL by Pavels Jelisejevs from C.T.Co at FrontCon 2018 — DEVCLUB LV
Draws the BFF layer between clients and microservices, showing its place in the stack.
Pitfalls: when the concierge starts running the hotel
The pattern works — and then, if you're not watching, it works a little too well. Three classic failure modes:
BFF sprawl: N concierges become N hotels. You start with a mobile BFF. Then
a web BFF, a partner BFF, a smart-TV BFF, a watch BFF. Each one quietly grows
its own copy of the same logic — five slightly different implementations of
"get the user profile." SoundCloud lived this: with about five BFFs in
production, the duplicated profile-fetching was the smell that told them a
UserProfileService was missing from their domain model. The fix isn't fewer
BFFs; it's noticing when duplication across BFFs means a shared concept belongs
downstream, in a real service, instead of being copy-pasted across five
concierges.
Business logic leaks into the BFF. This is the big one. The concierge's job is translation and aggregation — not deciding the menu. The day your mobile BFF starts computing discount eligibility or enforcing refund policy, you've built a second, hidden business-logic layer that no domain expert reviews and every other BFF will eventually contradict. Rule of thumb: if the logic would need to be identical in two BFFs, it doesn't belong in either — push it down into the domain service and let the BFFs call it.
Ownership confusion. A BFF owned by the frontend team that uses it thrives; a BFF owned by nobody in particular rots. The pattern only delivers its release-independence payoff when the team feeling the pain can change the code. If your mobile BFF requires a ticket to the platform team and a two-week wait, you've rebuilt the lobby desk with extra steps.
Video: BFF4EAE: Your Backend's New Best Friend Forever - Stacy Devino | droidcon USA 2026 — nextapp devCon
A production BFF talk with honest notes on when the pattern becomes overkill.
Takeaways
- One generic API fails clients differently: mobile drowns in payload it can't show, chatty composition punishes the worst network, and shared fields couple every client's releases together.
- A BFF is a thin backend per client type — web BFF, mobile BFF, partner BFF — that fans out to downstream services and returns one screen-shaped payload.
- Ownership is the point. The BFF belongs to the frontend team that consumes it, so that team ships UI-driven API changes without waiting on a backend release train.
- BFFs sit behind the gateway, in front of domain services. The gateway protects, the BFF translates, the services compute — keep the layering honest.
- Watch for sprawl, leaks, and orphans. Duplicated logic across BFFs belongs downstream as a real service; business rules belong in domain services, never in the BFF; and a BFF nobody owns is the lobby desk with extra steps.
Check your understanding
Your mobile app calls an endpoint that returns 60 fields, but the screen shows 6. What's the core problem the BFF pattern solves here?
- The API needs more fields, not fewer
- The database is too slow at returning 60 fields
- The mobile app should cache the extra fields for later
- The phone downloads, parses, and pays battery for 54 fields it never shows — a generic payload shaped for nobody in particular
The web team wants to add a field to their screens today, but the backend team ships monthly. How does a web BFF help?
- It doesn't — BFFs still require backend team approval for every change
- It removes the need for the downstream services entirely
- It forces the backend team to ship weekly instead
- The web team owns their BFF, so they can add the field to their own layer immediately and fan out to existing services
Where does a BFF sit in the request path?
- Inside the database, as a stored procedure
- Behind the API gateway and in front of the domain services — translating and aggregating between them
- In front of the API gateway, handling TLS termination for all clients
- On the client device, as part of the mobile SDK
Your mobile BFF and web BFF both implement discount-eligibility rules, and they've started disagreeing. What went wrong, and what's the fix?
- Business logic leaked into the BFF layer; move the rules down into a shared domain service that both BFFs call
- The gateway is misconfigured; add rate limiting
- Nothing went wrong — BFFs are supposed to each own business rules
- BFF sprawl — delete one of the BFFs
SoundCloud ran about five BFFs and found the same user-profile fetching logic duplicated across all of them. What did that duplication signal?
- That the BFF pattern had failed and they should return to one generic API
- That BFFs should never share any code
- A missing domain concept — the fix was a shared UserProfileService downstream, not more copies in the BFFs
- That they needed even more BFFs to spread the load
Go deeper
Want to keep pulling this thread? These talks and tutorials go further than we did here:
- Killing BFFs with GraphQL and Next.js — Roy Derks, React Advanced 2021 (21 min). BFF benefits and sprawl risks, compared with gateways and monoliths.
- Client-First Architecture: Backends for Frontends — Chibuike Nwachukwu, Codementor Events. Why BFFs exist, their trade-offs, and how they differ from gateways.
Sources & further reading
- Phil Calçado, "The Back-end for Front-end Pattern (BFF)" (philcalcado.com, 2015) — the original pattern write-up from SoundCloud: one backend per user experience, and the discovery that the BFF is part of the application.
- Sam Newman, Building Microservices (O'Reilly, 2015) — the BFF as a dedicated aggregation layer per client, distinct from the general-purpose API gateway.
- ThoughtWorks Technology Radar — the BFF pattern's assessment as a technique for decoupling frontend teams from shared backends.
- Better Engineers, "A Crash Course on Microservices Architecture" (Substack) — a concise refresher on the BFF alongside the gateway, CQRS, Saga, and event-sourcing patterns.