Skip to content

shard-db 2026.06.3

Explain query mode, lock-free warm reads, and a reindex spill-file collision fix. Wire-compatible with 2026.06.2 — no migration required.

Highlights

  • Explain mode — add "explain":true to any find, count, or aggregate request to see the query plan without executing it. Returns the plan type, indexed source leaves with cardinality estimates, postfilter leaves, order strategy, and optimization hints.
  • Lock-free warm reads — generation counters on the global cache table let warm reads (cache hits) skip the global lock entirely, reducing contention on read-heavy workloads.
  • Reindex spill isolation — per-field-index spill directories prevent btree and trigram builders from colliding when rebuilding multiple indexes on the same field simultaneously.

Features

Explain query mode

Add "explain":true to any find, count, or aggregate request. The query is not executed — the planner runs and returns a JSON plan description.

{
  "mode": "find",
  "dir": "mydir",
  "object": "orders",
  "criteria": [{"field": "status", "op": "eq", "value": "pending"}],
  "order_by": "created_at",
  "explain": true
}

Response:

{
  "plan": "leaf",
  "order": "index_walk",
  "total_cheap": false,
  "table_rows": 1240000,
  "source": [
    {
      "field": "status",
      "op": "eq",
      "index": "btree",
      "role": "seed",
      "estimated_rows": 52000
    }
  ],
  "postfilter": [],
  "hints": []
}

Plan types: leaf (single indexed driver), scan (full parallel scan), intersect (multiple indexed AND leaves, KeySet intersection), union (all OR children indexed, KeySet union).

Order strategies: index_walk (order index driven directly), composite (composite index covers filter+order), composite_exact (composite + exact prefix), sort (post-fetch in-memory sort), none (unordered).

Hints fire when the planner detects a suboptimal path:

Hint Meaning
add_index Criteria field has no index; adding one would enable index-driven execution
composite_index Filter field and order_by field are separate; a composite index would eliminate the sort
add_trigram_index contains/like/ends criterion has no trigram index; adding one prunes candidates before record fetch
add_bitmap_index Low-cardinality field without a bitmap index; bitmap would accelerate grouping and counting

CLI subcommand:

./shard-db explain <dir> <obj> '<criteria_json>' [order_by]

TUI: in the Query panel, press e on the preview screen to show the formatted explain output for the current query without running it.

Full reference: docs/query-protocol/explain.md.

Performance

Lock-free warm reads

Global cache table lookups now use generation counters to detect in-flight mutations. Threads that find a stable generation (no write in progress) complete the lookup without acquiring the table lock. Only cold misses and writers take the lock.

Effect: reduces global lock contention on workloads with high concurrency and warm caches (index reads, segment reads). No configuration needed; always active.

Bug fixes

Reindex spill-file collision

During reindex (or add-index), each indexed field builds its B+ tree and trigram data via spill files. Previously all spill files for a given object shared the same directory, so btree and trigram builders on the same field (or two fields being built simultaneously) could overwrite each other's spill data.

Each builder now uses a private spill directory named by field and index type (<obj>/tmp/spill/<field>/<type>/). Objects with multiple indexes can be reindexed safely in parallel without data collision.

Affected configurations: objects with both a btree and trigram index on the same field, or multi-field reindex triggered via ./shard-db reindex. Single-index objects were not affected.

Upgrade notes

No migration needed. Drop-in replacement for 2026.06.2. Recommended if you run reindex on objects with trigram indexes.