> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.sqd.dev/feedback

```json
{
  "path": "/en/sdk/squid-sdk/reference/openreader-server/configuration/dos-protection",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# DoS protection

> Protect your Squid SDK GraphQL API from denial-of-service queries — depth, complexity, and rate-limit configuration in OpenReader.

The squid [GraphQL API server](https://github.com/subsquid/squid-sdk/tree/master/graphql/graphql-server) accepts the following optional start arguments to fend off heavy queries.

To enable the protection, add the corresponding flags to `serve` and `serve:prod` command definitions at [`commands.json`](/en/sdk/squid-sdk/squid-cli/commands-json):

```json theme={"system"}
...
  "serve": {
    "description": "Start the GraphQL API server",
    "cmd": ["squid-graphql-server", "--max-root-fields", "10", "--max-response-size", "1000"]
  },
  "serve:prod": {
    "description": "Start the GraphQL API server in prod",
    "cmd": ["squid-graphql-server", "--max-root-fields", "10", "--max-response-size", "1000", "--dumb-cache", "in-memory"]
  },
...
```

When deploying to [SQD Cloud](/en/cloud), make sure to use `serve:prod` to start the GraphQL `api` service in the [deployment manifest](/en/cloud/reference/manifest#deploy):

```yaml title="squid.yaml" theme={"system"}
# ...
deploy:
  # other services ...
  api:
    cmd: [ "sqd", "serve:prod" ]
```

**`--max-request-size <kb>`**

The argument limits the size of a request in kilobytes. It is set to `256kb` by default.

**`--max-root-fields <count>`**

The maximal allowed number of root-level queries in a single GraphQL request.

**`--max-response-size <nodes>`**

This option limits the *estimated* query response size and makes server return an error if it exceeds the provided value. Note that the estimated size depends only on the decorators in `schema.graphql` and the requested fields.

The estimate is the product of the cardinality of the entity list and the response item weight.

The cardinality is estimated as the minimum of

* the `limit` argument of the query (`Infinity` if not provided)
* `@cardinality` value defined in `schema.graphql` (if the requested entity type is decorated in the schema file, `Infinity` otherwise)
* the size of the argument list of the `_eq` and `id_in` filters in the `where` clause (if applicable)

In particular, if there are no `@cardinality` decorators in `schema.graphql`, the client queries must explicitly provide limits or where filters to pass through.

The response item weight is calculated recursively:

* `byteWeight` for each scalar field or `1` if it's not decorated
* for non-scalar fields, the estimated weight times the estimated cardinality (if it's a list)
* each non-leaf node in the query AST tree adds a weight of `1`

In a nutshell, assuming that the schema file is properly decorated with `@cardinality` and `@byteWeight`, the estimated response size should roughly be at the same scale as the byte size of the query result.

**`--subscription-max-response-size <nodes>`**

Same as `--max-response-size` but for live query [subscriptions](/en/sdk/squid-sdk/reference/openreader-server/configuration/subscriptions).

#### Example

Assume the schema is defined as follows, and the server is launched with `--max-response-size 1000`.

```ts title="schema.graphql" theme={"system"}
type Foo @entity {
    id: ID!
    // a large string 
    bigField: String! @byteWeight(value: 1000.0)
    bar: Bar!
}

type Bar @entity {
    id: ID!
    // bar.foos typically contain about 100 items
    foos: [Foo!]! @derivedFrom(field: "bar") @cardinality(value: 100)
    bazs: [Baz!]! @derivedFrom(field: "bar")
}

// there are around 100 entities of type Baz
type Baz @entity @cardinality(value: 100) {
    id: ID!
    bar: Bar!
}
```

The following queries will be bounced:

```graphql theme={"system"}
query A {
    bars {
        id
    }
}

query B {
    bars(limit: 1001) {
        id
    }
}

query C {
    bars(limit: 100) {
        id 
        foos(limit: 10) {
            id
        }
    }
}

query D {
    bars(limit: 10) {
        id 
        foos {
            id
        }
    }
}

query E {
    foos(id_eq: "1") {
        id
        bigField
    }
}
```

* The estimated cardinality of query A is `Infinity`
* The estimated cardinality of query B `1001` and so the expected size exceeds the limit
* The estimated cardinality of query C is `100` while the item size is `13`, so the size is estimated to `1300`.
* The estimated cardinality of query D is `10` while the item size is `103`, so the size is estimated to `1030`.
* The estimated cardinality of query E is `1` while the item size is `1001` (due to `bigField` having weight `1000`).

At the same time, the following queries will go through:

```graphql theme={"system"}
query A {
    bars(limit: 100) {
        id
    }
}

query B {
    bars(limit: 3) {
        id
        foos {
            id
        }
        bazs {
            id
        }
    }
}

query C {
    bars {
        id
        bar {
            foos(where: { id_in ["1", "2" ]}) {
                id
            }
            id
        }
    }
}
```
