count¶
Returns the number of records matching the criteria, without materializing any record values. Uses the same criteria shape as find.
Shape¶
Response¶
A bare integer (no JSON wrapper):
Errors still come back as {"error":"..."}.
Cost¶
- Single-criterion indexed path — uses
idx_count_cb, the inline index-walk counter. Zero record fetches — O(1) per B+ tree hit. Fastest path. neqalgebraic shortcut —count(neq X)rewrites tocount(*) - count(eq X): two cheap counts instead of a near-everything scan. Same trick applies insideaggregate.- AND of indexed leaves —
PRIMARY_INTERSECTplanner branch (2026.05+). Each leaf's btree walks into aKeySet(xxh128 hashes, lock-free CAS inserts), sets intersect, and the count is just|result|— no per-record fetch. Big win when the intersection is small. See find → AND index intersection. - Mixed AND (indexed + non-indexed) — primary index picks candidates, other criteria filter via the criteria tree (
criteria_match_tree). Still fast because segment-record payloads are read only for candidates that survive the primary index. - Pure-OR (all children indexed) — B+ tree lookups unioned into a
KeySet; count =|KeySet|. No record fetch, no per-record match. - Full scan — parallel per-kf-shard slot walk; each live slot's segment payload is fetched only when its in-kf hash doesn't already disprove the criterion. Sub-millisecond per shard on warm caches.
See find → OR criteria for the full planner table.
count is always cheaper than find + ignoring results because it skips payload materialization and serialization.
Empty criteria¶
Returns the total active record count (same as size). Uses the cached metadata/counts value — O(1). For the deleted-but-not-vacuumed slot count, use the orphaned mode.
Explain mode¶
Set "explain":true to return the query plan without executing. Response is a JSON object with plan, order, total_cheap, table_rows, source, postfilter, and hints fields. No records are counted. See explain.
Examples¶
Count by status¶
// Request
{"mode":"count","dir":"acme","object":"orders",
"criteria":[{"field":"status","op":"eq","value":"paid"}]}
// Response (bare integer)
8432
Range count¶
{"mode":"count","dir":"default","object":"events",
"criteria":[
{"field":"severity","op":"gte","value":"3"},
{"field":"created","op":"gte","value":"20260418000000"}
]}
CLI shortcut¶
Omit the criteria argument to get the O(1) metadata count. Criteria must be a JSON array in a single shell-quoted argument:
When to prefer aggregate¶
If you want multiple counts (by status, by region, etc.) in one trip, use aggregate with group_by instead of N round trips.