---
title: "BFF Pattern: A Separate API Layer for Mobile and Web"
description: "Separate API layers for mobile and web: the hidden cost of bending one API to fit every client, and when a BFF is actually warranted"
url: https://sade.dev/en/notes/bff-backend-for-frontend/
lang: en
author: "Muhammet Şafak"
published: 2026-07-04
updated: 2026-09-06
section: Note
tags: ["architecture","api","bff"]
summary: "Bending one general-purpose API to fit every client is paid for in over-fetching, chatty flows, conditional fields and a versioning knot that locks web and mobile into one contract. A BFF cancels that bill with a thin adaptation layer per client — aggregation and response shaping, never business rules. What justifies the layer is the distance between clients, not their number."
---

# BFF Pattern: A Separate API Layer for Mobile and Web

> Bending one general-purpose API to fit every client is paid for in over-fetching, chatty flows, conditional fields and a versioning knot that locks web and mobile into one contract. A BFF cancels that bill with a thin adaptation layer per client — aggregation and response shaping, never business rules. What justifies the layer is the distance between clients, not their number.

I once watched a mobile app fire nine separate requests just to render a single home screen. The API had actually been designed for web; mobile was collecting the data the way web sliced it, piece by piece, and stitching it back together on screen. Nine round-trips per launch — under mobile network conditions, no less.

That was the bill for the "one API fits everyone" assumption. The BFF — Backend for Frontend — exists precisely to cancel that bill.

## What a BFF is

A BFF is a thin API layer tailored to one specific client type. Web gets its own BFF, mobile gets its own. Each one calls the same underlying services and domain, but shapes the response to fit its own client's screen.

The real business logic doesn't live in the BFF. The BFF is only an **adaptation layer**: it aggregates, trims unneeded fields, and gathers everything a client needs for one screen into a single response.

## The hidden cost of bending one API to fit everyone

A single general-purpose API can't fully satisfy two clients over time:

- **Over-fetching.** Mobile downloads a 40-field user object and uses 4 of them. The rest is wasted bandwidth and battery.
- **Chatty flow.** The "fetch the list first, then fetch details for each row" flow that web finds perfectly normal turns into nine round-trips on a mobile network.
- **Conditional fields.** The response starts branching with `if mobile then ... else ...`. A single endpoint tries to carry the requirements of two clients at once and does a mediocre job for both.
- **Versioning knot.** A change needed for web risks breaking mobile's published version. Two clients get locked into one contract.

Each of these costs looks small on its own; their sum is an architectural problem.

## When is a BFF warranted?

A BFF is justified when client needs **genuinely** diverge:

- Mobile and web need distinctly different screens and different data shapes.
- Mobile network and battery constraints make round-trip count and payload size a first-class concern.
- The clients ship at different cadences — the mobile release is stuck in store review while web deploys every day; a single contract locks the two together.

When these differences exist, giving each client its own BFF is cheaper than constantly bending one API to fit both.

## When is a BFF unnecessary?

If you have a single client, a BFF is more layer than solution — just an extra hop.

If you have two clients but both want almost the same data in almost the same shape, it's still unnecessary. What justifies a BFF isn't the number of clients but the **difference between** them. No difference, no separate layer — otherwise it's [speculative generality](/en/journal/the-cost-of-just-in-case-code) in the shape of an API layer.

## A BFF is not a microservice

A common confusion: adding a BFF doesn't drop you into distributed architecture. A BFF is a presentation/aggregation layer, not a domain service. Putting business rules inside it means copying the rule once per client.

The BFF's only kinship with microservices is this: both ask "is this worth a separate deployable?" The answer is usually "no" — the measured-signal threshold from [the decision to move to microservices](/en/journal/when-i-move-to-microservices) applies here too.

## Start light

"BFF" doesn't have to mean standing up a separate server. Within the same monolith:

- One route namespace per client — `routes/web-api.php`, `routes/mobile-api.php` — each with its own controllers and its own response shape.
- Or a single GraphQL layer: each client queries exactly what it needs, and over-fetching resolves itself.

The real idea isn't a box, it's a boundary: collect the client-specific adaptation in one place and keep the domain clean of it. Move to a separate deployable only when [a measured signal](/en/journal/when-i-move-to-microservices) forces it.

---

The BFF is the antidote to the "every client makes do with the same API" stubbornness — but only when clients genuinely diverge. No difference, no layer.

What adds the layer isn't the number of clients, it's the distance between them.

## Frequently asked

**When is a BFF unnecessary?**

When there is only one client, a BFF is more layer than solution — just an extra hop. And with two clients that want almost the same data in almost the same shape it is still unnecessary: what justifies a BFF is the difference between clients, not their number.

**Is a BFF a microservice?**

No. A BFF is a presentation and aggregation layer, not a domain service, and adding one does not drop you into a distributed architecture. Putting business rules inside it means copying the rule once per client. It shares only one question with microservices: is this worth a separate deployable?


## Sources

- [Pattern: Backends For Frontends](https://samnewman.io/patterns/architectural/bff/) — Sam Newman
- [Backends for Frontends pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends) — Microsoft Azure Architecture Center
