GraphQL Federation Field-level Metrics 101 - WunderGraph

Prithwish Nath

January 1, 2024·11min read

Edited on May 12, 2026 by Brendan Bondurant

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 Usage Metrics 101

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 subgraph
1
2
3
4
5

Users Subgraph
1
2
3
4
5
6
7
8
9

From 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:

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?

TL;DR: less reactive firefighting, more proactive optimization. Let’s show off these metrics for a second.

What GraphQL Field-Level Metrics Tell You

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.

Field Deprecation Workflow

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.

Error Rate Investigation

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.

SLA Monitoring

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.

From Metrics to Observability: Distributed Tracing in Federation

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.

How This Looks in Practice with WunderGraph Cosmo

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.

The Cosmo platform comprises of:

  1. the Studio — a GUI web interface for managing schemas, users, projects, and metrics/traces,
  2. the Router — a Go server that implements Federation V1/V2, routing requests and aggregating responses,
  3. 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:

Then, we run a few queries against our federated graph, and then fire up Studio, our web interface.

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.

Why Field-Level Metrics Matter for Federation

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.