grx

Limits

HTTP payload caps, timeouts, persisted-query modes, executor selection safeguards - contain abusive graphs before resolver work dominates.

Use this guide to set the outer request budget before resolver work starts. Combine HTTP body limits, execution timeouts, document-shape limits, and trusted documents according to the traffic your service accepts.

Even well‑formed GraphQL documents can overwhelm memory or CPU (alias bombs, multi‑megabyte JSON bodies). Separate these controls from masking/auth (Security) and schema discovery knobs (Introspection).


Payload & timeouts

ControlGoalgrx helper (grx.NewServer)Only server.Config
HTTP envelopeOversized POST JSON bodiesWithMaxHTTPRequestBytes(n)MaxHTTPRequestBytes
Variables JSONOversized variables payloads-MaxVariableBytes
Clock guardHanging resolversWithRequestTimeout(d)RequestTimeout
package main

import (
	"log"
	"time"

	"example.com/hello-grx/graph"

	"github.com/grx-gql/grx"
	"github.com/grx-gql/grx/server"
)

func main() {
	var err error

	_, err = grx.NewServer(
		grx.WithSchema(graph.Schema()),
		grx.WithRequestTimeout(15*time.Second),
		grx.WithMaxHTTPRequestBytes(1<<20),
		grx.WithMaxSelectionDepth(16),
	)
	if err != nil {
		log.Fatal(err)
	}

	_, err = server.New(server.Config{
		Schema:              graph.Schema(),
		RequestTimeout:      30 * time.Second,
		MaxHTTPRequestBytes: 2 << 20,
		MaxVariableBytes:    96 << 10,
	})
	if err != nil {
		log.Fatal(err)
	}
}

Persisted & trusted corpus

WithPersistedQueries maps sha256 → literal query. Harden server.Config with RequirePersistedQuery, StrictPersistedQueries, TrustedDocuments, RejectUnknownVariables for closed corpora (server package tests demonstrate behaviour).

Extended procedure: Persisted queries (APQ).


Document-shape safeguards

Executors reject parses that explode combinationally (Execution pipeline).

MechanismSource
Total selectionsserver.Config.MaxSelectionCount
AliasesMaxAliasCount
Parallel root fieldsMaxRootFieldCount
Deepest nestinggrx.WithMaxSelectionDepth(n) / server.Config.MaxSelectionDepth
package main

import (
	"log"

	"example.com/hello-grx/graph"

	"github.com/grx-gql/grx/server"
)

func main() {
	srv, err := server.New(server.Config{
		Schema:            graph.Schema(),
		MaxSelectionDepth: 16,
		MaxSelectionCount: 750,
		MaxAliasCount:     200,
		MaxRootFieldCount: 10,
	})
	if err != nil {
		log.Fatal(err)
	}
	_ = srv
}

Patterns + rationale: Query & document limits.

Limits ≠ deterministic cost modelling

Counters are guardrails - not Apollo-style deterministic cost engines.

Edit this page on GitHub

Last updated on

On this page