graphql-query-complexity
Query complexity analysis and validation to protect graphql-js servers
Repository Health
Technical Analysis
graphql-query-complexity is a validation library for graphql-js that calculates the cost of an incoming GraphQL query and rejects it if it exceeds a configured maximum. By scoring queries before they execute, it protects GraphQL servers from resource exhaustion and denial-of-service attacks driven by deeply nested or expensive queries.
Complexity is computed through composable estimators, letting teams assign fixed costs, schema directives, or fully custom per-field logic, and integrate the result as a standard validation rule with graphql-js, express-graphql, and similar servers.
What You Get
- A drop-in validation rule (createComplexityRule) with a configurable maximumComplexity
- Built-in estimators: simpleEstimator, directiveEstimator, and fieldExtensionsEstimator
- A getComplexity helper to compute cost outside the validation phase
- Hooks like onComplete and createError for logging, rate limiting, and custom errors
Common Use Cases
- Rejecting overly deep or expensive queries to prevent DoS attacks
- Assigning per-field cost via schema directives or field extensions
- Measuring query complexity in a resolver for logging or rate limiting
Under The Hood
Architecture - The core QueryComplexity class implements a graphql-js ValidationRule visitor that walks the query AST, resolving each field’s cost by running the configured estimator chain (the first estimator to return a number wins) and summing child complexity bottom-up. createComplexityRule wraps it for the validation phase, while getComplexity exposes the same computation standalone. Estimators live under src/estimators as independent modules.
Tech Stack - Written in TypeScript, targeting the graphql-js reference implementation as its sole peer dependency. It ships compiled type definitions and is framework-agnostic, working with express-graphql and any server that accepts graphql-js validation rules.
Code Quality - The repo has a thorough test suite (QueryComplexity-test plus per-estimator tests under tests with schema fixtures), ESLint configuration, and a 19-release history with active maintenance. Each estimator ships its own README documenting configuration.
API Design - The API is small and composition-oriented: configure a maximum, supply an ordered list of estimators, and optionally hook onComplete/createError. Custom estimators are a single function receiving type, field, node, args, and childComplexity, which keeps extension approachable while the defaults cover common cases.