Skip to main content

GraphQL Query Cost Reference

The graphql-limit-count plugin assigns an integer cost to each GraphQL document and evaluates it against the configured quota. Query depth is the default measure. For workloads where depth is a poor estimate of effort, the plugin can instead score the fields and arguments that a document requests.

Cost Strategies​

Choose how the raw cost is calculated with cost_strategy:

StrategyRaw cost
depthSelection nesting depth. This is the default and preserves the behavior of existing configurations.
complexityCost of the operation and every selected field. Each node contributes (sum of its children) × mul + add; both weights default to 1.
node_quantifierCost of decorated nodes with a usable argument listed in mul_arguments. The multiplier carries to deeper quantified nodes. If no node has both a matching decoration and a usable argument, the raw cost is 0.

For example, a decoration that lists first in mul_arguments can use the value from first: 10. Complexity scoring multiplies all descendant cost by 10, while node quantifier scoring carries a multiplier of 10 to deeper quantified nodes.

Charged Cost​

The plugin converts the raw cost into the integer charged against the quota. Complexity and node quantifier scores receive a 0.01 adjustment before scaling and rounding up; depth skips this adjustment.

The score_factor field controls scaling. With its default value of 1, an integer raw cost of 3 is charged as 4, while a raw cost of 0 is charged as 1.

The rate limiter evaluates the charge before applying max_cost, so a query rejected by this threshold may still consume quota. The rejected query returns HTTP 403 before reaching the upstream.

When quota headers are enabled, X-Graphql-Query-Cost reports the charged cost.

Variable Resolution​

Variable resolution is enabled by default. The plugin resolves values supplied with the request, defaults declared by the operation, and argument defaults from the upstream schema before calculating cost.

Disabling resolve_variables treats an argument such as first: $n as absent. This can assign too little cost when a variable supplies the quantifier.

Schema Introspection​

The gateway needs the upstream schema to match cost decorations against a query. Each worker introspects the service on its first applicable request and caches the schema for the worker's lifetime. Reload the gateway after the upstream schema changes.

Set introspection_endpoint when the schema is exposed at a different endpoint. Set introspection_headers when that endpoint requires credentials.

A route is not introspected when it has no service or its service has no cost decorations. In that case, the complexity strategy gives every node its default weight, while the node quantifier strategy produces a raw cost of 0.

Cost Decorations​

Cost decorations assign weights to positions in the upstream schema. They are stored with the service as graphql_cost_decorations. Every route under that service shares them, and they can be changed without editing those routes.

The field_path value can identify a GraphQL type, such as Product; a type and field, such as Product.name; or a chain, such as Query.products.nodes:

FieldEffect
add_valueSets the node's own cost. The default is 1.
mul_valueMultiplies the cost of the node's children.
add_argumentsNames arguments whose values are added to the node's own cost.
mul_argumentsNames arguments whose values multiply descendant cost. Under node_quantifier, the multiplier carries to deeper quantified nodes.

Use each field path only once within a service, and serialize concurrent decoration updates to preserve that uniqueness. In APISIX, manage decorations through the service's graphql_cost_decorations Admin API resource rather than through the service request body. See the Admin API reference for services for request and response schemas.

See GraphQL Limit Count Configuration for the plugin fields that control cost calculation and schema introspection.