Backend for Frontend (BFF) Pattern: Designing Single‑Purpose Edge Services for User Interfaces
The article explains how the Backend for Frontend (BFF) pattern creates dedicated, lightweight server‑side APIs for each UI type—desktop web, mobile, or third‑party—allowing teams to tailor functionality, reduce coupling, aggregate micro‑service calls, and improve autonomy while addressing performance, scaling, and organizational concerns.
Introduction
With the rise of the web, delivering user interfaces shifted from thick client applications to web‑based UIs, dramatically lowering the cost of publishing new features because client‑side installation costs were eliminated.
However, the arrival of mobile devices introduced new challenges: server‑side functionality now needed to be exposed to both desktop web UIs and one or more mobile UIs, creating tight coupling between the original desktop UI and the services it consumes.
Generic API Backend
The first step to supporting multiple UI types is often to provide a single server‑side API and gradually add more capabilities as new mobile interactions are required.
When different UIs need to make the same or very similar calls, a generic API can work well. Yet mobile experiences differ fundamentally from desktop: smaller screens, limited battery and data plans, and distinct interaction patterns (e.g., barcode scanning, context‑aware offers). Consequently, mobile clients make fewer, different calls and expect less data, requiring additional API functionality.
A generic API backend that serves many front‑ends can become a bottleneck as changes for one UI affect the shared artifact, often necessitating a dedicated team to manage the codebase, which adds coordination overhead.
Introducing Backend for Frontend (BFF)
A solution observed at REA and SoundCloud is to give each UI its own backend, often called a Backend for Frontend (BFF). Conceptually, a user‑facing application consists of two components: a client UI and a server‑side component (the BFF) that sits at the edge.
The BFF is tightly coupled to a specific UI and is usually owned by the same team that builds the UI, making API definition and adjustments easier and simplifying the release pipeline for both client and server components.
Each UI gets its own BFF, which focuses solely on that UI, keeping it small and manageable.
How Many BFFs?
Two approaches are common. The first, seen at REA, creates a strict BFF per client type. The second, used at SoundCloud, shares a BFF between Android and iOS native apps while giving other clients separate BFFs.
Choosing a shared BFF makes sense when iOS and Android experiences are very similar; otherwise, separate BFFs are justified. Team structure often dictates the number of BFFs—if you have a single mobile team, one BFF suffices; separate iOS and Android teams usually warrant separate BFFs.
Multiple Downstream Services (Microservices!)
When an architecture has many backend services, BFFs become essential for aggregating calls. For example, an e‑commerce app may need to fetch a wishlist, inventory levels, and pricing from three different services, which the BFF can combine into a single response.
Parallelizing these calls improves latency, but error handling becomes critical—if one downstream service fails, the BFF must decide whether to degrade gracefully or return an error.
Reuse
Having many BFFs can lead to duplicated aggregation logic. Some teams attempt to merge this code into a shared service, but that often results in bloated, tightly‑coupled code. Instead, extracting shared libraries or creating new services for common functionality can be a better approach, provided the added coupling is acceptable.
Desktop Web and Other Domains
BFFs are not limited to mobile; they can also be useful for desktop web when heavy aggregation is required, or when server‑side rendering is employed. Placing a reverse proxy in front of a BFF can aid caching of aggregated responses.
Autonomy
When frontend teams own the BFF, they can evolve the API independently of the downstream services, reducing friction and allowing faster feature delivery without waiting for other teams.
General Peripheral Concerns
Some teams implement cross‑cutting concerns such as authentication, authorization, or request logging in the BFF, but this adds latency and complexity. An upstream layer (e.g., Nginx, Apache) can handle these concerns more efficiently.
When to Use BFF
If an application only serves a web UI, a BFF is worthwhile only when significant server‑side aggregation is needed. For mobile UIs or third‑party consumers, a BFF is strongly recommended to separate concerns and simplify client development.
Further Reading (and Watching)
Since this article was written, ThoughtWorks' Lukasz Plotnicki published a great piece on SoundCloud’s use of the BFF pattern, and he discussed the pattern on a recent software engineering podcast. Bora Tunca from SoundCloud also covered the topic in a 2016 microxchg talk.
Conclusion
The BFF pattern solves a pressing problem for mobile development on microservice architectures and offers a compelling alternative to a generic API backend for many use cases. By limiting the number of consumers, BFFs are easier to manage, change, and allow frontend teams to retain greater autonomy.
Architects Research Society
A daily treasure trove for architects, expanding your view and depth. We share enterprise, business, application, data, technology, and security architecture, discuss frameworks, planning, governance, standards, and implementation, and explore emerging styles such as microservices, event‑driven, micro‑frontend, big data, data warehousing, IoT, and AI architecture.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.