Quickstart
Run VeltrixDB in Docker, talk to it over the text protocol (keys, data types, vector, text and hybrid search), and confirm the server is healthy.
Run with Docker
No build required. Pull and run the published image, then talk to it over the text protocol using nc:
docker run -p 9000:9000 -p 2112:2112 ghcr.io/veltrixdb/veltrixdb:latest
Port 9000 is the storage protocol; 2112 serves metrics and health checks (used in Verify it's running). With no flags the server runs --mode=standalone with a 256 MB cache. Among the startup log lines you should see (timestamps dropped):
[index] implementation=native (native = off-heap C++ table, invisible to the Go GC; set VELTRIXDB_INDEX=map to opt out)
[storage] engine started disks=1 cache=256MB data=./veltrixdb-data
[server] plaintext listening on :9000
[tls] disabled — TLS listener not started
[server] ready — plain: :9000 tls: off
[search] rebuilt 0 vectors and 0 text documents in 86ms
The image is a cgo build, so the index is the off-heap native table; a CGO_ENABLED=0 build (or Go older than 1.21) prints implementation=map. The [search] line comes from a background rebuild of the search indexes and its time varies. Then send a few commands:
echo -e "PUT hello world\nGET hello\nPING" | nc localhost 9000
You should see OK, world, then PONG printed back.
The same socket speaks every data type. Each command is followed by the reply it printed on a fresh server:
# atomic counter → 1, 11
echo -e "INCR pageviews\nINCR pageviews 10" | nc localhost 9000
# hash fields (per-field TTL) → OK, alice
echo -e "HSET user:42 name alice\nHGET user:42 name" | nc localhost 9000
# lists and sets → 1, job-1, 1, red, END
echo -e "RPUSH queue job-1\nLPOP queue\nSADD tags red\nSMEMBERS tags" | nc localhost 9000
Vector, text and hybrid search
A KV record, a vector and a text document that share an id describe one thing. Store two records with their vectors and text in namespace docs, then search them three ways:
echo -e 'PUT doc:1 {"lang":"en"}
PUT doc:2 {"lang":"de"}
VSET doc:1 NS docs 0.12 0.94 0.31
VSET doc:2 NS docs 0.90 0.10 0.20
TSET doc:1 NS docs TEXT how to rotate encryption keys
TSET doc:2 NS docs TEXT backup and restore keys' | nc localhost 9000
# → OK (six times)
# vector: top 2 by cosine
echo "VSEARCH 2 NS docs 0.10 0.90 0.30" | nc localhost 9000
doc:1 0.99987286
doc:2 0.2712947
END
# full text: top 2 by BM25
echo "TSEARCH 2 NS docs QUERY rotate keys" | nc localhost 9000
doc:1 0.8374049
doc:2 0.19100353
END
# hybrid: both rankings fused by reciprocal rank,
# filtered on the KV record with the same id
echo "HSEARCH 2 NS docs FILTER lang = de VEC 0.10 0.90 0.30 QUERY rotate keys" | nc localhost 9000
doc:2 0.016393442
END
Without the FILTER clause the same HSEARCH returns doc:1 0.016393442 then doc:2 0.016129032. The first VSET fixes a namespace's dimension (3 here); NS defaults to default. Quantization (VCREATE … QUANT int8|pq), filters, clusters and measured recall are in Vector & Hybrid Search.
Full syntax for every command is in the wire protocol reference; the type semantics live in the data model.
Build from source
VeltrixDB builds on macOS and Linux with Go 1.19+ (go.mod). A default build uses cgo and needs a C++ compiler (and liburing on Linux); the native off-heap index also needs Go 1.21+ — an older toolchain, or CGO_ENABLED=0, gets the Go map index. See Installation for details.
go build ./... # or: CGO_ENABLED=0 go build ./...
go run ./cmd/server -addr :9000 -data ./dev-data -cache 256
This starts a single-node server listening on :9000, writing to a local ./dev-data directory, with a 256 MB LIRS cache (the default) and adaptive group commit (the default since v1.12: a lone writer is synced at once). The network front-end is the Go server (--net=go) serving the text and binary protocols. On a cgo build the in-memory index uses off-heap C++ tables; everything else on the serving path — WAL, VLog reads and writes, the cache — is Go unless you opt in to the io_uring bridge or the experimental --net=cpp front-end.
8-disk production example
For production hardware with multiple NVMe disks, pass them as a comma-separated list via -data-dirs so shards fan out across all disks in parallel:
./veltrixdb -addr :9000 \
-data-dirs /mnt/nvme0,/mnt/nvme1,/mnt/nvme2,/mnt/nvme3,\
/mnt/nvme4,/mnt/nvme5,/mnt/nvme6,/mnt/nvme7 \
-cache 65536
With 8 disks, each disk serves 1024 of the 8192 shards, and a 64 GB (65536 MB) cache is allocated for hot data.
Connect with a client SDK
Client SDKs for six languages speak the same binary protocol; they live in the separate Veltrixdb-client repository. The cluster-aware Go client in the server repo (client/) is the only one with the search API — from other languages, send the search commands above over a TCP socket. Here's the Python SDK:
import veltrixdb
db = veltrixdb.Client(host="localhost", port=9000)
db.put("user:1001", "alice")
print(db.get("user:1001")) # alice
See the Python SDK reference for installation and the full API. Tip: prefer MPUT/MGET batches for bulk loads: one 1024-key MPUT shares one WAL write, one VLog pwrite and one fdatasync per disk instead of paying them per key.
Verify it's running
Every VeltrixDB node exposes a metrics and health endpoint on port 2112:
curl http://localhost:2112/healthz # liveness probe
curl http://localhost:2112/readyz # readiness probe
curl http://localhost:2112/metrics # Prometheus scrape endpoint
/healthz returns 200 ok as soon as the process is alive (it starts before the engine). /readyz returns 503 initializing until the storage engine has opened and the metrics and admin handlers are registered, then 200 ready; it returns 503 degraded if a disk breaker trips. WAL replay finishes in the background after that, and searches are refused until the search rebuild ends — INFO reports search_ready=1 once it has. /metrics exposes 70+ Prometheus metric families (77 on a standalone node), including:
| Metric | Healthy value |
|---|---|
veltrixdb_storage_writes_total / veltrixdb_storage_reads_total | growing |
veltrixdb_cache_hits_total / misses_total | hit rate > 90% |
veltrixdb_storage_write_admission_throttles_total | 0 |
veltrixdb_vlog_garbage_ratio | < 0.30 |
veltrixdb_vlog_gc_emergency_runs_total | 0 |
You can also open the built-in web dashboard at http://localhost:2112/admin/ui. Without --admin-token (or VELTRIX_ADMIN_TOKEN), /admin/* accepts only loopback connections — from outside a Docker container, set a token; /metrics, /healthz and /readyz are always unauthenticated.
/admin surface can trigger destructive operations (checkpoints, cluster topology). Never expose port 2112 to untrusted networks.