What is the Backend for Frontend pattern?
A backend for frontend (BFF) is a server-side component built for one client experience, such as the iOS app or the web app. It sits between that client and the domain services, calls what it needs, and returns responses in the shape the client wants. Usually the team that builds the client also owns its BFF.
What problem does the Backend for Frontend pattern solve?
One general-purpose API for every client becomes a compromise nobody likes. Mobile wants small payloads and few round trips, web wants something else, and every change needs agreement between teams. A BFF per client lets each team move at its own pace.
How do you implement the Backend for Frontend pattern?
- Create one BFF per distinct client experience, not one per device model or per feature.
- Let the client team own the BFF and deploy it with the client when they change together.
- Keep business rules in domain services. The BFF only fetches, combines and reshapes.
- Share cross-cutting code (auth, telemetry) through a small library or the gateway, and change it slowly.
- Apply timeouts and fallbacks to every downstream call.
When should you use it?
- Clients need very different data shapes or interaction patterns.
- Client teams keep waiting on a shared API team for changes.
When should you avoid it?
- There is one client, or all clients need the same thing. A single API is simpler.
- No client team can own and operate a backend service.
What do you gain?
- Client teams change their API without negotiating
- Responses fit each client
- Domain services stay client-agnostic
What does it cost?
- More services to run
- Logic can be duplicated across BFFs
- Business rules tend to leak into them
What are common mistakes with the Backend for Frontend pattern?
- Putting authorization or pricing rules in a BFF, so each client enforces them differently.
- A shared BFF library that changes often and breaks every BFF at once.
- One BFF per feature, which brings back the problem it was meant to solve.
Backend for Frontend in practice
SoundCloud
A Rails monolith exposed one public API to the web app, Android, iOS and external partners. Every client team needed changes to the same API, and it served none of the mobile apps' needs well.
Client teams were allowed to build and own backend-for-frontend facades outside the monolith, with a shared library for concerns such as monitoring and authentication. A later lesson was that business and authorization logic crept into individual BFFs, and that fast-moving shared libraries could spread bugs across all of them.
Example decision record
- Context
- Mobile and web teams keep fighting over the shape and size of shared API responses.
- Decision
- Give the mobile and web clients separate backend-for-frontend services, owned by the client teams.
- Consequences
- Each client team ships API changes on its own schedule.
- Business rules must stay in the domain services, not in the BFFs.