Most GraphQL APIs need depth and amount limits, plus timeouts and pagination. Query cost analysis is the most thorough option but harder to build, so add it when your schema has nested relationships that can still be expensive within those limits. Each control blocks a different kind of abusive query.
Three limits, three attacks
GraphQL lets a caller shape the query. OWASP's cheat sheet notes that by default both the depth of a query and the number of objects requested can be unlimited, which may lead to denial of service. Support for limits is not built into the language, so it usually takes a small custom implementation or a library.
Depth limit. Caps how many levels of nesting a query may have. It stops a query that bounces between related types, such as an album that lists songs that list the album again, level after level.
Amount limit. Caps how many items a field may return, for example a request for ninety nine million posts in one call. Pagination with a sensible maximum page size does the same job.
Cost analysis. Gives each field or type a cost and rejects queries whose total is too high. OWASP describes it as the most thorough approach to preventing this kind of denial of service, but also says it is not easy to implement and may not always be necessary.
Comparison
| Control | Blocks | Misses | Effort |
|---|---|---|---|
| Depth limit | Deeply nested loops | Wide, shallow, expensive queries | Low |
| Amount limit or pagination | Huge result sets | Many small expensive fields | Low |
| Cost analysis | Combinations of both | Nothing you forgot to price | Higher |
| Timeout | Long running work | Damage done before it fires | Low |
| Rate limit | Floods of requests | Single huge request | Low to medium |
Timeouts deserve a note. OWASP points out that a timeout may not activate until a bad query has already used a lot of resources, so it is a backstop, not the main control. Application level timeouts that can stop a resolver are usually more effective than a proxy timeout.
How to decide
Start by measuring. One piece of advice quoted in OWASP's cheat sheet is worth repeating: before spending time on cost analysis, try to crash or slow your staging API with a nasty query and see how far you get. If it holds up, cost analysis may not be urgent.
Then work through these steps:
- Set a maximum depth that real clients never exceed. Check your own client queries to find the deepest legitimate one.
- Require pagination on list fields and set a maximum page size.
- Add an application level timeout for operations and resolvers.
- Cap how many operations a single request may batch. Batching is covered in a separate post on GraphQL batching and rate limits.
- Add cost analysis if depth, amount and timeouts still leave an expensive path, for example a field that fans out to many database calls.
- Rate limit in the business logic layer, because a count of HTTP requests does not account for expensive queries or multiple operations in one request.
What to watch out for
Limits that are too tight break real clients. Limits that are too loose do nothing. Review them whenever the schema grows a new relationship, because a new link between types can create a new deep path.
Also remember that these controls protect availability. They do not fix authorization. A cheap query can still read data it should not, which is why field level checks remain separate work.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at how an API scan reports findings so you can tell which issues relate to resource limits.
Quick check
Is a depth limit enough to stop GraphQL denial of service?
No. A shallow query can still request a very large list or touch many expensive fields. Pair depth limits with amount limits, timeouts and rate limits.
Do I need query cost analysis?
Not always. Test your staging API with a heavy query first. If simpler limits hold, cost analysis may be optional. If not, it is the most thorough control.
Safeguard scans your dependencies and SBOMs for known vulnerabilities, including the GraphQL libraries that implement these limits, and uses reachability analysis to show which findings matter. A free scan is at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.