Documentation
Performance & Best Practices
Performance & Best Practices
Query Optimization Tips
- Always anchor on a specific node first. Start your
MATCHwith a node that has a knownexternal_idrather than scanning all nodes of a type. - Use velocity APIs for time-window counts. Do not use
COUNTover traversals for time-windowed counts — the pre-computed O(1) velocity API is orders of magnitude faster. - Prefer shorter paths. Traversals up to 2–3 hops are fast. Deeper unbounded traversals should have a
LIMITto avoid full graph scans. - Use parameterized queries. This enables query plan reuse across calls with different values.
- Limit result sets. Always add
LIMITto exploratory queries — especially in production where the graph may be large.
Efficient Traversal Patterns
| Pattern | Recommended | Avoid |
|---|---|---|
| Count events in time window | Velocity API (get_velocity_count) |
COUNT with filter over edges |
| Check if relationship exists | edge_exists(src, dst, type) |
Full MATCH + COUNT |
| Find connected neighbours | 1–2 hop MATCH with LIMIT |
Unbounded variable-length paths |
| Get risk context | get_fraud_context(node_id) |
Manually traversing and aggregating |
Common Mistakes to Avoid
- Writing data before calling
db.finalizeSchema()— all writes will fail - Forgetting to call
CREATEfor destination nodes before creating a relationship - Using string interpolation to build Cypher queries — always use
parameters - Querying without
LIMITon large result sets in production - Skipping the edge insert when a transaction is declined — this breaks future velocity counts
- Modeling shared attributes (devices, IPs) as string properties instead of nodes — you lose the ability to traverse them