# Query Cost, Depth Limits and Persisted Queries — GraphQL

Source: https://www.skillbyai.com/en/graphql/p-limits

> Protecting the server.

## Bound what clients can ask for

Because clients compose queries, a single request can be very expensive: deeply nested relationships, huge page sizes or many aliased copies of a field. Protect the server with **maximum depth**, **query complexity/cost analysis** (assign costs to fields and multiply by page sizes), maximum page sizes, timeouts and rate limits based on cost. **Persisted queries** go further: clients send a hash or ID of a pre-registered operation, and the server can reject unknown queries entirely, which suits first-party apps.

## An expensive query and the defences

Why limits matter.

```graphql
# without limits, this asks for up to 100 x 100 x 100 = 1,000,000 nodes
query Expensive {
  users(first: 100) {
    edges { node {
      followers(first: 100) {
        edges { node {
          followers(first: 100) { edges { node { name } } }
        } }
      }
    } }
  }
}

# defences: depth limit (e.g. 7), cost limit (e.g. 1,000 points with list sizes multiplied),
# max first: 50, request timeout, persisted query allow-list for first-party clients
```

## Also limit aliases and batching

Attackers can repeat a field hundreds of times with aliases or send many operations in one batch to bypass simple rate limits.

**Quiz:** What do persisted queries allow a server to do?

- [ ] Skip the schema entirely
- [x] Accept only pre-registered operations, identified by hash or ID
- [ ] Store user passwords
- [ ] Disable resolvers

*Answer:* Accept only pre-registered operations, identified by hash or ID. An allow-list of queries.
