Ruvio.

One process · RESP · shared nothing

One RESP process. The shard that owns the key does the work.

Lease, semaphore, a capped counter, version, limit, once, an idempotent reserve, take, sliding expiry, delayed stream delivery, and a change feed stay in that process, on that shard. You do not add Redis, Garnet, Dragonfly, or a side tool for those jobs.

Eleven jobs on the owner shard

A feature stores bytes only when a key uses it. GET, SET, and INCR do not look it up.

LEASE · RELEASE

A token for one key. Expiry and RELEASE keep the sequence while the key remains; deletion or data loss can restart it. External resources need their own fencing. The grant is a WAL record in WAL-backed modes.

#coordination#leases

SEMAPHORE · RELEASE

Up to max holders on one key. Each holder has its own TTL, so a crashed worker frees its slot when that TTL passes. RELEASE frees one token. The key goes away with the last holder. A token from a previous key cannot release a new holder.

#concurrency#workers

INCRBY · MAX

INCRBY key n MAX limit adds n only when the result stays at or below limit. Past the limit the reply is a null bulk, and the key and the WAL stay as they were. Plain INCR is unchanged.

#capacity#counters

SETV

The write lands only when the caller still holds the current version. Two clients cannot both turn 12 into 11. The version sits only on keys written with SETV.

#conditionalWrite#lostUpdate

LIMIT

A fixed window on one key. It returns the remaining allowance, or a null bulk when the window is full. The window is the key deadline, so an unused window disappears.

#rateLimiting#quota

ONCE

The first call returns 1 and keeps the key until the TTL. A later call returns 0 and does not refresh the TTL. After the deadline the next call is first again.

#dedupe#once

IDEM

Reserve a request, reject fingerprint conflicts, and replay its completed result. Completion checks the owner and keeps the original deadline. External side effects still need their own deduplication or transaction.

#idempotency#payments

TAKE

Subtracts from an integer only when the key holds enough. A shortfall returns a null bulk and leaves the key unchanged.

#inventory#stock

GETEX

Returns the string and moves its deadline to now plus the given milliseconds. GET does not move a deadline.

#sessions#slidingExpiry

XADD DELAY

The entry is stored now. XREADGROUP waits until the delay passes. XREAD can still see it. The hold is a WAL record, written only when a delay is set.

#delayedJobs#queues

CHANGES

CHANGES START arms a 1024-note feed of later SET, SETV, LEASE, and RELEASE on that shard. Before START, those writes pay one null check. The feed is empty after restart.

#changeFeed

A write is checked, appended, then applied

Durability is named at startup: memory, snapshot, everysec, or always. If the log cannot take the record, the key stays as it was and later writes return MISCONF. Durability

Memory stays with the key you wrote

An entry is the value. TTL lives in a separate ring, so a key without expiry does not carry a deadline. On this machine, 20,000 lease keys added about 3.6 MB. 20,000 versioned 64-byte strings added about 7.2 MB, body included.

Clients that find the shards

Point Ruvio.Client or ruvio-client at one address. They read CLUSTER SLOTS, open one socket per shard, and follow MOVED. Each shard has its own WAL. PING still answers PONG. Clients

Start

A default server listens on 127.0.0.1:6379. The operator UI is a second process on port 8080.

docker pull salihcantekin/ruvio:linux
docker run --rm -p 6379:6379 \
  -e RUVIO_REQUIREPASS=change-me \
  -v ruvio-data:/data \
  salihcantekin/ruvio:linux

Read the detail