Not a confirmed bug — an investigation surfaced during a large ADR ingest.
Observation
While ingestion was actively writing, graph-query endpoints were slow:
- `POST /query/related` ~8.6s
- `POST /query/search` ~6.3s
- `GET /query/concept/*` ~2s each
Meanwhile CRUD/admin endpoints stayed ~2ms, and the DB was not contended (1 active connection, no long-running queries, no pool exhaustion). Graph size at the time: ~3,947 concepts / 27,702 edges / 6,997 instances.
Hypothesis
graph_accel cache thrash. Per ADR-207, every mutation advances the freshness tick and invalidates graph_accel; under continuous ingest the accel layer never stays warm, so /query/* falls back to raw AGE Cypher over ~27k edges (genuinely seconds). Likely transient — tied to active write load.
To look into
- Re-measure
/query/* at rest (no active ingestion, annealing frozen). Expect sub-second if the hypothesis holds.
- If still slow at rest:
EXPLAIN ANALYZE the /query/related and /query/search Cypher, check graph_accel cache hit-rate, and review AGE index coverage on those paths.
Not a confirmed bug — an investigation surfaced during a large ADR ingest.
Observation
While ingestion was actively writing, graph-query endpoints were slow:
Meanwhile CRUD/admin endpoints stayed ~2ms, and the DB was not contended (1 active connection, no long-running queries, no pool exhaustion). Graph size at the time: ~3,947 concepts / 27,702 edges / 6,997 instances.
Hypothesis
graph_accelcache thrash. Per ADR-207, every mutation advances the freshness tick and invalidatesgraph_accel; under continuous ingest the accel layer never stays warm, so/query/*falls back to raw AGE Cypher over ~27k edges (genuinely seconds). Likely transient — tied to active write load.To look into
/query/*at rest (no active ingestion, annealing frozen). Expect sub-second if the hypothesis holds.EXPLAIN ANALYZEthe/query/relatedand/query/searchCypher, checkgraph_accelcache hit-rate, and review AGE index coverage on those paths.