dgraph-io/dgraph · error
Exceeded query edge limit = %v. Found %v edges.
Error message
Exceeded query edge limit = %v. Found %v edges.
What it means
Recurse queries expand outward from root nodes up to a depth. If the total number of edges traversed exceeds x.Config.LimitQueryEdge (default 1,000,000), Dgraph aborts the query to protect the server. It is a resource-protection limit, not a data error.
Source
Thrown at query/recurse.go:156
// modify the exec and attach child nodes.
var out []*SubGraph
var exp []*SubGraph
for _, sg := range exec {
if sg.UnknownAttr {
continue
}
if len(sg.DestUIDs.Uids) == 0 {
continue
}
if exp, err = expandChildren(ctx, sg, startChildren); err != nil {
return err
}
out = append(out, exp...)
}
if numEdges > x.Config.LimitQueryEdge {
// If we've seen too many edges, stop the query.
return errors.Errorf("Exceeded query edge limit = %v. Found %v edges.",
x.Config.LimitQueryEdge, numEdges)
}
if len(out) == 0 {
return nil
}
exec = out
}
}
// expandChildren adds child nodes to a SubGraph with no children, expanding them if necessary.
func expandChildren(ctx context.Context, sg *SubGraph, children []*SubGraph) ([]*SubGraph, error) {
if len(sg.Children) > 0 {
return nil, errors.New("Subgraph should not have any children")
}
// Add children and expand if necessary
sg.Children = append(sg.Children, children...)
expandedChildren, err := expandSubgraph(ctx, sg)View on GitHub (pinned to 759e242be6)
Solutions
- Bound the recursion with an explicit depth, e.g. recurse(depth: 3)
- Narrow the root set with a filter/root function to reduce starting nodes
- Raise the limit in server config (limit{"query-edge": N}) if the server can afford more memory
- Restructure the query: use shortest-path or specific predicates instead of full expand-all (_all_directives or expand(_all_))
Example fix
// before: unbounded recurse over everything
{
me(func: eq(name, "alice")) @recurse {
expand(_all_)
}
}
// after: bounded depth and selected predicates
{
me(func: eq(name, "alice")) @recurse(depth: 3) {
friend
name
}
} Defensive patterns
Strategy: validation
Validate before calling
// Compute expected traversal size before running recurse
maxDepth := 3
if estimateEdgesFromRoot(rootUIDs, maxDepth) > 1_000_000 {
return errors.New("recurse would exceed query-edge limit; add depth bound or filter")
} Try / catch
resp, err := txn.Query(ctx, dql)
if err != nil && strings.Contains(err.Error(), "Exceeded query edge limit") {
// retry with reduced depth or narrowed root set
dql = reduceDepth(dql)
resp, err = txn.Query(ctx, dql)
} Prevention
- Always specify an explicit depth on @recurse for large graphs
- Filter the root set before recursing
- Tune limit{"query-edge"} to match your dataset and memory budget
- Prefer expand of named predicates over expand(_all_)
When it happens
Trigger: A recurse { ... } query whose traversal touches more edges than the limit-query-edge config: starting from high-degree root nodes, deep recursion without a depth bound, or large datasets with dense connectivity.
Common situations: Running recurse from a node with thousands of neighbors, forgetting to set depth: N on huge graphs, defaults changed in self-hosted configs, or per-node limits (query-edge limit) set lower than dataset size.
Related errors
- Length of facetsMatrix and uidMatrix mismatch: %d vs %d
- Invalid recurse path query
- Depth must be > 0 when loop is true for recurse query
- recurse queries require that all predicates are specified in
- illegal rune found "%c", expecting {
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/b37ac600ac92cadc.
Report an issue: GitHub.