CLI reference¶
Every ./shard-db <cmd> subcommand in one place. Shortcuts for the common operations — for full expressiveness see the Query protocol.
All data-plane commands (anything besides start/stop/status/server) talk to the running server over TCP at $PORT. Start the server first.
Looking for a TUI?
shard-cliis a separate ncurses binary built alongsideshard-db— full menu-driven access to every JSON mode (browse / query / schema / maintenance / auth / stats), no JSON typing required.
Lifecycle¶
| Command | Args | Description |
|---|---|---|
start |
— | Start the server in the background. Reads PORT, DB_ROOT, etc. from db.env. Writes a pidfile. |
server |
— | Start in the foreground (no fork). Useful for systemd Type=simple or debugging. |
stop |
— | Graceful shutdown. Refuses new connections, waits up to 30 s for in-flight writes to drain. |
status |
— | Print running (pid=..., port=...) or stopped. Exit code reflects status. |
CRUD¶
| Command | Args | Description |
|---|---|---|
insert |
<dir> <obj> <key> '<json_value>' |
Insert (or overwrite) a record. Set if_not_exists via JSON mode. |
get |
<dir> <obj> <key> |
Retrieve a single record. |
delete |
<dir> <obj> <key> |
Delete a record by key. |
exists |
<dir> <obj> <key> |
Returns bare true / false. (Multi-key form keeps the {key:bool} dict shape.) |
size |
<dir> <obj> |
Bare integer — live record count, O(1) metadata read. Use orphaned for the tombstoned count. |
Query¶
| Command | Args | Description |
|---|---|---|
find |
<dir> <obj> [filter] [--limit N] [--offset N] [--fields f1,f2] [--order-by f[:dir]] [--format json\|rows\|csv] |
Search records using NQL filter syntax. For join, cursor pagination, or dict format, use JSON mode. |
count |
<dir> <obj> [filter\|criteria_json] |
Count matching records. Omit filter for the O(1) metadata count. Accepts either NQL filter string or JSON criteria array. |
aggregate |
<dir> <obj> [filter] <agg-list> [--group-by f1,f2] [--having filter] [--order-by alias[:dir]] [--limit N] |
Group + aggregate using NQL syntax. For JSON mode with full alias control, use JSON mode. |
keys |
<dir> <obj> [offset] [limit] |
List keys, paginated. |
fetch |
<dir> <obj> [offset] [limit] [fields] |
Paginated full scan with optional field projection. Use JSON mode for keyset cursor pagination. |
NQL filter examples¶
./shard-db find default users 'age > 25'
./shard-db find default users 'status = active and age between 18 and 65' --limit 20 --fields name,email
./shard-db count default users 'status in (active,pending)'
./shard-db aggregate default orders 'status = active' sum(amount),count() --group-by region
See the NQL reference for the full grammar and operator list.
Bulk¶
| Command | Args | Description |
|---|---|---|
bulk-insert |
<dir> <obj> [file] |
JSON array of {"key":"<key>","value":{...}} objects, or dict form {"k1":{...},"k2":{...}}. File path or stdin. Acts as upsert (overwrites existing keys; if_not_exists available via JSON mode). |
bulk-delete |
<dir> <obj> [file] |
JSON array of keys (e.g. ["k1","k2"]). For criteria-based deletes, use JSON mode. |
bulk-update has no CLI shortcut — use JSON mode. It has three sub-shapes: (1) criteria + value to filter then patch matching records, (2) records: for per-key patches inline, (3) file: for the same from disk. CSV input via bulk-update-delimited.
File storage¶
| Command | Args | Description |
|---|---|---|
put-file |
<dir> <obj> <local-path> [--if-not-exists] |
Upload local file to server (base64 over TCP). --if-not-exists refuses overwrite. |
get-file |
<dir> <obj> <filename> [<out-path>] |
Download by filename (base64 over TCP). Writes to <out-path> or stdout. |
delete-file |
<dir> <obj> <filename> |
Remove a stored file. Returns {"status":"deleted",...} or {"error":"file not found",...}. |
list-files |
<dir> <obj> [pattern] [offset] [limit] [--match=<mode>] |
Alphabetical paginated listing. --match=prefix (default), suffix, contains, or glob (fnmatch(3): *, ?, [abc]). Empty pattern matches all. limit defaults to GLOBAL_LIMIT when 0/omitted. Returns {"files":[...],"total":N,"offset":N,"limit":N}. |
Size bounded by MAX_REQUEST_SIZE (default 32 MB ⇒ ~24 MB effective file). For same-host admin tasks, JSON mode put-file with path and get-file-path skip the base64 roundtrip.
Index management¶
| Command | Args | Description |
|---|---|---|
add-index |
<dir> <obj> <field> [-f] |
Build a B+ tree index on a single field. -f forces rebuild. Composite via field1+field2. Batch builds via JSON mode. |
remove-index |
<dir> <obj> <field> |
Drop the index. <field> must be the exact name stored in index.conf — bare for btree/composite, with the type suffix (field:trigram, field:bitmap) for typed indexes, even if it's the only index on that field. There's no bare-name fallback: a field can have both a bare btree index and a typed sibling at once, so the engine won't guess. See Index management → remove-index. Safe on non-existent index. |
Maintenance¶
| Command | Args | Description |
|---|---|---|
vacuum |
<dir> <obj> |
Fast in-place tombstone reclaim (no schema changes). For compact/reshard, use JSON mode. |
compact |
<dir> <obj> |
Offline VARCHAR compaction — rewrites all VARIABLE-format segments, trimming trailing zero bytes from every record. Reclaims the space saved by switching from fixed-width slots to the VARIABLE format. Run once after ./migrate on upgrade. Requires the server to be stopped. |
recount |
<dir> <obj> |
Rescans shards and rewrites the cached counts file. |
rebuild-kf |
<dir> <obj> |
Repair corrupted/dangling kf entries by rescanning every segment file and re-deriving each live record's kf slot. Idempotent. New in 2026.07.1 — see rebuild-kf. |
truncate |
<dir> <obj> |
Delete all records. Schema + indexes survive. |
backup |
<dir> <obj> |
Copy the object's data + metadata + indexes to a timestamped backup directory. |
edit-field |
<dir> <obj> <name:type[:param]> |
Single-field shortcut for edit-field. Same-type edits only (varchar grow/shrink, integer family widen/narrow, numeric scale change, float→double). v2 only. Use JSON mode for batch edits. |
Diagnostics¶
| Command | Args | Description |
|---|---|---|
stats |
— | Global snapshot: uptime, active connections, in-flight writes, cache hit rates, recent slow queries. Prints as table. |
stats-prom |
— | Same counters as stats, rendered as Prometheus text-format exposition. Wire to your scrape pipeline. |
shard-stats |
[dir] [obj] |
Per-shard load table. Without args, shows all objects; with one arg, all objects in that dir; with both, just that object. |
db-dirs |
— | List registered tenant directories (from dirs.conf). |
vacuum-check |
— | List objects where tombstoned ≥ 10 % AND live ≥ 1000. Suggests candidates for vacuum. |
reindex |
[dir] [obj] |
Rebuild indexes — wipes per-field idx directories and rebuilds at the current index_splits_for(splits) shard count. No args = all tenants. |
orphaned |
<dir> <obj> |
Bare integer count of tombstoned-but-not-vacuumed slots. O(1) metadata read. New in 2026.05.1. |
(./migrate) |
— | Per-release one-shot upgrade runner — separate binary at build/bin/migrate. Stops the daemon, runs every required migration for the release, restarts the daemon, exits. For 2026.05.1: migrate-files (lift pre-2026.05.2 XX/XX/<filename> to flat) + reindex (per-shard btree rebuild). |
JSON query mode¶
For anything not covered by the shortcut commands (multi-get, aggregates, joins, CAS, schema mutations, bulk-update, file-path variants, etc.):
See Query protocol for every mode and its parameters.
Exit codes¶
| Code | Meaning |
|---|---|
0 |
Success. |
1 |
Error — usage problem, connection failure, or server returned {"error":...}. |
Error responses are printed verbatim to stdout as JSON, so you can pipe into jq or parse in scripts.
Examples¶
# Multi-get via JSON mode
./shard-db query '{"mode":"get","dir":"default","object":"users","keys":["u1","u2","u3"]}'
# Aggregate (count by status)
./shard-db query '{
"mode":"aggregate","dir":"default","object":"orders",
"group_by":["status"],
"aggregates":[{"fn":"count","alias":"n"}]
}'
# CAS update
./shard-db query '{
"mode":"update","dir":"default","object":"orders","key":"o1",
"value":{"status":"paid"},
"if":[{"field":"status","op":"eq","value":"pending"}]
}'
# Dry-run bulk delete
./shard-db query '{
"mode":"bulk-delete","dir":"default","object":"orders",
"criteria":[{"field":"status","op":"eq","value":"cancelled"}],
"dry_run":true
}'