Most servers implement a heuristic for "query cost/complexity" with a configurable max. At the time the query is parsed, its cost is determined based on the heuristic and if it is over the max, the query is rejected.
An adversary is going to utilize more than a single query. It mostly protects against well intentioned folks.
Other forms of protection such as rate limiting are needed for threat models that involve an adversary.
The same problems exist with REST but there it is easier as you can know query complexity ahead of time at end points. GraphQL has to have something to account for the unknown query complexity, thus the additional heuristics.