Browse documentation
Concept GraphQL

GraphQL filters, pagination, and limits

Encode factQuery filters safely, page with explicit limits and offsets, and stay within time-window, complexity, depth, and token guards.

View as Markdown

factQuery filters are a JSON document carried inside one GraphQL string. Always pass them as a variable so your JSON encoder handles the nested escaping.

Valid filter variables

query ShippedOrders($slug: String!, $filters: String!, $offset: Int!) {
factQuery(
dataModelSlug: $slug
mode: "timeline"
filters: $filters
since: "2026-07-01T00:00:00Z"
limit: 20
offset: $offset
) {
hasNextPage
results { entityId observedAt data }
}
}
{
"slug": "order",
"offset": 0,
"filters": "[{\"field\":\"status\",\"op\":\"eq\",\"value\":\"shipped\"},{\"field\":\"total\",\"op\":\"gte\",\"value\":100}]"
}

Each clause has field, op, and non-null value. field must exactly match one DataModelField and at most 20 clauses are accepted.

Field type Operators
String eq, neq, contains
Integer/Float eq, neq, gt, gte, lt, lte
Datetime eq, neq, gt, gte, lt, lte
Boolean eq, neq

contains is a case-insensitive literal substring. % and _ in the value are escaped instead of becoming SQL wildcards.

Invalid filters

These are query errors and must be corrected before retrying:

  • malformed JSON in the GraphQL string;
  • unknown or non-filterable field names;
  • an operator unsupported by the model field type;
  • values that cannot cast to the field type;
  • null values; or
  • more than 20 clauses.

The error identifies the invalid field/operator where safe. It does not expose arbitrary warehouse payload paths.

Offset pagination

limit defaults to 50, has a hard maximum of 250, and should still be explicit. Start offset at zero and add the applied limit while hasNextPage is true. Request count on the first page only when needed.

The 250 maximum is not a throughput promise: complexity often binds first.

Complexity

The default maximum query complexity is 200. A page field selection is multiplied by the requested limit, so narrower selections permit more rows. A query selecting several page fields and results { entityId observedAt data } can exceed the limit at limit: 50; reduce the limit or selected fields.

Do not request fields “just in case.” GraphQL's explicit selection is a cost and data-minimization tool.

Depth, document size, and windows

Default configurable guards are depth 10 and 8,000 parseable tokens. Violations are rejected before resolution. Timeline windows default to 90 days and clamp at 366 days; explicitly bounded smaller windows are easier to operate.

Per-credential rate limiting also applies: 300 requests per 60 seconds by default, with 429 and Retry-After on breach.

For exact types and response objects, open the factQuery reference.

Related documentation