GraphQL Federation Field-level Metrics 101

Prithwish Nath
TL;DR
Field-level metrics track per-field request counts, latency, error rates, and client usage across your federated graph. Without them, you're making architectural decisions blind. This post covers what field-level metrics are, why they matter for federated GraphQL, and two patterns they unlock — field deprecation workflows and Zero Trust-style debugging — using WunderGraph Cosmo as the demonstration platform.
Field-level metrics are what make GraphQL Federation manageable in production. Without per-field visibility into request counts, latency, and error rates across your federated graph, you're making architectural decisions blind.
Federated GraphQL has been an invaluable tool for enterprise systems because it offers a scalable, decentralized architecture that accommodates evolving data requirements across distributed teams — and their diverse microservices. You have your independent services, merge them into a unified schema with a single endpoint, and now all of your clients can access exactly the data they want, as if it were all coming from a single GraphQL API.
Instead of having a single, monolithic GraphQL server that eventually becomes difficult to scale, you’ve divided your schema and functionality across multiple services.
But the agility, collaboration, and adaptability afforded by such an architecture would hold little value if you didn’t also have crucial graphql federation metrics that let you optimize your data fetching strategies, minimize downtime by patching issues fast, allocate your resources efficiently, and — in general — make informed decisions in the context of your system.
Field-level metrics in federated GraphQL are precisely this detailed insight.
To demonstrate field usage metrics in Federation, I’ll be using WunderGraph Cosmo — a fully open-source, fully self-hostable platform that supports Federation v1 and v2, licensed under Apache 2.0.
What’s a ‘field’ in GraphQL, anyway?
A field is just an atomic unit of information that can be queried using GraphQL. Suppose we have these two very simple subgraphs — Users, and Posts:
Posts subgraphFrom these two graphs, we can tell that Users have id’s and names, Posts have id’s, content, and authorId’s — and the shape of each specific data is represented by their respective fields (name is a simple, built-in GraphQL type — a String, while the author of a Post is a compound type represented by the User object type ).
The relationship in this example is simple enough — Each Post has a User who authored it, resolved through the authorId field to uniquely identify a User for each Post.
Let’s not go too deep into Federation specific directives here (TL;DR: @key represents the unique identifier for each object type, @external signals that a field is defined in another subgraph and will be resolved externally, via whichever field is presented by the @requires directive — here, authorId).
So if you wanted to query for all Posts along with their User authors, you would request these fields in your GraphQL query:
postsis a root query object (technically a field) on thePostssubgraph, and contains an array ofPosttype objects.id, andcontentare fields on thePosttype.authoris a field on theUsertype. Within the posts query we’re using the relation viaauthorIdto reference aUserfrom theUserssubgraph
Field-level usage metrics in GraphQL — sometimes called graphql field usage tracking — would track how often these specific fields across different subgraphs are requested in queries on the federated graph. And then, for object types like posts, we could get even more fine-grained and look at the usage of its individual fields, in turn.
What does all this information get us?
- We’d be able to debug issues faster, because thanks to our metrics we’d know exactly which fields were having trouble resolving data.
- Even if there were no immediate fatal errors, specific performance data for each field would still allow us to pinpoint bottlenecks or optimization opportunities — and then we could ship fixes/improvements at different levels: our resolver functions, database queries, or network calls associated with those specific fields.
- Just knowing how many times a specific field has been requested or resolved (taking into account potential caching) within a given timeframe would provide valuable insights into user behavior and needs, help us streamline the schema and reduce infrastructure costs, or just help us make informed decisions about pricing tiers and resource allocation.
- We’d have insight into performance trends — error rates, latency, etc. — of specific fields. We could use this to proactively improve scalability (ex. a certain field might require ramping up compute power, another might require increased database throughput) based on anticipated increased demand for certain fields, before they ever get bad enough to impact user experience.
- Tracking field-level metrics is crucial for enterprises to ensure compliance with SLAs —make sure the performance of individual fields meet predefined service-level expectations.
TL;DR: less reactive firefighting, more proactive optimization. Let’s show off these metrics for a second.
The first thing that jumps out right away from field usage data is that in a real world scenario, certain posts will always be more popular than others, but frequent lookups for the same author across multiple posts is redundant, and can and will strain the Users subgraph and its backend. A simple solution could be to implement caching on the User subgraph, and cache author (User) data for the most popular posts, without having to retrieve it every single time.
Since Cosmo lets you filter field usage by client and operation, you might find that your mobile client predominantly accesses the content and author fields, while your analytics dashboard frequently retrieves likes and shares. Now, you can create specialized queries on each client, optimizing for speed and minimizing unnecessary data transfer. Field usage numbers here let you recognize unique requirements of each client type, and their unique field access patterns.
These metrics also show you exactly when a field was accessed over a 7 day retention period, and this is useful in more ways than one: historical usage data, of course, can be used to align caching strategies with predicted future demand, meaning proactive infra scaling (up or down) to avoid bottlenecks during peaks.
But also, the timestamps provide a historical perspective on the adoption and usage patterns of the features each field represents. If you’re not seeing expected usage rate for a certain field/feature, perhaps you need to reassess its relevance to user needs, its value proposition, or even its pricing/monetization strategy.
Simply put, engineers and stakeholders make better decisions on how to evolve the organization’s graphs when they have relevant data to back it up.
Here's a workflow that comes up constantly in any growing federated graph: deprecating a field. Without graphql analytics, deprecation is a guessing game. You mark a field as @deprecated, wait an arbitrary amount of time, and hope nobody still depends on it.
Field-level metrics turn this into an evidence-based process. You can see exactly which clients are still querying a field, how many requests it receives per day, and when it was last accessed. If a field hasn't been touched in three weeks and only one internal client ever used it, you have a clear signal: coordinate with that team, migrate them off, and remove the field with confidence. No guessing. No breakage.
Per-field error rates and latency are diagnostic tools that traditional operation-level monitoring can't match. When you see that a specific field's error rate spikes — say the author field on Post starts returning errors at 5x its baseline — you know immediately which resolver and which subgraph to investigate. You don't need to sift through aggregate error logs across the entire federated graph. The field tells you where to look.
Pair this with latency data and you can spot slow resolvers before they cascade. A field that resolves in 200ms when it used to resolve in 20ms is a signal worth acting on — even if it hasn't started throwing errors yet.
If you've committed to SLAs on your API, field-level latency data is how you prove compliance — or catch violations early. Tracking per-field latency against your SLA budget means you can identify fields that consistently exceed their target before your users notice. That's the difference between a proactive infrastructure conversation and an incident postmortem.
Field-level metrics tell you what's happening across your federated graph in aggregate. But when something goes wrong with a specific request, you need more than aggregates — you need the full trace. This is where graphql observability connects the dots between metrics and debugging.
In a federated architecture, a single client query can fan out across multiple subgraphs. The router parses the query, builds a query plan, and dispatches fetches to each subgraph that owns part of the response. Each of those fetches — and each field resolution within them — is a span in a distributed trace. The trace follows the query plan across subgraphs, so you can see exactly where time is spent, where errors originate, and how data flows through your system.
Federated tracing is what ties your per-field metrics to individual request paths. Metrics show you trends: this field is slow on average, that field's error rate is climbing. Traces show you specifics: this particular request took 800ms because the author field waited on a slow database query in the Users subgraph. You need both for effective graphql federation monitoring — metrics for the big picture, traces for the debugging sessions.
OpenTelemetry and Prometheus are the standards that make this data portable and actionable. With native OpenTelemetry support , your federation traces integrate with whatever observability stack you already run — Jaeger, Grafana Tempo, Datadog, or anything else that speaks OTLP. Prometheus metrics give you the time-series data for dashboards and alerts. No proprietary vendor lock-in for your observability data.
State of GraphQL Federation 2026
How are teams governing schema changes, handling production traffic, and measuring Federation success? Share your experience and get early access to the full report. For every valid survey completed, we'll donate $30 to UNICEF .
I’ll use WunderGraph Cosmo to federate those two subgraphs. Cosmo is an all-in-one platform for GraphQL Federation that comes with composition checks, routing, analytics and distributed tracing — all under the Apache 2.0 license, and able to be run entirely on-prem. It supports Federation v1 and v2 at the directive level.
👉 Cosmo on GitHub: The code
The Cosmo platform comprises of:
- the Studio — a GUI web interface for managing schemas, users, projects, and metrics/traces,
- the Router — a Go server that implements Federation V1/V2, routing requests and aggregating responses,
- and the Control Plane — a layer that houses core Cosmo APIs.
The key to managing your Federation with the Cosmo stack is its CLI tool: wgc . You install it from the NPM registry, and your subsequent workflow would look something like this:
- Create subgraphs from your independently deployed and managed GraphQL services using
wgc subgraph create. - Publish the created subgraphs to the Cosmo platform (or more accurately, to its Control Plane) with
wgc subgraph publish. This makes the subgraphs available for consumption. Note that the Cosmo “platform” here can be entirely on-prem. - Once you have all your subgraphs created and published, federate them into a unified graph using
wgc federated-graph create - Configure and deploy the Cosmo Router to make your federated graph available to be queried at the routing URL you specified. The router, in addition to being a stateless gateway that intelligently routes client requests to subgraphs that can resolve them, also generates the field usage metrics for your federated graph as it’s being queried. And because Cosmo Router exports OpenTelemetry traces natively, every field resolution is captured as a span — complete with subgraph attribution, timing, and error propagation.
Then, we run a few queries against our federated graph, and then fire up Studio, our web interface.
Studio contains the Schema Explorer, which is the control room for your federated GraphQL ecosystem. Here, you can view and download schemas of all of your subgraphs and federated graphs, and — more importantly in our case — view usage of every single type in your federated ecosystem, from Objects (Users, Posts) to the Scalars that they’re made of (Boolean, ID, and String), and even the root operation types (each query, mutation, and subscription).
This is an incredibly fine-grained look at your system. Want to know exactly how many times the author relation (via authorId) was actually accessed when querying for one or more Posts? Go right ahead.
The field usage metrics for the author relation here tell you exactly how many clients and operations requested it, along with a histogram for usage. You get to see exactly which operations accessed it, how many times they did so, which subgraphs were involved in resolving requests for this field, and finally, the first and last time the relation was accessed.
Where to go next with Cosmo observability
Field metrics sit next to tracing, analytics, and cost signals. If you are sizing infrastructure or tuning spend, these posts extend the same thread:
- Open source analytics, tracing, and monitoring for federated GraphQL — what “full stack” observability looks like on a federated graph.
- Scaling GraphQL schema usage to billions of requests — turning usage data into capacity decisions.
- How to analyze GraphQL schema usage — drilling from aggregate traffic into schema hotspots.
- Cost control for your supergraph — tying field demand to budget and quotas.
Federation gives you a distributed architecture. Field-level metrics give you the visibility to run it well. Without per-field data on request counts, latency, error rates, and client usage, you're operating a federated graph on intuition instead of evidence.
The argument is straightforward: the more granular your graphql federation metrics, the better your decisions — about deprecation, scaling, debugging, and SLA compliance. That's what makes field-level observability not a nice-to-have, but the foundation of a well-run federated graph.
Frequently Asked Questions (FAQ)
Field-level metrics track per-field request count, latency, error rate, and client usage across a federated graph. Instead of seeing aggregate numbers at the operation level, you get visibility into each individual field — how often it's queried, how fast it resolves, and which clients depend on it. This granularity matters because in a federated architecture, a single query can touch fields owned by multiple subgraphs, and operation-level metrics can't tell you which field or which subgraph is the bottleneck.
Effective graphql federation monitoring combines three layers: field-level metrics for granular visibility into what's happening across your federated graph, distributed tracing for request-level debugging when something goes wrong, and alerting on per-field latency and error thresholds to catch problems early. OpenTelemetry is the standard that ties these together — it lets you export traces and metrics to whatever observability stack you already run, without locking you into a single vendor.
Metrics aggregate: how often a field is queried, its average latency, its error rate over time. Traces show individual request paths: this specific query took 800ms because the `author` field waited on a slow database call in the Users subgraph. You need both. Metrics surface trends and let you spot regressions. Traces let you debug specific incidents and understand exactly where time is spent across subgraphs.
Yes. Open-source federation platforms like Cosmo provide field-level analytics, distributed tracing, and Prometheus metrics export — all under the Apache 2.0 license. Because Cosmo supports native OpenTelemetry export, your observability data flows to whatever backend you choose: Jaeger, Grafana, Datadog, or your own infrastructure. No proprietary dependencies, and you can self-host the entire stack.
Field usage data shows you exactly which fields are actively queried, by which clients, and when they were last accessed. Instead of marking a field as `@deprecated` and hoping for the best, you can check whether any client has queried it in the past month, identify the specific teams that depend on it, and coordinate the migration before you remove it. This evidence base turns deprecation from a guessing game into a defined workflow.

