Proxy · Override subgraph config

Subgraph Overrides — One Router Config Across All

Register cluster-internal, localhost, and custom subgraph addresses once. The router uses the right address for each environment without separate config files.

No redeployment. No URL templating. One router config for every environment.

One execution config · many environments

Execution configcanonical subgraph URLs
Router · Devlocalhost · overrides
Router · Stagingcluster DNS
Router · Prodcluster DNS

Available onFreeProEnterprise

The problem

Canonical URLs are not always the right hop

Inside the cluster, through ingress, or on a laptop, routing should match the network, not duplicate configs.

Public URLs aren't the right routing target inside a cluster

A subgraph registered as `https://products.example.com/graphql` should not be called that way from inside the same Kubernetes cluster. Routing through the public ingress costs latency, egress fees, and sometimes fails when traffic leaves the cluster only to come back in (NAT hairpinning).

Separate router configs per environment fall out of sync

When dev, staging, and prod each carry their own YAML, it is easy to change one file and miss the others. Small mismatches add up until comparing configs is mostly churn—and real mistakes get harder to spot.

URL templating inside the config is a workaround, not a fix

`${SUBGRAPH_URL_PRODUCTS}` chained across a dozen services turns a federation config into a string-substitution exercise. The router can't tell you what URL it's actually using without you resolving the template by hand.

Our solution

One config file, different subgraph addresses per environment

Subgraph overrides live in router YAML: per subgraph, you swap the execution-config URL for the hop that actually works on that machine or cluster. The list below is the field reference; anything you omit keeps its value from the execution config.

Overrides cover

  • routing_url replaces the query/mutation URL from the execution config
  • subscription_url replaces the subscription URL independently
  • subscription_protocol: ws, sse, or sse_post
  • subscription_websocket_subprotocol ( graphql-ws, graphql-transport-ws, or auto)

Why it works

  1. You publish one execution config; each router applies only the overrides it defines—cluster-internal DNS in Kubernetes, localhost on a laptop, and so on—without forking the whole file per environment.

  2. Canonical URLs stay on the control plane for publishing and validation; overrides change only how that router instance reaches subgraphs at runtime.

Overrides

Before & After

Before CosmoWith Cosmo
Separate router config per environmentOne config, local overrides per environment
Complex URL templating chainsPlain YAML with per-subgraph entries
Control-plane URL and runtime URL mismatch hiddenClear separation: canonical in control plane, local at runtime
Manual coordination when a URL changesEach environment updates independently

Operations

Reload without drift

Overrides live in router config; when they change, the next reload applies new routing with the same graceful handoff as Config Hot Reload.

How subgraph overrides work

01
Canonical URLs preserved upstream.

Router loads the execution config

Execution config comes from the control plane with all registered subgraph URLs.

02
Per subgraph, per environment.

Apply local overrides

If an override exists for a subgraph, the router replaces the execution-config URL with the override value.

03
Routing only; schema unchanged.

Route requests to the override target

Queries, mutations, and subscriptions go to the override URL.

04
Same handoff as config hot reload.

Reload picks up changes

When the override config changes, the router applies the new routing on its next reload without dropping traffic.

Route subgraphs for the network you are in

One config file: local overrides for dev, staging, and production.

FAQ

Override subgraph config

More detail in the override subgraph config documentation.