Skip to content

chore(deps): update dependency apollographql/router to v2.12.0#68

Merged
renovate[bot] merged 1 commit intomainfrom
renovate/apollographql-router-2.x
Mar 2, 2026
Merged

chore(deps): update dependency apollographql/router to v2.12.0#68
renovate[bot] merged 1 commit intomainfrom
renovate/apollographql-router-2.x

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Dec 13, 2025

This PR contains the following updates:

Package Update Change
apollographql/router minor 2.10.02.12.0

Release Notes

apollographql/router (apollographql/router)

v2.12.0

Compare Source

🚀 Features
Support Unix domain socket (UDS) communication for coprocessors (Issue #​5739)

Many coprocessor deployments run side-by-side with the router, typically on the same host (for example, within the same Kubernetes pod).

This change brings coprocessor communication to parity with subgraphs by adding Unix domain socket (UDS) support. When the router and coprocessor are co-located, communicating over a Unix domain socket bypasses the full TCP/IP network stack and uses shared host memory instead, which can meaningfully reduce latency compared to HTTP.

By @​theJC in #​8348

Add redact_query_validation_errors supergraph config option (PR #​8888)

The new redact_query_validation_errors option in the supergraph configuration section replaces all query validation errors with a single generic error:

{
  "message": "invalid query",
  "extensions": {
    "code": "UNKNOWN_ERROR"
  }
}

By @​phryneas in #​8888

Support multiple @listSize directives on the same field (PR #​8872)

[!WARNING]

Multiple @listSize directives on a field only take effect after Federation supports repeatable @listSize in the supergraph schema. Until then, composition continues to expose at most one directive per field. This change makes the router ready for that Federation release.

The router now supports multiple @listSize directives on a single field, enabling more flexible cost estimation when directives from different subgraphs are combined during federation composition.

  • The router processes all @listSize directives on a field (stored as Vec<ListSizeDirective> instead of Option<ListSizeDirective>).
  • When multiple directives specify assumedSize values, the router uses the maximum value for cost calculation.
  • Existing schemas with single directives continue to work exactly as before.

This change prepares the router for federation's upcoming support for repeatable @listSize directives, and maintains full compatibility with current non-repeatable directive schemas.

By @​cmorris in #​8872

Add parser recursion and lexical token metrics (PR #​8845)

The router now emits two new metrics: apollo.router.operations.recursion for the recursion level reached, and apollo.router.operations.lexical_tokens for the number of lexical tokens in a query.

By @​jhrldev in #​8845

Support subgraph-level demand control (PR #​8829)

Subgraph-level demand control lets you enforce per-subgraph query cost limits in the router, in addition to the existing global cost limit for the whole supergraph. This helps you protect specific backend services that have different capacity or cost profiles from being overwhelmed by expensive operations.

When a subgraph-specific cost limit is exceeded, the router:

  • Still runs the rest of the operation, including other subgraphs whose cost is within limits.
  • Skips calls to only the over-budget subgraph, and composes the response as if that subgraph had returned null, instead of rejecting the entire query.

Per-subgraph limits apply to the total work for that subgraph in a single operation. For each request, the router tracks the aggregate estimated cost per subgraph across the entire query plan. If the same subgraph is fetched multiple times (for example, through entity lookups, nested fetches, or conditional branches), those costs are summed together and the subgraph's limit is enforced against that total.

Configuration
demand_control:
  enabled: true
  mode: enforce
  strategy:
    static_estimated:
      max: 10
      list_size: 10
      actual_cost_mode: by_subgraph
      subgraphs: # everything from here down is new (all fields optional)
        all:
          max: 8
          list_size: 10
        subgraphs:
          products:
            max: 6
            # list_size omitted, 10 implied because of all.list_size
          reviews:
            list_size: 50
            # max omitted, 8 implied because of all.max
Example

Consider a topProducts query that fetches a list of products from a products subgraph and then performs an entity lookup for each product in a reviews subgraph. Assume the products cost is 10 and the reviews cost is 5, leading to a total estimated cost of 15 (10 + 5).

Previously, you could only restrict that query via demand_control.static_estimated.max:

  • If you set it to 15 or higher, the query executes.
  • If you set it below 15, the query is rejected.

Subgraph-level demand control enables much more granular control. In addition to demand_control.static_estimated.max, which operates as before, you can also set per-subgraph limits.

For example, if you set max = 20 and reviews.max = 2, the query passes the aggregate check (15 < 20) and executes on the products subgraph (no limit specified), but doesn't execute against the reviews subgraph (5 > 2). The result is composed as if the reviews subgraph had returned null.

By @​carodewig in #​8829

Improve @listSize directive parsing and nested path support (PR #​8893)

Demand control cost calculation now supports:

  • Array-style parsing for @listSize sizing (for example, list arguments)
  • Nested input paths when resolving list size from query arguments
  • Nested field paths in the sizedFields argument on @listSize for more accurate cost estimation

These changes are backward compatible with existing schemas and directives.

By @​cmorris in #​8893

Add coprocessor hooks for connector request and response stages (PR #​8869)

You can now configure a coprocessor hook for the ConnectorRequest and ConnectorResponse stages of the router lifecycle.

coprocessor:
  url: http://localhost:3007
  connector:
    all:
      request:
        uri: true
        headers: true
        body: true
        context: all
        service_name: true
      response:
        headers: true
        body: true
        context: all
        service_name: true

By @​andrewmcgivery in #​8869

🐛 Fixes
Pass variables to introspection queries (PR #​8816)

Introspection queries now receive variables, enabling @include and @skip directives during introspection.

By @​jephuff in #​8816

Log warning instead of returning error for non-UTF-8 headers in externalize_header_map (PR #​8828)
  • The router now emits a warning log with the name of the header instead of returning an error.
  • The remaining valid headers are returned, which is more consistent with the router's default behavior when a coprocessor isn't used.

By @​rohan-b99 in #​8828

Place http_client span attributes on the http_request span (PR #​8798)

Attributes configured under telemetry.instrumentation.spans.http_client are now added to the http_request span instead of subgraph_request.

Given this config:

telemetry:
  instrumentation:
    spans:
      http_client:
        attributes:
          http.request.header.content-type:
            request_header: "content-type"
          http.response.header.content-type:
            response_header: "content-type"

Both attributes are now placed on the http_request span.

By @​rohan-b99 in #​8798

Validate ObjectValue variable fields against input type definitions (PR #​8821 and PR #​8884)

The router now validates individual fields of input object variables against their type definitions. Previously, variable validation checked that the variable itself was present but didn't validate the fields within the object.

Example:

## schema ##
input MessageInput {
    content: String
    author: String
}
type Receipt {
    id: ID!
}
type Query{
    send(message: MessageInput): Receipt
}

## query ##
query(: MessageInput) {
    send(message: ) {
        id
    }
}

## input variables ##
{"msg":
    {
    "content": "Hello",
    "author": "Me",
    "unknownField": "unknown",
    }
}

This request previously passed validation because the variable msg was present in the input, but the fields of msg weren't validated against the MessageInput type.

[!WARNING]
To opt out of this behavior, set the supergraph.strict_variable_validation config option to measure.

Enabled:

supergraph:
  strict_variable_validation: enforce

Disabled:

supergraph:
  strict_variable_validation: measure

By @​conwuegb in #​8821 and #​8884

Increase internal Redis timeout from 5s to 10s (PR #​8863)

Because mTLS handshakes can be slow in some environments, the internal Redis timeout is now 10s (previously 5s). The connection "unresponsive" threshold is also increased from 5s to 10s.

By @​aaronarinder in #​8863

Enforce and log operation limits for cached query plans (PR #​8810)

The router now logs the operation-limits warning for cached query plans as well, ensuring the query text is included whenever limits are exceeded. This also fixes a case where a cached plan could bypass enforcement after changing warn_only from true to false during a hot reload.

By @​rohan-b99 in #​8810

Prevent duplicate content-type headers in connectors (PR #​8867)

When you override the content-type header in a connector @source directive, the router no longer appends the default value. The custom header value now properly replaces the default.

For example:

@&#8203;source(
    name: "datasetInsightsAPI"
    http: {
        headers: [
            { name: "Content-Type", value: "application/vnd.iaas.v1+json" },
        ]
    }
)

Previously resulted in:

content-type: application/json, application/vnd.iaas.v1+json

Now correctly results in:

content-type: application/vnd.iaas.v1+json

By @​andrewmcgivery in #​8867

Prevent duplicate tags in router spans added by dynamic attributes (PR #​8865)

When dynamic attributes are added via SpanDynAttribute::insert, SpanDynAttribute::extend, LogAttributes::insert, LogAttributes::extend, EventAttributes::insert, or EventAttributes::extend and the key already exists, the router now replaces the existing value instead of creating duplicate attributes.

By @​rohan-b99 in #​8865

Compute actual demand control costs across all subgraph fetches (PR #​8827)

The demand control feature estimates query costs by summing together the cost of each subgraph operation, capturing any intermediate work that must be completed to return a complete response.

Previously, the actual query cost computation only considered the final response shape and didn't include any of the intermediate work in its total.

The router now computes the actual query cost as the sum of all subgraph response costs. This more accurately reflects the work done per operation and enables a more meaningful comparison between actual and estimated costs.

To disable the new actual cost computation behavior, set the router configuration option demand_control.strategy.static_estimated.actual_cost_mode to response_shape:

demand_control:
  enabled: true
  mode: enforce
  strategy:
    static_estimated:
      max: 10
      list_size: 10
      actual_cost_mode: by_subgraph # the default value
      # actual_cost_mode: response_shape # revert to prior actual cost computation mode

By @​carodewig in #​8827

📚 Documentation
Correct response caching FAQ for schema updates and multi-root-field caching (PR #​8794)

Updated the response caching FAQ to accurately describe caching behavior:

  • Clarify that schema updates generate new cache keys, so old entries don't receive cache hits (effectively expired from your perspective) instead of implying stale data might be served.
  • Correct the multi-root-field caching explanation to state that the router caches the entire subgraph response as a single unit, not separately per root field.
  • Add clarification that the configured TTL is a fallback when subgraph responses don't include Cache-Control: max-age headers.
  • Change example TTL from 300s to 5m for better readability.

By @​the-gigi-apollo in #​8794

v2.11.0

Compare Source

🚀 Features
Support client awareness metadata via HTTP headers (PR #​8503)

Clients can now send library name and version metadata for client awareness and enhanced client awareness using HTTP headers. This provides a consistent transport mechanism instead of splitting values between headers and request.extensions.

By @​calvincestari in #​8503

Reload OCI artifacts when a tag reference changes (PR #​8805)

You can now configure tag-based OCI references in the router. When you use a tag reference such as artifacts.apollographql.com/my-org/my-graph:prod, the router polls and reloads when that tag points to a new artifact.

This also applies to automatically generated variant tags and custom tags.

By @​graytonio in #​8805

Add memory limit option for cooperative cancellation (PR #​8808)

The router now supports a memory_limit option on experimental_cooperative_cancellation to cap memory allocations during query planning. When the memory limit is exceeded, the router:

  • In enforce mode, cancels query planning and returns an error to the client.
  • In measure mode, records the cancellation outcome in metrics and allows query planning to complete.

The memory limit works alongside the existing timeout option. Whichever limit is reached first triggers cancellation.

This feature is only available on Unix platforms when the global-allocator feature is enabled and dhat-heap is not enabled.

Example configuration:

supergraph:
  query_planning:
    experimental_cooperative_cancellation:
      enabled: true
      mode: enforce  # or "measure" to only record metrics
      memory_limit: 50mb  # Supports formats like "50mb", "1gb", "1024kb", etc.
      timeout: 5s  # Optional: can be combined with memory_limit

By @​rohan-b99 in #​8808

Add memory tracking metrics for requests (PR #​8717)

The router now emits two histogram metrics to track memory allocation activity during request processing:

  • apollo.router.request.memory: Memory activity across the full request lifecycle (including parsing, validation, query planning, and plugins)
  • apollo.router.query_planner.memory: Memory activity for query planning work in the compute job thread pool

Each metric includes:

  • allocation.type: allocated, deallocated, zeroed, or reallocated
  • context: The tracking context name (for example, router.request or query_planning)

This feature is only available on Unix platforms when the global-allocator feature is enabled and dhat-heap is not enabled.

By @​rohan-b99 in #​8717

🐛 Fixes
Support nullable @key fields in response caching (PR #​8767)

Response caching can now use nullable @key fields. Previously, the response caching feature rejected nullable @key fields, which prevented caching in schemas that use them.

When you cache data keyed by nullable fields, keep your cache keys simple and avoid ambiguous null values.

By @​aaronArinder in #​8767

Return 429 instead of 503 when enforcing a rate limit (PR #​8765)

In v2.0.0, the router changed the rate-limiting error from 429 (TOO_MANY_REQUESTS) to 503 (SERVICE_UNAVAILABLE). This change restores 429 to align with the router error documentation.

By @​carodewig in #​8765

Add status code and error type attributes to http_request spans (PR #​8775)

The router now always adds the http.response.status_code attribute to http_request spans (for example, for router -> subgraph requests). The router also conditionally adds error.type for non-success status codes.

By @​rohan-b99 in #​8775

Report response cache invalidation failures as errors (PR #​8813)

The router now returns an error when response cache invalidation fails. Previously, an invalidation attempt could fail without being surfaced as an error.

After you upgrade, you might see an increase in the apollo.router.operations.response_cache.invalidation.error metric.

By @​bnjjj in #​8813

Reuse response cache Redis connections for identical subgraph configuration (PR #​8764)

The response cache now reuses Redis connection pools when subgraph-level configuration resolves to the same Redis configuration as the global all setting. Previously, the router could create redundant Redis connections even when the effective configuration was identical.

Impact: If you configure response caching at both the global and subgraph levels, you should see fewer Redis connections and lower connection overhead.

By @​bnjjj in #​8764

Prevent TLS connections from hanging when a handshake stalls (PR #​8779)

The router listener loop no longer blocks while waiting for a TLS handshake to complete. Use server.http.tls_handshake_timeout to control how long the router waits before terminating a connection (default: 10s).

By @​rohan-b99 in #​8779

Emit cardinality overflow metrics for more OpenTelemetry error formats (PR #​8740)

The router now emits the apollo.router.telemetry.metrics.cardinality_overflow metric for additional OpenTelemetry cardinality overflow error formats.

By @​bonnici in #​8740

Propagate trace context on WebSocket upgrade requests (PR #​8739)

The router now injects trace propagation headers into the initial HTTP upgrade request when it opens WebSocket connections to subgraphs. This preserves distributed trace continuity between the router and subgraph services.

Trace propagation happens during the HTTP handshake only. After the WebSocket connection is established, headers cannot be added to individual messages.

By @​theJC in #​8739

Stop query planning compute jobs when the parent task is canceled (PR #​8741)

Query planning compute jobs now stop when cooperative cancellation cancels the parent task.

By @​rohan-b99 in #​8741

Reject invalidation requests with unknown fields (PR #​8752)

The response cache invalidation endpoint now rejects request payloads that include unknown fields. When unknown fields are present, the router returns HTTP 400 (Bad Request).

By @​bnjjj in #​8752

Restore plugin access to SubscriptionTaskParams in execution::Request builders (PR #​8771)

Plugins and other external crates can use SubscriptionTaskParams with execution::Request builders again. This restores compatibility for plugin unit tests that construct subscription requests.

By @​aaronArinder in #​8771

Support JWT tokens with multiple audiences (PR #​8780)

When issuers or audiences is included in the router's JWK configuration, the router will check each request's JWT for iss or aud and reject requests with mismatches.

Expected behavior:

  • If present, the iss claim must be specified as a string.
    • ✅ The JWK's issuers is empty.
    • ✅ The iss is a string and is present in the JWK's issuers.
    • ✅ The iss is null.
    • ❌ The iss is a string but is not present in the JWK's issuers.
    • ❌ The iss is not a string or null.
  • If present, the aud claim can be specified as either a string or an array of strings.
    • ✅ The JWK's audiences is empty.
    • ✅ The aud is a string and is present in the JWK's audiences.
    • ✅ The aud is an array of strings and at least one of those strings is present in the JWK's audiences.
    • ❌ The aud is not a string or array of strings (i.e., null).

Behavior prior to this change:

  • If the iss was not null or a string, it was permitted (regardless of its value).
  • If the aud was an array, it was rejected (regardless of its value).

By @​carodewig in #​8780

Enforce feature restrictions for warning-state licenses (PR #​8768)

The router now enforces license restrictions even when a license is in a warning state. Previously, warning-state licenses could bypass enforcement for restricted features.

If your deployment uses restricted features, the router returns an error instead of continuing to run.

By @​aaronArinder in #​8768

🛠 Maintenance
Warn at startup when OTEL_EXPORTER_OTLP_ENDPOINT is set (PR #​8729)

The router now displays a warning at startup if the OTEL_EXPORTER_OTLP_ENDPOINT environment variable is set. This variable takes precedence over default configurations and can override trace export to Apollo Studio, so the warning helps you identify when telemetry data might not be sent where expected.

By @​apollo-mateuswgoettems in #​8729

Increase Redis 'unresponsive' check frequency (PR #​8763)

Perform the 'unresponsive' check every two seconds. This aligns with the Redis client's guideline that the check interval should be less than half the timeout value.

By @​carodewig in #​8763

📚 Documentation
Fix subscription licensing discrepancy in documentation (PR #​8726)

Corrected the subscription support documentation to reflect that subscriptions are available on all GraphOS plans (Free, Developer, Standard, and Enterprise) with self-hosted routers.

The documentation previously stated that subscription support was an Enterprise-only feature for self-hosted routers, which was incorrect. Subscriptions are a licensed feature available to all GraphOS plans when the router is connected to GraphOS with an API key and graph ref.

Updated both the configuration and overview pages to remove the misleading Enterprise-only requirement and clarify the actual requirements.

By @​the-gigi-apollo in #​8726

Clarify traffic shaping compression headers in documentation (PR #​8773)

The traffic shaping documentation now clearly explains how the router handles HTTP compression headers for subgraph requests. It clarifies that content-encoding is set when compression is configured via traffic_shaping, while accept-encoding is automatically set on all subgraph requests to indicate the router can accept compressed responses (gzip, br, or deflate). The documentation also notes that these headers are added after requests are added to the debug stack, so they won't appear in the Connectors Debugger.

By @​the-gigi-apollo in #​8773

Document default histogram buckets and their relationship to timeout settings (PR #​8783)

The documentation now explains how histogram bucket configuration affects timeout monitoring in Prometheus and other metrics exporters.

The documentation now includes:

  • Default bucket values: The router's default histogram buckets (0.001 to 10.0 seconds)
  • Timeout behavior: Histogram metrics cap values at the highest bucket boundary, which can make timeouts appear ignored if they exceed ten seconds
  • Customization guidance: Configure custom buckets via telemetry.exporters.metrics.common.buckets to match your timeout settings

This update helps users understand why their timeout metrics may not behave as expected and provides clear guidance on customizing buckets for applications with longer timeout configurations.

By @​the-gigi-apollo in #​8783


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot enabled auto-merge (squash) December 13, 2025 22:03
@renovate renovate bot force-pushed the renovate/apollographql-router-2.x branch from fcceaa8 to 94683ee Compare January 14, 2026 21:43
@renovate renovate bot changed the title chore(deps): update dependency apollographql/router to v2.10.0 chore(deps): update dependency apollographql/router to v2.10.0 - autoclosed Jan 26, 2026
@renovate renovate bot closed this Jan 26, 2026
auto-merge was automatically disabled January 26, 2026 22:09

Pull request was closed

@renovate renovate bot deleted the renovate/apollographql-router-2.x branch January 26, 2026 22:09
@renovate renovate bot changed the title chore(deps): update dependency apollographql/router to v2.10.0 - autoclosed chore(deps): update dependency apollographql/router to v2.11.0 Jan 27, 2026
@renovate renovate bot reopened this Jan 27, 2026
@renovate renovate bot enabled auto-merge (squash) January 27, 2026 21:49
@renovate renovate bot force-pushed the renovate/apollographql-router-2.x branch from 94683ee to 53d4800 Compare January 27, 2026 21:49
@renovate renovate bot force-pushed the renovate/apollographql-router-2.x branch 2 times, most recently from a045883 to 58a7675 Compare February 24, 2026 19:51
@renovate renovate bot changed the title chore(deps): update dependency apollographql/router to v2.11.0 chore(deps): update dependency apollographql/router to v2.12.0 Feb 24, 2026
@gijs-martens
Copy link

gijs-martens commented Feb 25, 2026

@gocamille any chance this could be looked at?
Currently the apollo-runtime container is 2 minor versions behind on the router.

@renovate renovate bot force-pushed the renovate/apollographql-router-2.x branch 3 times, most recently from 11f147b to d02c3fc Compare March 2, 2026 09:33
@jonathanrainer jonathanrainer force-pushed the renovate/apollographql-router-2.x branch from d02c3fc to a31a2a3 Compare March 2, 2026 09:38
Copy link
Contributor

@jonathanrainer jonathanrainer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@renovate renovate bot merged commit e3ff52e into main Mar 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants