Summary
During a sustained Lunaris ingest, a single Moon shard entered a CPU spin
(~266%) and stopped answering all commands — redis-cli PING blocks
indefinitely even though the TCP listener is still up — and made no further
persistence_tick checkpoint progress for 40+ minutes. The only recovery was
SIGKILL. One pathological ingest payload wedged the entire shard, not just the
offending request.
Environment
moon release build, single shard (--shards 1)
- flags:
--appendonly no --save "" --disk-free-min-pct 1, --protected-mode no, port 6381
- macOS (Darwin 24.6, arm64), host under heavy memory pressure at the time (swap ~87% full, ~2.5 GB free) — noting this as a possible contributing factor, not a confirmed cause.
Trigger
Ingesting the haystack for LongMemEval-S (longmemeval_s) question qid
1faac195 (dataset offset 57) — ~46 sessions / ~494 turns, written as ~46
documents through Lunaris ingest_episode. Each document = one atomic_write
(MULTI) carrying HSET hydration docs plus FT vector + keyword index upserts
(FT.*). Offsets 0–56 ingested cleanly; the wedge reproduced on this specific
question.
Observed
- Moon process pinned at ~266% CPU, sustained, for 40+ min (compute spin, not an idle wait).
redis-cli -p 6381 PING blocks — no reply — while the listener still accepts connections.
- Last
moon::shard::persistence_tick: Checkpoint complete log line ~40 min before kill, then total silence.
- The Lunaris client was blocked on the in-flight command. Lunaris bounds every Moon command with a 10 s per-command response timeout (
LUNARIS_MOON_OP_TIMEOUT), but no reply ever arrived — the connection stayed open and the server simply never responded, so the timeout's failure path didn't engage as expected against a spinning (vs. cleanly-dead) server.
Impact
A single degenerate ingest payload can wedge a whole shard indefinitely. There
is no server-side ceiling that bounds how long one request can hold the shard
spinning.
Repro pointer
LongMemEval-S longmemeval_s offset 57 (qid 1faac195), ingested through
Lunaris ingest_episode (chunk + RAPTOR community tree + vector/keyword FT.*
upserts). A minimal FT.*/HSET-only repro that drops the Lunaris layer is
pending — will follow once isolated (the host is mid-benchmark).
Questions / asks
- Any known
FT.* / HNSW degenerate-input path that can spin (e.g. a
pathological vector batch, an oversized field, or an index-rebuild loop)?
- Could sustained memory pressure push a shard into an unbounded alloc/GC spin
rather than failing fast?
- Would a server-side per-command watchdog / CPU budget be feasible, so one
request can't hold a shard spinning and unresponsive indefinitely?
Summary
During a sustained Lunaris ingest, a single Moon shard entered a CPU spin
(~266%) and stopped answering all commands —
redis-cli PINGblocksindefinitely even though the TCP listener is still up — and made no further
persistence_tickcheckpoint progress for 40+ minutes. The only recovery wasSIGKILL. One pathological ingest payload wedged the entire shard, not just theoffending request.
Environment
moonrelease build, single shard (--shards 1)--appendonly no --save "" --disk-free-min-pct 1,--protected-mode no, port 6381Trigger
Ingesting the haystack for LongMemEval-S (
longmemeval_s) question qid1faac195(dataset offset 57) — ~46 sessions / ~494 turns, written as ~46documents through Lunaris
ingest_episode. Each document = oneatomic_write(MULTI) carrying HSET hydration docs plus FT vector + keyword index upserts
(
FT.*). Offsets 0–56 ingested cleanly; the wedge reproduced on this specificquestion.
Observed
redis-cli -p 6381 PINGblocks — no reply — while the listener still accepts connections.moon::shard::persistence_tick: Checkpoint completelog line ~40 min before kill, then total silence.LUNARIS_MOON_OP_TIMEOUT), but no reply ever arrived — the connection stayed open and the server simply never responded, so the timeout's failure path didn't engage as expected against a spinning (vs. cleanly-dead) server.Impact
A single degenerate ingest payload can wedge a whole shard indefinitely. There
is no server-side ceiling that bounds how long one request can hold the shard
spinning.
Repro pointer
LongMemEval-S
longmemeval_soffset 57 (qid1faac195), ingested throughLunaris
ingest_episode(chunk + RAPTOR community tree + vector/keywordFT.*upserts). A minimal
FT.*/HSET-only repro that drops the Lunaris layer ispending — will follow once isolated (the host is mid-benchmark).
Questions / asks
FT.*/ HNSW degenerate-input path that can spin (e.g. apathological vector batch, an oversized field, or an index-rebuild loop)?
rather than failing fast?
request can't hold a shard spinning and unresponsive indefinitely?