Live demo
Every headline feature, run against a real 3-shard durable cluster on
localhost — this is the verbatim output of demo/demo.sh:
membership, replicated write/read + rendezvous routing, server-side set ops, per-key TTL, atomic
CAS & counters, bearer auth, leader election, the durable ingest queue, Prometheus metrics, and a
hot backup + verify.
== 1. Start a 3-shard DURABLE cluster + coordinator == shards on :8100-8102 (lmdb), coordinator on :8080 — leader election + durable ingest queue + bearer auth == 2. Cluster membership (id + endpoint + epoch) == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' http://127.0.0.1:8080/members {"epoch":1,"members":[{"endpoint":"http://127.0.0.1:8100","id":"s0"},{"endpoint":"http://127.0.0.1:8101","id":"s1"},{"endpoint":"http://127.0.0.1:8102","id":"s2"}]} == 3. Write + read an object — replicated to 2 shards, routed by rendezvous hashing == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/write -d '{"coll":"kv","key":"alpha","obj":{"hello":"world"}}' {"ok":true} $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' 'http://127.0.0.1:8080/object?coll=kv&key=alpha' {"object":{"hello":"world"}} which shards own it: $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' http://127.0.0.1:8080/route?key=alpha {"owners":["s2","s1"],"servedBy":"s2"} == 4. Server-side set ops (posting lists, evaluated on the shard) == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/setAdd -d '{"coll":"tags","key":"reptiles","member":"vypr"}' {"ok":true} $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/setAdd -d '{"coll":"tags","key":"reptiles","member":"boa"}' {"ok":true} == 5. Per-key TTL (lazy expiry on read + background sweep) == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/write -d '{"coll":"kv","key":"session","obj":"abc","ttlMs":800}' {"ok":true} immediately: $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' 'http://127.0.0.1:8080/object?coll=kv&key=session' {"object":"abc"} after 1s (expired): $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' 'http://127.0.0.1:8080/object?coll=kv&key=session' {"object":null} == 6. Atomic compare-and-set + counters == acquire a lock (set-if-absent): $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/cas -d '{"coll":"kv","key":"lock","new":"held"}' {"set":true} someone else tries (fails): $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/cas -d '{"coll":"kv","key":"lock","new":"stolen"}' {"set":false} atomic counter: $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/incr -d '{"coll":"kv","key":"hits","delta":1}' {"value":1} $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/incr -d '{"coll":"kv","key":"hits","delta":41}' {"value":42} == 7. Bearer auth is enforced == without a token (expect 401): $ curl -s -o /dev/null -w 'HTTP %{http_code}\n' 'http://127.0.0.1:8080/object?coll=kv&key=alpha' HTTP 401 with the token (expect 200): $ curl -s -o /dev/null -w 'HTTP %{http_code}\n' -H 'authorization: Bearer ***' -H 'content-type: application/json' 'http://127.0.0.1:8080/object?coll=kv&key=alpha' HTTP 200 == 8. Coordinator leader election == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' http://127.0.0.1:8080/leader {"isLeader":true,"leader":"coord-a","self":"coord-a","token":1} == 9. Durable ingest queue — accepted durably, applied async, at-least-once == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8080/enqueue -d '{"coll":"kv","key":"queued","obj":"via-WAL"}' {"durable":true,"ok":true,"seq":1} $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' http://127.0.0.1:8080/ingest/status {"accepted":1,"committed":1,"pending":0} drained to the shards: $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' 'http://127.0.0.1:8080/object?coll=kv&key=queued' {"object":"via-WAL"} == 10. Prometheus metrics + cluster gauges == $ curl -s http://127.0.0.1:8080/metrics | grep -E 'stplr_ops_total|stplr_cluster_' stplr_ops_total{op="get"} 5 stplr_ops_total{op="set"} 6 stplr_ops_total{op="sadd"} 2 stplr_ops_total{op="srem"} 0 stplr_ops_total{op="del"} 0 stplr_cluster_shards 3 stplr_cluster_replication 2 stplr_cluster_migrating 0 == 11. Hot backup snapshot + verify (against shard s0 directly) == $ curl -s -H 'authorization: Bearer ***' -H 'content-type: application/json' -X POST http://127.0.0.1:8100/backup?dest=/tmp/tmp.WPURv3eHql/s0.snap {"dest":"/tmp/tmp.WPURv3eHql/s0.snap","ok":true} verify the backup is restorable (counts entries, read-only): $ /home/viktorvondrakk/.cache/cargo-target/release/stplrd --verify-snapshot /tmp/tmp.WPURv3eHql/s0.snap snapshot /tmp/tmp.WPURv3eHql/s0.snap: 3 collection(s), 5 entries o:__lease 1 o:kv 3 o:tags 1 == Done — tearing down the cluster == stplr.org · one self-managing binary · durable, distributed, zero-touch
Not a consensus coordinator. An HA data plane, not a Raft/Paxos config store — strong per-shard (the CAS & counters in step 6), available through node loss and partitions, async last-writer-wins across DCs. Need a strict lock service for a handful of keys? That's etcd's job; stplr runs leader election (step 8) on top.
Not a vector database. The server-side set ops in step 4 are the half of retrieval vectors can't do: exact, structured correlation — membership, AND/OR/NOT, deterministic joins with auditable provenance. The precise complement to similarity search — and what the Stitch engine builds on. Pair them; don't swap one for the other.
The script builds stplrd, spins up three lmdb shards + a coordinator (leader election,
durable ingest queue, bearer auth), walks every feature, and tears everything down — temp dirs, no
config, ~15 seconds: ./demo/demo.sh