Skip to content

feat: expose costs#2470

Merged
ysmolski merged 137 commits intomainfrom
yury/eng-8636-router-expose-the-static-cost-to-the-middleware
Mar 17, 2026
Merged

feat: expose costs#2470
ysmolski merged 137 commits intomainfrom
yury/eng-8636-router-expose-the-static-cost-to-the-middleware

Conversation

@ysmolski
Copy link
Copy Markdown
Contributor

@ysmolski ysmolski commented Jan 27, 2026

Integrate static and dynamic cost calculation into the router.
Expose the static (estimated) cost value in the modules.
Expose both costs via telemetry and response headers.

Metrics for costs should be enabled individually in the corresponding telemetry section.

Composition was reviewed in another PR and merged here.

I have added end-to-end benchmark for a big query to measure the impact of cost control:

     │ SequentialBig │     SequentialBigCostAnalysis      │
     │    sec/op     │   sec/op     vs base               │
*-14     584.1µ ± 0%   586.7µ ± 0%  +0.45% (p=0.000 n=40)

     │ SequentialBig │      SequentialBigCostAnalysis      │
     │      B/s      │     B/s       vs base               │
*-14    5.527Mi ± 0%   5.503Mi ± 0%  -0.43% (p=0.000 n=40)

     │ SequentialBig │   SequentialBigCostAnalysis    │
     │     B/op      │     B/op      vs base          │
*-14    456.1Ki ± 0%   456.1Ki ± 0%  ~ (p=0.822 n=40)

     │ SequentialBig │     SequentialBigCostAnalysis      │
     │   allocs/op   │  allocs/op   vs base               │
*-14     6.444k ± 0%   6.452k ± 0%  +0.12% (p=0.000 n=40)

Fixes ENG-8844
Fixes ENG-8986

Summary by CodeRabbit

  • New Features

    • Cost control: measure or enforce GraphQL operation costs, with optional response headers and static validation to block over-limit queries.
    • Support for @cost and @listsize directives across composition, federation, and router; propagated through subgraph composition.
  • Configuration

    • cost_control options (enabled, mode, max_estimated_limit, estimated_list_size, expose_headers) and CostStats toggles.
  • Metrics

    • New estimated and actual operation cost histograms and recording APIs.
  • Tests / Docs

    • Extensive directive and cost integration tests; composition architecture docs added.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds end-to-end cost control: new @cost and @listSize directives in composition and demo schemas, propagates cost metadata through composition and datasource configs, adds CostControl/CostStats config, enforces static-cost during planning/execution, emits cost metrics, exposes optional cost headers, and adds extensive tests.

Changes

Cohort / File(s) Summary
Composition: directives, normalization & types
composition/src/v1/constants/..., composition/src/v1/normalization/..., composition/src/normalization/..., composition/src/schema-building/utils.ts, composition/src/utils/string-constants.ts
Introduce @cost and @listSize directive definitions, new Costs types and constants, helpers to detect list types, normalization handlers to extract/validate directive args, and propagate costs through normalization results.
Composition: federation & wiring
composition/src/v1/federation/federation-factory.ts, composition/src/subgraph/types.ts, shared/src/router-config/builder.ts
Propagate per-subgraph costs into federation results and add costs -> data-source costConfiguration mapping to composed router config.
Composition: tests & docs
composition/tests/v1/directives/*, composition/tests/v1/utils/utils.ts, composition/ARCHITECTURE.md, composition/README.md
Add comprehensive Vitest suites for @cost/@listSize, test utilities, and an architecture/onboarding doc.
Router core: cost plumbing & enforcement
router/core/context.go, router/core/operation_processor.go, router/core/operation_planner.go, router/core/executor.go, router/core/factoryresolver.go, router/core/graphql_prehandler.go, router/core/graphql_handler.go, router/core/websocket.go, router/core/header_rule_engine.go, router/core/operation_metrics.go, router/core/router.go, router/core/plan_generator.go
Add OperationContext.Cost API and OperationCost type; thread plan configuration and CostControl through planner/executor/processor/factory; add static-cost validation and enforcement, cost header wiring/callbacks, and record estimated/actual cost in operation metrics.
Metrics: histograms & stores
router/pkg/metric/measurements.go, router/pkg/metric/metric_store.go, router/pkg/metric/metric_store_test.go, router/pkg/metric/noop_metrics.go, router/pkg/metric/otlp_metric_store.go, router/pkg/metric/prom_metric_store.go, router/pkg/metric/config.go
Add OperationCostEstimated and OperationCostActual histograms and options, CostStats toggles, provider/store API surface and implementations for OTLP/Prometheus, conditional metric creation, and tests exercising histograms.
Config: cost controls & schema
router/pkg/config/config.go, router/pkg/config/config.schema.json, router/pkg/config/fixtures/full.yaml, router/pkg/config/testdata/*
Introduce CostControl and CostStats types/fields, add cost_control schema under complexity_limits, update fixtures and testdata to include cost settings.
Proto / connect / client bindings
proto/wg/cosmo/node/v1/node.proto, connect/src/wg/cosmo/node/v1/node_pb.ts
Add CostConfiguration, FieldWeightConfiguration, FieldListSizeConfiguration messages and extend DataSourceConfiguration with optional cost_configuration; regenerate connect bindings.
Demo schemas & CLI compose
demo/pkg/subgraphs/*/schema.graphqls, cli/src/commands/router/commands/compose.ts
Annotate demo subgraphs with new directives and propagate costs field through compose output.
Tests & test harness
router-tests/costs_test.go, router-tests/modules/verify-cost-control/module.go, router-tests/modules/verify_cost_control_test.go, router-tests/testenv/testenv.go, router-tests/integration_test.go, router-tests/go.mod, router-tests/modules/*_test.go
Add large integration tests covering enforcement, header exposure, and metrics; introduce verify-cost-control module to capture OperationCost; thread CostStats through testenv; add benchmark variants and small package test package renames.
Misc & formatting
router/pkg/plan_generator/plan_generator_test.go, composition/tsconfig.json, composition/vite.config.ts
Import/order tweaks, formatting and assertion-order adjustments, and minor whitespace edits.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: expose costs' is concise and directly relates to the main objective of the PR, which is to expose cost calculation (both estimated and actual) throughout the system.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@ysmolski ysmolski marked this pull request as draft January 27, 2026 10:14
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 27, 2026

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-f02ee6553db4be92bbc468eff1f484758d901ffe

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 27, 2026

Codecov Report

❌ Patch coverage is 8.88889% with 123 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.17%. Comparing base (360bee4) to head (7656c45).

Files with missing lines Patch % Lines
router/pkg/metric/metric_store.go 0.00% 33 Missing ⚠️
router/pkg/metric/measurements.go 0.00% 25 Missing ⚠️
router/core/operation_processor.go 27.77% 13 Missing ⚠️
router/core/context.go 0.00% 9 Missing ⚠️
router/pkg/metric/otlp_metric_store.go 0.00% 9 Missing ⚠️
router/pkg/metric/prom_metric_store.go 0.00% 9 Missing ⚠️
router/core/operation_metrics.go 11.11% 7 Missing and 1 partial ⚠️
router/core/router.go 0.00% 4 Missing and 1 partial ⚠️
router/core/executor.go 0.00% 2 Missing and 1 partial ⚠️
router/pkg/metric/noop_metrics.go 0.00% 3 Missing ⚠️
... and 3 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2470       +/-   ##
===========================================
- Coverage   61.79%   24.17%   -37.62%     
===========================================
  Files         231      213       -18     
  Lines       24143    23652      -491     
===========================================
- Hits        14919     5718     -9201     
- Misses       7980    17129     +9149     
+ Partials     1244      805      -439     
Files with missing lines Coverage Δ
router/core/factoryresolver.go 54.75% <100.00%> (-24.06%) ⬇️
router/core/graphql_handler.go 33.88% <100.00%> (-35.35%) ⬇️
router/core/modules.go 4.54% <ø> (-63.64%) ⬇️
router/core/operation_planner.go 47.36% <100.00%> (-20.64%) ⬇️
router/pkg/config/config.go 7.79% <ø> (-72.73%) ⬇️
router/pkg/metric/config.go 67.50% <ø> (ø)
router/core/graph_server.go 50.74% <50.00%> (-32.07%) ⬇️
router/core/graphql_prehandler.go 40.20% <0.00%> (-43.04%) ⬇️
router/core/websocket.go 55.77% <0.00%> (-20.38%) ⬇️
router/core/executor.go 70.83% <0.00%> (-15.50%) ⬇️
... and 9 more

... and 182 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ysmolski ysmolski requested a review from endigma March 13, 2026 10:11
@ysmolski ysmolski requested a review from StarpTech March 16, 2026 15:57
Copy link
Copy Markdown
Contributor

@StarpTech StarpTech left a comment

Choose a reason for hiding this comment

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

LGTM

@ysmolski ysmolski merged commit d43aa40 into main Mar 17, 2026
70 of 72 checks passed
@ysmolski ysmolski deleted the yury/eng-8636-router-expose-the-static-cost-to-the-middleware branch March 17, 2026 14:07
Noroth pushed a commit that referenced this pull request Mar 18, 2026
Integrate static and dynamic cost calculation into the router. 
Expose the static (estimated) cost value in the modules.
Expose both costs via telemetry and response headers.

Metrics for costs should be enabled individually in the corresponding telemetry section.

Composition was reviewed in another PR and merged here.

End-to-end benchmark for a big query to measure the impact of cost control:

     │ SequentialBig │     SequentialBigCostAnalysis      │
     │    sec/op     │   sec/op     vs base               │
*-14     584.1µ ± 0%   586.7µ ± 0%  +0.45% (p=0.000 n=40)

     │ SequentialBig │      SequentialBigCostAnalysis      │
     │      B/s      │     B/s       vs base               │
*-14    5.527Mi ± 0%   5.503Mi ± 0%  -0.43% (p=0.000 n=40)

     │ SequentialBig │   SequentialBigCostAnalysis    │
     │     B/op      │     B/op      vs base          │
*-14    456.1Ki ± 0%   456.1Ki ± 0%  ~ (p=0.822 n=40)

     │ SequentialBig │     SequentialBigCostAnalysis      │
     │   allocs/op   │  allocs/op   vs base               │
*-14     6.444k ± 0%   6.452k ± 0%  +0.12% (p=0.000 n=40)

Fixes ENG-8844
Fixes ENG-8986

Co-authored-by: Aenimus <47415099+Aenimus@users.noreply.github.com>
Co-authored-by: StarpTech <deusdustin@gmail.com>
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.

5 participants