Join us from October 8-10 in New York City to learn the latest tips, trends, and news about GraphQL Federation and API platform engineering.Join us for GraphQL Summit 2024 in NYC
Docs
Start for Free

Field Usage in GraphOS

Understand field usage metrics including which clients and operations request which fields and how often


NOTE

The retention period for usage metrics depends on your plan. Refer to the pricing page for details.

You can analyze the field metrics sent by your graph to from any 's Insights page in GraphOS Studio:

The Insights page in GraphOS Studio

The Insights page presents and field metrics. It has two main sections:

  • The collapsible left sidebar, where you can search, filter, and sort and fields
  • The main insights view on the right
    • This view displays overall operations metrics by default, or field information and usage metrics for a single field once you select it from the left sidebar

This guide focuses on field metrics and information. Refer to Operation metrics in GraphOS for more information on the other metrics on this page, including resolver-level traces.

Field usage metrics availability

The collapsible left sidebar on the Insights page lets you filter field types you want to view usage metrics for:

Field Insights page left sidebar

All organizations can view object fields, but only organizations with an can view usage metrics for input fields and enum values.

Object fields

All organizations can access field usage metrics for standard object fields. For example, given a User type like this:

type User {
id: ID!
name: String!
email: String!
age: Int
}

All plans can view usage metrics for User.id, User.name, etc.

Input fields and enum values

Only organizations with an Enterprise plan can view field usage metrics on input object fields and enum values.

For example, given a UserInput input type or InventoryStatus enum values like these:

input UserInput {
name: String!
email: String!
password: String!
address: AddressInput
}
enum InventoryStatus {
IN_STOCK
OUT_OF_STOCK
DISCONTINUED
}

Only enterprise organizations can view usage metrics on UserInput.name, UserInput.email, etc., or InventoryStatus.IN_STOCK, InventoryStatus.OUT_OF_STOCK, etc.

To access input and enum field metrics you must use the to report metrics and configure extended reference reporting in your .

NOTE

execution metrics are only available for standard object fields, not input object fields or enum values.

Field details

When you click a field name, you open detailed information for that field in the main insights view. This includes when the field first and last received traffic, any applied tags, and the that provide the field.

Below that, you can view the field definitions within your .

Field Insights page

Next, you see which clients and operations contribute to the field's usage. Each row in the Clients & Operations table shows a client that requested the field, the number of operations that used the field the client made, and the total number of requests the client made. Selecting a client shows more details about the operations that requested and executed the field.

Below Clients & , you can view visualizations for the field's request rate, latency distribution, and error metrics.

Field requests and executions

Each row in the Clients & Operations table displays some combination of the following metrics for each field, depending on which data you report to GraphOS:

MetricDescription
Client versionsHow many different client versions have sent the operation
RequestsHow many operations sent by clients over a given time period included the field, according to metrics provided by your servers
ExecutionsHow many times your servers have executed the resolver for the field over a given time period

NOTE

Execution metrics are only available for standard object fields, not input object fields or enum values.

For each of these columns to appear on the Insights page, your must report the associated metrics to GraphOS. If some but not all your GraphQL servers report this data, the Insights page presents an incomplete picture of your 's field usage.

Take a look at the Requests and Executions for an example field:

Insights page in Studio

As you can see, they can differ significantly. There are many possible reasons for this, described below.

Objects in lists

Let's say a client executes the following one time:

query GetBooks {
books {
title
}
}

If Query.books returns a list of ten Book objects, then Book.title is resolved ten times. This query, therefore contributes just one request but ten executions to the Book.title field.

Multiple references to a field

Let's say a client executes the following query one time:

query GetTwoBooks {
firstBook: book(id: "123") {
title
}
secondBook: book(id: "345") {
title
}
}

This operation includes two references to the fields Query.book and Book.title. Therefore, the for these fields each execute twice (assuming Query.book doesn't return null). However, these multiple references are all part of a single operation.

Therefore, this query contributes just one request but two executions for each of the Query.book and Book.title fields.

Fields that return interfaces

Let's say our 's schema defines the following interface and :

interface Media {
title: String!
}
type Book implements Media {
title: String!
author: String!
}
type Query {
favoriteMedia: Media!
}

Now, let's say a client executes the following query:

query GetFavoriteMedia {
favoriteMedia {
title
}
}

If Query.favoriteMedia returns a Book object here, then Book.title is resolved one time. However, the original query does not reference Book.title. Instead, it references Media.title, because Query.favoriteMedia has a return type of Media.

Therefore, this query contributes zero requests and one execution for Book.title. It also contributes one request for Media.title. Note that interface fields always have zero executions.

Requested fields that aren't resolved

Let's say a client executes the following query one time:

query GetLoggedInUser {
loggedInUser {
name
}
}

Now, let's say Query.loggedInUser returns null because no user is logged in. In this case, the for User.name never executes, because its parent returns null. Therefore, this query contributes one request and zero executions for User.name.

A requested field might not be resolved for any of these reasons:

  • The field is nested under a field that returns null, as shown above.
  • The field is nested under a field that returns a list, but the list is empty.
  • The field is part of a that doesn't apply to a particular object.
  • The resolver is skipped due to a @skip or @include .

@key and @requires fields in a federated graph

NOTE

This case applies only to that use Apollo Federation.

Let's say our federated graph includes these two :

Products subgraph
type Product @key(fields: "id") {
id: ID!
name: String!
}
Reviews subgraph
extend type Product @key(fields: "id") {
id: ID! @external
}
type Review {
id: ID!
score: Int!
product: Product!
}
type Query {
reviews: [Review!]!
}

Now, let's say a client executes the following query:

query GetAllReviews {
reviews {
score
product {
name
}
}
}

This query's execution starts in the Reviews , but it needs to obtain each Product's name from the Products subgraph. As part of this process, the Products subgraph must resolve references to Products provided by the Reviews subgraph.

To help resolve these references, the Reviews subgraph must return each Product's id field, even though that field isn't included in the original query. This is because id is a @key field for Product.

Therefore, this query contributes zero requests and one execution for Product.id. Similar logic applies to fields that use the @requires directive.

Previous
Operation Metrics
Next
Segmenting by Client
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc., d/b/a Apollo GraphQL.

Privacy Policy

Company