marekvs

Redis API reference

Implemented · some Planned

marekvs speaks RESP2 and RESP3. The tables below list the commands that are actually wired into the command dispatcher (crates/marekvs-engine/src/cmd/), so if a command is here, it runs. Commands that some tools assume exist but that marekvs does not implement are called out explicitly in Not implemented.

Note

Read guarantees are per connection: a connection sees its own writes and never reads backward in time. They are not cross-client — two clients on two nodes can briefly observe different values. See Consistency.

#Connection & server

CommandNotes
PING ECHOLiveness / echo.
HELLOProtocol handshake; selects RESP2/RESP3.
AUTHSingle-password auth when MAREKVS_REQUIREPASS is set.
QUIT RESETClose / reset the connection state.
SELECTAccepted (single logical keyspace).
CLIENT COMMAND CONFIG INFO DBSIZEIntrospection / runtime config.
FLUSHALL FLUSHDBClear data.
TIMEServer time.
REPLICAOF / SLAVEOFFollow a real Redis master (live migration).
SHUTDOWN DEBUGLifecycle / debug helpers.
CLUSTER INFO/MYID/KEYSLOT/SLOTS/SHARDS/NODESRead-only topology for cluster-aware client routing. See Cluster protocol.

A few settings are live-reconfigurable via CONFIG SET: requirepass, lua-time-limit, and loglevel.

#Generic / keyspace

CommandNotes
DEL UNLINK EXISTS TYPE TOUCHStandard key ops.
TTL PTTL EXPIRETIME PEXPIRETIMERead expiry.
EXPIRE PEXPIRE EXPIREAT PEXPIREAT PERSISTSet / clear expiry.
KEYS SCAN RANDOMKEYEnumerate keys.
RENAME RENAMENXRename keys.
COPYCopy a key within DB 0; supports REPLACE and accepts DB 0.
OBJECTCompatibility introspection: ENCODING, REFCOUNT, IDLETIME, FREQ, HELP.
EXPIREMEMBER EXPIREMEMBERAT PEXPIREMEMBERATKeyDB-style per-member TTL.
TTL key memberPer-member TTL read (KeyDB extension).

#Strings

CommandNotes
GET SET SETNX SETEX PSETEXGet / set with options.
GETSET GETDEL GETEXGet-and-mutate.
APPEND STRLEN SETRANGE GETRANGE / SUBSTRSubstring ops.
INCR DECR INCRBY DECRBY INCRBYFLOATCounters (see below).
MGET MSET MSETNXMulti-key get / set.
Done

INCR / DECR / INCRBY / DECRBY are backed by PN-counters: concurrent increments on different nodes are all preserved, never lost. An explicit SET resets the counter. See counters.

#Hashes

CommandNotes
HSET HMSET HSETNX HGET HMGET HGETALLField get / set.
HGETDELReturn and delete one or more fields using FIELDS n field ....
HDEL HEXISTS HLEN HKEYS HVALS HSTRLENField inspection.
HEXPIRE HPEXPIRE HEXPIREAT HPEXPIREATSet field-level TTLs using FIELDS n field ...; supports NX/XX/GT/LT.
HTTL HPTTL HEXPIRETIME HPEXPIRETIME HPERSISTRead or clear field-level TTL metadata.
HGETEXReturn fields and optionally set EX/PX/EXAT/PXAT or PERSIST.
HSETEXSet field/value pairs using FVS n field value ...; supports FNX/FXX, expiry options, and KEEPTTL.
HINCRBYField arithmetic. A PN counter: concurrent increments on different nodes all survive.
HINCRBYFLOATField arithmetic. Last-writer-wins — float addition is not associative, so per-node slots would drift.
HRANDFIELD HSCANSample / iterate.

#Sets

CommandNotes
SADD SREM SCARD SISMEMBER SMISMEMBERMembership.
SMEMBERS SPOP SRANDMEMBER SSCANRead / sample / iterate.
SMOVEMove a member between sets.
SUNION SINTER SDIFF (+ STORE) SINTERCARDSet algebra.

Concurrent SADDs on different nodes both survive (ORSWOT merge).

#Sorted sets

CommandNotes
ZADD ZINCRBY ZREMAdd / mutate.
ZSCORE ZMSCORE ZCARD ZRANK ZREVRANK ZCOUNT ZLEXCOUNTInspect.
ZRANGE ZRANGEBYSCORE ZREVRANGE ZREVRANGEBYSCORE ZRANGEBYLEX ZREVRANGEBYLEXRange queries.
ZRANDMEMBERReturn one or more members, optionally WITHSCORES.
ZRANGESTOREStore a ZRANGE result in a destination key.
ZPOPMIN ZPOPMAX BZPOPMIN BZPOPMAX ZMPOP BZMPOPPop commands, including blocking variants.
ZREMRANGEBYSCORE ZREMRANGEBYRANK ZREMRANGEBYLEXRange deletion.
ZUNION ZINTER ZDIFFReturn sorted-set algebra results; supports WEIGHTS, AGGREGATE, and WITHSCORES.
ZUNIONSTORE ZINTERSTORE ZDIFFSTORE ZINTERCARDStore or count sorted-set algebra results.
ZSCANIterate members and scores.
Note

Lexicographical sorted-set operations are implemented as scans over live members (O(N)). ZRANDMEMBER follows marekvs' deterministic sampling style rather than making distribution guarantees.

#Lists

CommandNotes
LPUSH RPUSH LPUSHX RPUSHXPush.
LPOP RPOP LLEN LRANGE LINDEXPop / read.
LSET LREM LTRIM LINSERT LPOSMutate / search.
LMOVE RPOPLPUSHMove between lists.
LMPOPPop multiple elements from the first non-empty list.
BLPOP BRPOP BLMOVE BRPOPLPUSH BLMPOPBlocking variants.
Note

Lists are per-element position-keyed LWW registers. Blocking commands poll at ~50 ms and also wake on a replicated push. Concurrent cross-node pushes can collide on a position — see the list caveat.

#Streams

CommandNotes
XADD XLEN XDEL XTRIMAppend / size / trim.
XRANGE XREVRANGE XREADRead entries.
XSETIDSet last-generated-id metadata, with optional ENTRIESADDED and MAXDELETEDID.
XINFO STREAMReturn stream metadata, length, first/last entry, and placeholder radix/group fields.
Warning

Consumer groups are not implemented — XGROUP, XREADGROUP, XACK, XCLAIM, XAUTOCLAIM, XPENDING, and XINFO GROUPS/XINFO CONSUMERS are absent. Streams provide raw, at-least-once entry operations plus basic stream metadata.

#HyperLogLog

CommandNotes
PFADD PFCOUNT PFMERGEConvergent (per-register max) cardinality.

#Pub/Sub

CommandNotes
SUBSCRIBE UNSUBSCRIBE PSUBSCRIBE PUNSUBSCRIBEChannel / pattern.
PUBLISH PUBSUBPublish / introspect.

#Scripting

CommandNotes
EVAL EVALSHA SCRIPTLua 5.4; keys must co-locate. See Lua scripting.

#Transactions

CommandNotes
MULTI EXEC DISCARDQueue and run sequentially.
Warning

Transactions are a convenience batch, not ACID: queued commands run sequentially with no atomicity beyond per-key shard serialization. WATCH / UNWATCH are rejected with an error — marekvs is AP and has no transactional compare-and-swap.

#Distributed budgets (marekvs extension)

Not a Redis family — BG.* is marekvs-native: escrow-based shared budgets with a hard never-overspend invariant that holds through partitions, crashes, and split-brain (fail-closed). Full guide: Distributed budgets.

CommandNotes
BG.CREATE BG.TOPUPCreate / fund a budget (central actor; SEQ-idempotent; MODE WINDOW = self-refilling rate limit).
BG.RESERVEReserve an amount → token + deadline; forwards to a peer with escrow headroom; fails closed (-BUDGETEXHAUSTED).
BG.COMMIT BG.RELEASE BG.DRAWReport spend / return / draw incrementally against a token (routed to its issuing node).
BG.INFONode-local ledger view.
BG.RECLAIMAdmin: fence a permanently dead node and redistribute its unconsumed escrow.

TYPE reports budget; EXPIRE, RENAME, and COPY are rejected on budget keys; DEL starts a fresh generation (outstanding tokens die with the old one).

#JSON documents (RedisJSON-compatible)

Full RedisJSON v2 surface over a per-path CRDT document model — concurrent editors on different nodes merge structurally instead of last-writer-wins on whole documents. Full guide: JSON documents.

CommandNotes
JSON.SET JSON.GET JSON.MGET JSON.MSETBoth path dialects ($… JSONPath, legacy .a.b[3]); MSET not atomic across keys.
JSON.DEL JSON.FORGET JSON.TYPE JSON.CLEARSubtree delete wins over concurrent interior edits; add-wins per record.
JSON.NUMINCRBY JSON.NUMMULTBYLWW under concurrency (unlike HINCRBY, which is a PN counter).
JSON.STRAPPEND JSON.STRLEN JSON.TOGGLEScalar ops.
JSON.ARRAPPEND JSON.ARRINDEX JSON.ARRINSERT JSON.ARRLEN JSON.ARRPOP JSON.ARRTRIMArrays are RGA sequences: concurrent appends all survive, runs never interleave.
JSON.OBJKEYS JSON.OBJLENLexicographic key order.
JSON.MERGERFC 7386 merge-patch, decomposed into per-field deltas.
JSON.RESP JSON.DEBUGRESP view; MEMORY = stored-record bytes.

TYPE reports ReJSON-RL (module-compat); OBJECT ENCODING reports json; TTL and RENAME/COPY behave like other collection types.

#Document comparison (marekvs extension)

DIFF.* compares canonical document trees stored with JSON.*. It creates reviewable suggestions, replicates per-change decisions, and applies accepted changes to immutable snapshots. Full guide and runnable walkthrough: Document comparison.

CommandsPurpose
DIFF.SNAPSHOT DIFF.FORKSave a semantic version and create an editable branch.
DIFF.COMPARE DIFF.MERGE3Build two-way or three-way suggestion graphs.
DIFF.DECIDE DIFF.DECISIONSRecord attributed decisions; inspect revisions and unresolved groups.
DIFF.APPLYApply the accepted selection with a retryable request token.
DIFF.IMPORTUpdate a branch from a complete tree while preserving supported identities.
DIFF.HASH DIFF.STATSInspect subtree hashes and local resource counters.

Inputs share one hash tag. Snapshot, graph, and result keys are immutable to ordinary client writers. These commands are experimental marekvs extensions and are unavailable inside Lua scripts.

#Protobuf values (marekvs extension)

Not a Redis family — PROTO.* is marekvs-native: a server-side protobuf schema registry with prefix bindings, validated typed values, field access and JSON projection. Full guide: Protobuf values.

CommandNotes
PROTO.SCHEMA SET/COMPILE/GET/LIST/TYPES/DELRegistry: upload .proto source (server-compiled, imports resolve from the registry) or a compiled descriptor set; versioned; DEL keeps old versions so stored values always decode.
PROTO.BIND PROTO.UNBIND PROTO.BINDINGSBind key prefixes to message types; longest prefix wins; explicit TYPE argument overrides.
PROTO.SET PROTO.GET PROTO.INFOValidated values stored decomposed into per-field CRDT records; GET materializes the message, INFO reports {schema, version, type, format, records, bytes} (format = whole for legacy values, fields for decomposed).
PROTO.GETJSON PROTO.SETJSONCanonical protobuf-JSON projection in/out.
PROTO.GETFIELD PROTO.SETFIELD PROTO.CLEARFIELDDot-path field access; SETFIELD/CLEARFIELD write per-field CRDT deltas — concurrent edits to different fields merge (repeated = RGA, map = add-wins, oneof = deterministic winner). Legacy whole-message values upgrade on first write; upgrade the whole cluster before the first field-level write.
PROTO.HSET PROTO.SADDValidate values, then store as ordinary hash fields / set members (raw bytes; plain HGET/SMEMBERS unchanged).
PROTO.HGETJSON PROTO.HGETFIELDDecode one hash element at read time.

TYPE reports proto; OBJECT ENCODING reports the fq message type; plain SET overwrites a proto value (standard Redis semantics). Errors are raw codes: -NOSCHEMA, -SCHEMAERR, -PROTOVALIDATE, -NOBINDING, -PROTOPATH. PROTO.* is not callable from Lua scripts in v1.

#Not implemented

These are not in the dispatch table, even though some clients or older design notes assume them. Calling one returns an error:

  • Keyspace: SORT, DUMP, RESTORE, MOVE
  • Stream: consumer-group commands (XGROUP, XREADGROUP, XACK, XCLAIM, XAUTOCLAIM, XPENDING, XINFO GROUPS, XINFO CONSUMERS)
  • Cluster / HA: WAIT, FAILOVER, FUNCTION. CLUSTER SETSLOT/FORGET/ MEET are also absent — topology is gossip+HRW managed, not client-mutated. (Read-only CLUSTER topology commands are implemented — see Cluster protocol.)
  • Modules / extras: GEO*, bitfield/bit ops, CLIENT TRACKING (client-side caching)
  • Transport: no TLS.

#Cross-cutting semantics

  • Protocols: RESP2 and RESP3, negotiated with HELLO; inline commands are supported.
  • Atomicity: per-key only. A key's operations are serialized on one shard thread; there is no multi-key or cross-node atomicity.
  • Type errors: operating on the wrong structure returns WRONGTYPE.
  • Expiry: absolute deadlines decided at the origin, converging cluster-wide.
  • Counters: exact under concurrency (PN-counters).
  • Blocking commands: implemented via ~50 ms polling that also wakes on a replicated push.
  • Cluster routing: no MOVED/ASK redirects, no CROSSSLOT errors — any node serves any key, cluster-aware clients just get to skip the extra hop. See Cluster protocol.

#Where to go next