Repository navigation
Add runtime.graphql.cost options to configure GraphQL cost analysis - #3876
Open
Marcus Rangell (marcusrangell) wants to merge 4 commits into
Open
Marcus Rangell (marcusrangell) wants to merge 4 commits into
Marcus Rangell (marcusrangell) wants to merge 4 commits into
Conversation
Adds a cost section to runtime.graphql (enabled, max-field-cost, max-type-cost), configurable in the config file and with dab configure. Cost limits are only enforced when enabled is true. Closes Azure#3748.
Marcus Rangell (marcusrangell)
requested review from
Alekhya-Polavarapu,
Aniruddh Munde (Aniruddh25),
RubenCerna2079,
aaronburtle,
cwebb-msft,
Mohit G (gmohit21),
mhyon,
rusamant,
Sourabh Jain (sourabh1007),
Souvik Ghosh (souvikghosh04),
Stuart Padley (stuartpa) and
vadeveka
as code owners
October 24, 2026 19:59
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Late-configured deployments ignore enabled cost limits, and the schema and converter disagree on accepted values.
3 open issues
What changed in this PR
Adds configurable GraphQL cost limits to DAB, addressing #3748 by allowing users to adjust or disable limits that reject valid queries with HC0047.
Changes:
- Adds
runtime.graphql.costsettings and correspondingdab configureoptions. - Maps settings to Hot Chocolate, making enforcement opt-in while preserving engine defaults for unspecified maximums.
- Adds converter, CLI, and host-level tests, plus schema and CLI documentation updates.
| File | Description |
|---|---|
| src/Service/Startup.cs | Applies cost settings to Hot Chocolate. |
| src/Service.Tests/UnitTests/RuntimeOptionsConverterCoverageTests.cs | Tests serialization, defaults, and invalid values. |
| src/Service.Tests/Configuration/ConfigurationTests.cs | Tests cost enforcement through the GraphQL endpoint. |
| src/Config/RuntimeConfigLoader.cs | Registers the cost-options converter. |
| src/Config/ObjectModel/GraphQLRuntimeOptions.cs | Exposes the optional cost configuration. |
| src/Config/ObjectModel/GraphQLCostOptions.cs | Defines enforcement and maximum-cost settings. |
| src/Config/Converters/GraphQLRuntimeOptionsConverterFactory.cs | Reads and writes the nested cost section. |
| src/Config/Converters/GraphQLCostOptionsConverter.cs | Converts and validates cost settings. |
| src/Cli/ConfigGenerator.cs | Updates cost settings while preserving unspecified values. |
| src/Cli/Commands/ConfigureOptions.cs | Declares the three cost-related CLI options. |
| src/Cli.Tests/ConfigureOptionsTests.cs | Tests CLI updates, defaults, and invalid limits. |
| schemas/dab.draft.schema.json | Defines the cost configuration schema. |
| docs/design/dab-configure.md | Lists the new CLI options. |
Review effort: Balanced
Author
|
@microsoft-github-policy-service agree |
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Why make this change?
HC0047). DAB gave no way to configure or disable this, so requests that are valid but expensive were rejected with no workaround.runtime.graphqlonly haddepth-limit.What is this change?
Adds a
costsection toruntime.graphql, configurable from the config file and fromdab configure:enabled(defaultfalse): whether cost limits are enforced.max-field-cost/max-type-cost: maximum allowed field / type cost of a request. Allowed values: 1 to 2147483647.Behaviour to review
costsection, orenabled: false, DAB no longer enforces cost limits. Previously Hot Chocolate's built-in default limit was always enforced. This matches howdepth-limitworks (off unless configured), but it removes a protection that 2.x had, so I'd like maintainers to confirm this default.enabledis explicit. Setting a maximum on its own does not turn enforcement on, in line with other sections such asruntime.cache.enabled(likeruntime.cache,runtime.healthand the other sections), not Hot Chocolate'sEnforceCostLimits, and the limits are kebab-casemax-*properties likemax-page-size. This keeps the config consistent and independent of the engine's property names, which are mapped to Hot Chocolate inStartup.cs.enabledistrue. Setting onlymax-type-cost, for example, still applies the default field-cost limit.int, likedepth-limit). Hot Chocolate accepts larger values.$schemaURL fail validation until the schema is published. Validation (dab validate, and the validation done on hot reload) downloads the schema named in$schema. A config pointing at an already released schema, e.g..../releases/download/v0.10.23/dab.draft.schema.json, doesn't knowcost, so it is rejected, and on hot reload DAB keeps the previous configuration. This is the same for other options added after that release. It resolves once a release publishes the updateddab.draft.schema.json.Implementation
GraphQLCostOptionsrecord inConfig/ObjectModel, exposed asGraphQLRuntimeOptions.Cost.GraphQLCostOptionsConverter, registered inRuntimeConfigLoaderand used by the GraphQL options converter, the same way asMultipleMutationOptionsConverter.Startup.AddGraphQLServiceapplies the settings with Hot Chocolate'sModifyCostOptions, next to the existing depth-limit rule.dab configure:--runtime.graphql.cost.enabled,--runtime.graphql.cost.max-field-cost,--runtime.graphql.cost.max-type-cost. Like the cache and health options, values below 1 are rejected and there is no way to remove a value from the CLI.dab.draft.schema.json) anddocs/design/dab-configure.mdupdated.How was this tested?
Integration Tests
Unit Tests
Converter tests (round trip, defaults,
enablednot implied by a maximum, all combinations of the three properties, invalid values).dab configuretests (add, update,enablednot implied, all combinations, existing values kept, invalid limits rejected).Host-level test against SQL Server: with
enabled: truea lowmax-field-costormax-type-costrejects the request withHC0047, a high maximum allows it, andenabled: falseor nocostsection allows it.Manually verified on a large real-world config: a low
max-field-costrejects a request that previously failed with the default limit, and a higher value lets it through.Hot reload of the cost settings is not covered by a test and was not verified; a restart applies them reliably.
Sample Request(s)
CLI, setting all three options:
dab configure --runtime.graphql.cost.enabled true --runtime.graphql.cost.max-field-cost 5000 --runtime.graphql.cost.max-type-cost 10000This writes the following to the config file:
With
enabled: trueand a maximum below the request's estimated cost, GraphQL requests are rejected withHC0047("The maximum allowed field cost was exceeded").Follow-up
runtime.graphql.cost(configuration/runtime.mdandcommand-line/dab-configure.mdinMicrosoftDocs/data-api-builder-docs) should be done in a separate PR once this is released.