PATTERN Cited by 1 source
Unified GraphQL Backend-For-Frontend (UBFF)¶
When to use¶
You have:
- Many frontend surfaces (Web, iOS, Android, partner APIs) consuming roughly the same business data.
- Many backend microservices owning that data (dozens of domains).
- An accumulated cost from a per-surface BFF deployment: duplicated logic, inconsistent customer experience across platforms, fragmented auth/observability, Conway's-Law drift between surfaces (see concepts/backend-for-frontend).
- Capacity to commit to one schema across the company (unified graph discipline), with a dedicated platform team.
- A preference for simpler operations and unified tooling over per-domain deploy independence.
The pattern¶
Deploy a single GraphQL service that:
- Owns one unified schema spanning all product domains.
- Is contributed to by every product team via a shared-ownership monorepo with explicit contribution principles.
- Is consumed by every frontend surface (Web, iOS, Android, partners, internal) through the same endpoint.
- Follows a strict No Business Logic principle — aggregates and shapes only; business logic lives in downstream presentation- layer backends.
all frontends (Web, iOS, Android, internal, partner)
│
▼
┌──────────────────────────────┐
│ Single UBFF GraphQL service │
│ (one schema, one deploy- │
│ ment artifact, one repo) │
└────────────────┬──────────────┘
▼
presentation-layer backends
(platform + domain specific logic)
│
▼
domain microservices
Why not Apollo Federation?¶
The explicit anti-pattern within this pattern. Apollo Federation is many services, one schema, composed at a router at runtime. The UBFF is one service, one schema, no runtime composition. The trade named in Zalando's 2021 post:
"instead of having multiple Graphs connected via a library and gateway we have a single service at Zalando which connects all the domains in a single schema Graph. This has tradeoffs which we have addressed as mentioned here, since we gain by keeping a single Graph in terms of tooling, deployment and governance."
The UBFF wins on: unified tooling, single deployment artifact, single governance surface. It loses on: per-domain deploy independence (all domains share the same release train) and per-domain runtime isolation (a bad resolver in domain X can degrade domain Y).
Canonical wiki instance: Zalando UBFF¶
Zalando's Unified Backend-For-Frontends GraphQL (Source: ):
- Production since end of 2018; development began H1 2018.
- 12+ domains in one monorepo under shared ownership.
- 150+ contributors (from 50 in 2020); 200+ consuming developers across 25-30 feature teams.
- >80% of Web and >50% of App use cases served.
- Runs on graphql-jit — Zalando's open-source JIT-compiled GraphQL executor.
- Uses an Entity system as first-class schema
citizens (
Product,Campaign, …), cross-linked into "a dense graph." - Deployed with per-platform bulkhead — separate deployments for Web and mobile Apps, same codebase.
How the monorepo-as-god-component risk is managed¶
The post names the concern: a 12+ domain monorepo is a God Component design smell. Two mitigations:
- Architectural: shared ownership across 12+ teams guided by a documented contribution framework; no single team can unilaterally reshape the graph.
- Operational: reliability patterns (Circuit Breakers, Timeouts, Retry) plus Bulkhead at the deployment level.
Adoption levers (from Zalando's retrospective)¶
Four levers scaled adoption 50 → 150+ contributors and 70 → 200 consumers in one calendar year:
- One-stop-shop Documentation (Divio framework) with embedded GraphiQL + Voyager + practice exercises.
- Dedicated support chat for users and contributors.
- Company-wide training (one session hit 150+ attendees).
- Schema-design consultation hours provided by the platform team for every new domain integrating into the graph.
Hard problems this pattern introduces¶
- Single-service deploys. No per-domain deploy independence — every team's changes ride the same release train.
- Single-service blast radius. A bad resolver in domain X can degrade latency or error rates for domain Y. Per-platform bulkhead only splits by Web/App, not by domain.
- Schema governance is load-bearing. Without a dedicated governance team and explicit contribution principles, the graph fractures.
- Scaling the execution engine. At Zalando's density
the reference
graphql-jsinterpreter was insufficient; they had to build and open-source graphql-jit. - The Entity system is hard to get right. Cross- domain first-class entity identity is a schema-design problem every organisation has to solve uniquely.
Contrast with adjacent patterns¶
- patterns/federated-graphql-subgraph-per-domain — same goal (unified graph), opposite topology (many services, one router).
- patterns/graphql-unified-api-platform — the broader umbrella; UBFF is the single-service implementation, federation is the distributed one.
- patterns/multi-tenant-graphql-runtime (added 2026-05-15) — the third topology sitting between UBFF and Federation: a few GraphQL runtimes, each hosting many tenant modules. UBFF is one runtime, one module; Federation is N runtimes, N modules; the multi-tenant runtime is few runtimes, many modules per runtime. Canonical wiki instance: Airbnb Viaduct. Trade vs UBFF: gain per-module ownership clarity + per-module testing + ability to partition unrelated modules into separate runtimes; lose UBFF's one-codebase-one-deploy simplicity. Source: sources/2026-05-13-airbnb-viaduct-1-0-and-the-future-of-airbnbs-data-mesh.
- Per-surface BFF (what UBFF replaces) — one BFF service per surface (Web, iOS, Android, …); named in concepts/backend-for-frontend.
Seen in¶
- sources/2026-05-13-airbnb-viaduct-1-0-and-the-future-of-airbnbs-data-mesh — Airbnb's Viaduct 1.0 announcement adds a third topology to the wiki's GraphQL-decentralisation taxonomy: the multi-tenant runtime sits between UBFF (one service, one module) and Federation (many services, one module each). The post's persona-mapping is explicit: "engineering organizations that have outgrown a single GraphQL service" — i.e. UBFF graduates to either Federation (N servers) or a multi-tenant runtime (few servers, many modules each). First on-wiki post-UBFF graduation framing.
- — Zalando UBFF; first wiki instance.
Related¶
- systems/zalando-graphql-ubff — canonical instance
- systems/graphql
- systems/graphql-jit — the execution engine
- systems/apollo-federation — the explicit not-chosen alternative
- systems/viaduct — the third-topology sibling
- concepts/backend-for-frontend
- concepts/unified-graph-principled-graphql
- concepts/decentralized-development-of-central-schema — the problem space
- patterns/business-logic-free-data-aggregation-layer
- patterns/per-platform-deployment-bulkhead
- patterns/graphql-unified-api-platform
- patterns/federated-graphql-subgraph-per-domain
- patterns/multi-tenant-graphql-runtime — the third-topology pattern
- patterns/module-based-graphql-decentralization — the contribution model the third-topology variant uses