Use graphql-query-complexity with an Apollo plugin registered in GraphQLModule.forRoot(). The plugin calculates total query complexity before execution and throws a GraphQLError if it exceeds the limit. Annotate expensive fields with @Complexity() to assign custom costs based on child complexity.
Reject queries before execution — complexity analysis runs in didResolveOperation, before any resolvers fire.
simpleEstimator assigns a default cost of 1 per field — a good baseline for most fields.
fieldExtensionsEstimator reads @Complexity() decorators for field-specific costs.
List fields should have higher costs than scalar fields — they multiply with child complexity.
Start with a high limit (e.g. 1000) in development and tune down as you measure real query costs.