Slow queries & index issues
Purpose: Find and fix traversal warnings, slow QueryBuilder calls and index-shaped performance cliffs.
Who this page is for
| Audience | Why it matters to you |
|---|---|
| Backend engineers | Query owners |
| Platform engineers | Index operators |
The signals
| Signal | Where |
|---|---|
Traversal query warnings / "consider creating an index" | error.log — each names the query; treat as a build-breaking bug, not noise |
| Query blocked at node limit (RuntimeException around 100k reads) | error.log + broken feature |
| Feature slow, no warnings | Query indexed but bad (huge result set, memory sort) — profile below |
| Everything slow after content growth | Index lag or a query whose cost scales with content (index management) |
Profile the query
- Reproduce it in Explain Query (Operations → Diagnosis → Query Performance) or the QueryBuilder debugger
(querydebug.html) — copy exact predicates from the code.
- Read the plan: which index?
traverse= none. Lucene index but huge estimated entries = unselective. - The slow-queries panel (Query Performance) lists the worst recent offenders with plans — start there when you
don't know which query is the problem.
Fix ladder (cheapest first)
| Fix | When |
|---|---|
| Don't query | Known-path child iteration replaces it (first question) |
| Constrain path + nodetype | Query scans less even on the same index |
| Cap + paginate (p.limit) | Unbounded results are latency AND memory |
| Stop sorting by unindexed property | Order by indexed property, or sort a capped page in memory |
| Add/extend a property index for the predicate | New query pattern is legitimate — ship the definition (as code) |
| Cache the result | Expensive-but-static aggregates (nav trees) — with invalidation designed |
Verify the fix
Explain again (plan uses the intended index), then latency at production content volume — dev-sized repos lie (load testing content-volume rule). Watch error.log a full day: some traversal warnings only fire from rare code paths.