GraphQL Federation: A Complete Guide - WunderGraph
GraphQL Federation Explained
One API surface, multiple backend teams. Here's how it works, when to use it, and what breaks in production.
TL;DR
GraphQL federation is an architectural pattern that combines multiple independently developed GraphQL services, called subgraphs, into a single unified API called a supergraph. A router builds a query plan and orchestrates requests across those subgraphs, so clients can query the whole system as if it were one schema. Because each team owns its own subgraph, federation is as much an organizational model as a runtime one.
Glossary
Supergraph
The unified schema clients query, composed from multiple subgraph schemas; the public surface of the federated system.
Clients see one API even when many teams own the backend services behind it.
Subgraph
An independent GraphQL service that owns a portion of the supergraph schema; the unit of team ownership.
Teams can ship domain changes without centralizing all backend development.
Router
The gateway that plans queries, fetches data from subgraphs, and assembles the response; the runtime hot path for every query.
Router quality determines latency and operational visibility; batching and caching behavior depend on the implementation.
Schema registry
The system of record for subgraph schemas and composition results; it validates whether schemas compose safely before they reach production.
Breaking composition can be caught in CI instead of during live traffic.
Composition
In composition-based federation, the process of merging subgraph schemas into a single supergraph ahead of execution rather than during request handling.
Schema conflicts can surface during composition or CI, before live traffic hits the graph.
Entity
A type that spans multiple subgraphs, identified in federation by a @key directive; the mechanism that lets one graph object be extended across service boundaries.
Shared types like User or Product can be owned in parts by different teams.
What Is GraphQL Federation?
GraphQL federation is an architectural pattern that combines multiple independently developed schemas, called subgraphs, into a single unified API called a supergraph. A router (or gateway) builds a query plan and orchestrates requests across those subgraphs so clients can query the system as if it were one schema.
Depending on your setup, a subgraph might be a traditional GraphQL server or a virtual schema generated from other backends, such as gRPC or REST services, as long as it participates in the federated composition process.
In practice, federation is as much an organizational model as a runtime model. Teams can own separate domains and still contribute to a shared graph, which makes federation especially useful when a single API has to reflect the structure and ownership boundaries of multiple backend teams.
What sets schema-composition-based federation apart from a simple proxying gateway:
- In composition-based setups, subgraph schemas are composed and validated before being rolled out to the router, so many incompatibilities can be caught before they ever affect production traffic.
- The router builds a schema-aware query plan and then orchestrates distributed execution across subgraphs, instead of simply proxying requests to a single backend. Planning behavior and optimizations vary by implementation.
- Entities can span services, so a single type like User or Product can be defined and extended across multiple subgraphs, while teams establish clear ownership conventions for who defines which parts of the type.
Platforms like WunderGraph Cosmo add governance tools and composition rules on top of federation to help enforce those ownership conventions across teams.
How Does GraphQL Federation Work?
Four core mechanics drive most federated graphs: schema composition, federation directives, query planning, and entity resolution. They are not an exhaustive picture of runtime behavior, but understanding them is the difference between wiring up federation and operating it well in production.
Schema composition
In composition-based setups, each subgraph's schema is registered with a central schema registry, usually via CI pipelines or CLI tooling. The registry composes these subgraph schemas into a supergraph and validates whether they form a consistent, compatible graph before new configurations are rolled out to the router.
That design matters operationally. Instead of discovering conflicts when a client query hits production, teams can fail schema changes during CI or review workflows and only publish a new supergraph once composition checks pass.
Mature federation platforms build governance and change-management features on top of this composition step.
Federation directives
Most federation implementations use schema directives to describe entity identity, cross-subgraph relationships, and routing and execution behavior.
In the Apollo / Open Federation family, core directives include @key (entity identity), @external, @requires, and @provides, with Federation v2 adding @shareable, @override, @interfaceObject, and others.
Cosmo implements an open, Apollo-compatible set of federation directives and adds platform-specific ones for governance, security, and documentation control.
Query planning
When the router receives a query, it validates it against the supergraph schema and builds a query plan. That plan determines which subgraphs to call, which fetches can run in parallel, and how to join the results back into one response.
Depending on the implementation, advanced routers may also batch subgraph requests, cache query plans, deduplicate fetches, and emit detailed tracing so operators can understand why a query behaved the way it did.
Platforms like WunderGraph Cosmo go further with features such as query-plan caching and cache warmers that precompute plans for operations that are slow to plan.
Entity resolution
Entity resolution is what lets a single graph object span service boundaries. If one subgraph owns User.name and another owns User.orders, the router can fetch an entity key (via a representation query like _entities) from the first service and use it to resolve related fields from the second.
This is one of federation's biggest strengths and one of its main performance risks. Without effective batching and smart query planning, which some routers implement and others do not, clean graph queries can devolve into slow internal fan-out.
That is why query planning, observability, and tracing matter so much in production.
Request flow, end to end
- The client sends a single GraphQL query to the router.
- The router validates it against the supergraph schema it loaded from the CDN and retrieves or computes a query plan.
- The router sends the necessary subgraph requests, batching and parallelizing where the plan allows.
- Each subgraph returns its slice of the response.
- The router assembles the result and returns one response to the client.
What Changes When GraphQL Federation Scales Across Teams?
Federation looks straightforward with a few subgraphs. It becomes much harder when many teams are publishing schema changes into the same production graph.
At scale, the hard part shifts from composition alone to the operating model around composition. Platform teams need ownership rules, review workflows, observability, and a reliable way to answer basic questions like which supergraph version is live and which clients still depend on a given field.
Common failure modes include:
- Schema changes break trust when teams cannot coordinate safely.
- Governance overhead grows when ownership and deprecation policies are informal.
- Query performance degrades when entity resolution fans out without effective batching.
- Observability gaps appear when traces stop at the gateway.
- Subscription complexity grows when connection state and delivery logic spread across services.
None of these problems mean federation is the wrong architectural choice. They point to a gap the spec does not cover. Composition merges schemas, but it does nothing for the human coordination around those schemas: finding the team that owns a type, agreeing on a field, and tracking the change.
That coordination tax is where federation programs actually slow down.
Federation doesn't enforce a design direction. Subgraph teams can build their pieces independently and let the supergraph emerge from composition. Or teams can design the consumer-facing API first and work backward.
In practice, most organizations do both at once, and the supergraph ends up a side effect of composition rather than something deliberately designed.
Cosmo is built for that reality. Schema checks, guardrails, distributed tracing, and governance extend beyond composition into the runtime.
When Is GraphQL Federation the Wrong Choice?
Federation is demanding infrastructure. It tends to pay for itself when multiple teams need to evolve one shared API surface, and it often costs more than it returns when that coordination problem does not yet exist.
A practical rule of thumb is that federation starts to become compelling when several teams need independent ownership over a shared API contract. Below that threshold, a modular monolith, schema stitching, or a client-specific BFF layer is often the better tradeoff.
- One or two teams with a small API surface. A modular monolith is often simpler to operate.
- Services that do not share entities across team boundaries.
- Backends that don't justify the cost of exposing them through a shared GraphQL contract yet.
From BFF to Federation
The Backend-for-Frontend pattern puts a dedicated gateway between each client type and the backend. Each BFF shapes data for its specific client: the mobile BFF returns compact payloads, the web BFF returns richer objects.
For a small number of clients and a contained backend, this is a reasonable design.
Problems tend to appear as the backend and client surface grow. Multiple BFFs end up integrating the same services.
User profile logic gets written once in the mobile BFF and again in the web BFF. When the user service changes, both owners update.
Add a third client type and the pattern extends: another BFF, another copy of the same integrations, another team to coordinate with when something changes upstream.
At that point, teams are paying a coordination cost twice: once when backend services change, and once when clients want different data shapes.
Federation addresses the duplication by putting one shared, typed contract (the supergraph schema) between the backend and all clients. Subgraph teams own their domain; the router handles assembly.
Clients still query what they need, but the integration logic is shared and governed rather than copied across BFFs.
Signs a BFF is ready to be consolidated into a federated graph:
- Multiple BFFs integrate the same backend services independently.
- Schema drift across client-specific APIs exposing the same underlying domain data.
- Backend changes require coordinating the same update across multiple BFF owners.
- A new client type would mean building another full integration layer from scratch.
- No central view of the full API surface across all clients.
How Does GraphQL Federation Compare to Schema Stitching?
Both present multiple services through one GraphQL API. The difference is in how cross-service relationships are expressed and validated, not in whether stitching is always “runtime-only.”
| Schema stitching | GraphQL Federation | |
|---|---|---|
| How schemas combine | Via a gateway using delegation and schema extension patterns, often with build-time or gateway-side logic | Composed ahead of execution in a registry or composition pipeline |
| Cross-service relationships | Commonly expressed in gateway delegation logic | Declared in the schema with federation directives and the composition model |
| Schema conflicts | May surface at runtime depending on setup | Often caught during composition or CI before deployment |
| Often better suited for | Smaller systems, single-team API ownership | Multiple teams that need explicit entity boundaries |
Stitching remains a valid pattern for smaller systems and centralized ownership. Federation tends to be a better fit when multiple teams need reviewable cross-subgraph contracts, including entity directives and clear ownership boundaries.
How Does GraphQL Federation Compare to a REST API Gateway?
The two operate at different layers and often coexist.
| REST / edge gateway | GraphQL Federation router | |
|---|---|---|
| What it exposes | Backend endpoints | A unified typed schema |
| Primary job | Routing, auth, rate limiting | Query planning, data composition, and schema-aware routing |
| Can they coexist? | Yes. A REST gateway can sit in front of a federation router. | Yes. Typically deployed behind an edge gateway. |
What Are the Benefits of GraphQL Federation?
Federation is worth the operational overhead when it solves a real coordination problem: multiple teams evolving one shared API without fragmenting the client experience.
Those benefits are real, but they are not automatic. Federation amplifies both good schema design and bad schema design, which is why successful programs treat schema quality as a core engineering concern, not as after-the-fact cleanup.
- Team autonomy through domain-based subgraph ownership.
- One unified API surface for clients.
- Design-time (pre-publication) validation of schema compatibility in composition-based setups, via a registry and schema checks.
- Better alignment between organizational ownership and API structure.
- A path to shared observability and centralized graph governance when paired with a platform that provides tracing, metrics, and schema checks.
What Do Successful GraphQL Federation Programs Need Beyond Composition?
The open mechanics of federation explain how schemas compose and how routers execute queries. They do not, by themselves, solve the full operating problem of running a shared graph in production.
This is where product differences matter more than spec differences. Teams rarely struggle with the abstract idea of federation; they struggle with operating it safely as the number of teams, services, and schema changes grows.
- A schema registry that validates compatibility before publication.
- Governance: ownership rules, review workflows, and controlled deprecations.
- A query planner whose output is inspectable and regression-tested, so you can understand and optimize how queries fan out across subgraphs.
- Distributed tracing from the router into subgraphs.
- A way to include non-GraphQL services without rewriting them.
The Federation Stack
Composition and a router contract are where the open spec ends. Everything else that keeps a shared graph healthy in production sits outside it.
At scale, federation works as a stack: a set of components that each own one layer of the problem and hand work to the next.
Schema changes start in a design and governance layer, where teams agree on the contract and a registry validates that the schemas still compose. The composed supergraph then reaches the runtime, where a router plans and executes queries across subgraphs on the hot path for every request.
Integration components bring non-GraphQL and event-driven backends into the same graph, so the router can resolve them alongside native subgraphs.
What WunderGraph Adds Beyond the Spec
WunderGraph Cosmo is an open-source federation platform built for the operating layer the spec leaves out. It adds schema checks, governance guardrails, distributed tracing, multi-protocol integration, and self-hosted or managed deployment. These are the parts that matter once a federated graph goes to production.
Router performance and query planning
Cosmo Router is built in Go with auth integration, subscriptions, and observability built in. In our benchmark comparisons against Apollo Router on cold query-planning workloads, Cosmo Router has shown significantly lower P99 latency.
Governance through Hub
Hub is the collaboration layer federation leaves out. It replaces the ad hoc mix of Slack threads, Miro boards, and design meetings teams use to coordinate schema changes today.
Hub's schema engine, Fission, inverts the standard federation workflow: teams design the consumer-facing API first, starting from a "dream query" that describes what a client needs.
gRPC and REST federation with Cosmo Connect
Cosmo Connect brings non-GraphQL backends into federation without requiring those teams to adopt GraphQL.
Event-driven subscriptions with Cosmo Streams
GraphQL federation does not define one universal subscription execution model. Implementations differ widely. Cosmo Streams is WunderGraph's event-driven approach to subscriptions in federated graphs.
How Does GraphQL Federation Work With AI Agents and MCP?
A federated supergraph is a typed, governed, queryable surface across many internal systems. Those properties are useful for AI agents, because typed operations, explicit schemas, and centralized routing can make tool exposure safer and easier to reason about.
Cosmo now includes two MCP capabilities. The MCP Gateway is a router feature that exposes your GraphQL operations as tools AI agents can call at runtime.
How Do You Get Started With GraphQL Federation?
Cosmo has a free tier and full documentation for both managed and self-hosted deployment. Basic evaluation setups can often be created quickly; time to value depends on how many services you federate, schema maturity, and operational requirements.
- Create or identify the first subgraph.
- Publish subgraph schemas into a schema registry and composition workflow.
- Compose the supergraph and validate compatibility via schema checks.
- Deploy a router against the composed graph.
- Start querying the unified API from clients.
Who Uses GraphQL Federation?
Federation is used across media, marketplaces, travel, SaaS, and platform engineering teams. The broad appeal is the same across industries: multiple teams need to contribute to one API without centralizing all backend development in one service.