Skip to content

Ask the HotKV docs

Answers come only from these docs and can be wrong; check the linked pages before you rely on them.

Protocol

Last updated

HotKV speaks RESP, the protocol Redis clients use, over TCP or TLS. Any client library or tool that works with Redis talks to HotKV without changes. This page describes the protocol as HotKV implements it. For using RESP3 features from an application, see RESP3.

  • A new connection starts in RESP2. Send HELLO 3 to switch it to RESP3, or HELLO 2 to switch back.
  • Plain-text clients connect to port (6379 by default), TLS clients to tls-port. Unix domain sockets are not supported.
  • When the default user has a password, a client must authenticate with AUTH or HELLO ... AUTH before running other commands.
  • With protected-mode on and no password set, only clients on the loopback interface are served; others get a DENIED error and are disconnected. See Errors.

A command is a RESP array of bulk strings: the command name, then its arguments. Names are case-insensitive; arguments are binary-safe.

*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$5\r\nhello\r\n

You can send many commands without waiting for their replies (pipelining). Replies always come back in the order the commands were sent.

For quick tests with telnet or nc, HotKV also takes a command as one line of text ending in \r\n, with the arguments separated by spaces:

SET mykey hello
+OK
GET mykey
$5
hello

HotKV sends these reply types:

Type Prefix RESP2 RESP3 Used for
Simple string + yes yes OK, PONG, status replies
Error - yes yes every error (see Errors)
Integer : yes yes counts, lengths, flags
Bulk string $ yes yes values
Array * yes yes lists of replies
Null $-1 / *-1, or _ yes yes missing values
Map % as a flat array yes HELLO, CONFIG GET, HGETALL, info-style replies
Set ~ as an array yes SMEMBERS and other set replies
Double , as a bulk string yes scores (ZSCORE, ZINCRBY, WITHSCORES)
Boolean # as an integer yes booleans returned by scripts that call redis.setresp(3)
Verbatim string = as a bulk string yes text reports (INFO, CLIENT INFO, CLIENT LIST, LATENCY DOCTOR)
Push > as an array yes pub/sub messages (see below)

In RESP2 a missing value is a null bulk string ($-1) or a null array (*-1), as Redis sends them; in RESP3 both are the null type (_).

HotKV does not send RESP3 big numbers or attributes.

HELLO [protover [AUTH username password] [SETNAME clientname]]

HELLO picks the protocol version for the connection, can authenticate and name the client in the same round trip, and replies with facts about the server. protover must be 2 or 3; anything else gets NOPROTO unsupported protocol version. Without arguments it replies in the connection’s current protocol.

127.0.0.1:6379> HELLO 3
1# "server" => "hotkv"
2# "version" => "8.4.0"
3# "proto" => (integer) 3
4# "id" => (integer) 7
5# "mode" => "standalone"
6# "role" => "master"
7# "modules" => (empty array)
Field Value
server Always hotkv.
version The Redis version whose commands and replies HotKV follows, 8.4.0. Client libraries choose features by it. HotKV’s own version is hotkv_version in INFO server.
proto The protocol now in use.
id The connection’s client ID, as CLIENT ID returns it.
mode standalone, or cluster on a cluster node.
role master, or replica on a replica.
modules Always empty: HotKV does not load modules.

In RESP2 the same fields come as a flat array of 14 elements.

If the server needs a password and the client has not authenticated, HELLO without AUTH fails with a NOAUTH error, and HELLO ... AUTH with a wrong password fails with WRONGPASS.

A client that subscribes (with SUBSCRIBE, PSUBSCRIBE or SSUBSCRIBE) receives messages it did not ask for at that moment. In RESP3 they arrive as push replies (>); in RESP2 as arrays. The first element names the kind:

Kind Elements
subscribe, psubscribe, ssubscribe channel or pattern, number of subscriptions now held
unsubscribe, punsubscribe, sunsubscribe channel or pattern, number of subscriptions left
message channel, payload
pmessage pattern, channel, payload
smessage shard channel, payload
invalidate array of keys, or null (see below)
tracking-redir-broken id of the connection that was redirected to

Keyspace notifications are delivered the same way, as messages on __keyspace@<db>__: and __keyevent@<db>__: channels. In a cluster, a client subscribed to a shard channel whose slot moves to another node receives a sunsubscribe push for it.

While a RESP2 connection holds any subscription, it may only run SUBSCRIBE, PSUBSCRIBE, SSUBSCRIBE, their UNSUBSCRIBE counterparts, PING, QUIT and RESET. Other commands get ERR Can't execute '<command>': only (P|S)SUBSCRIBE / (P|S)UNSUBSCRIBE / PING / QUIT / RESET are allowed in this context. A RESP3 connection can run any command while it is subscribed, because it can tell a message from a reply.

A RESP3 connection that turned on server-assisted client-side caching (CLIENT TRACKING) receives a push when a key it read changes: >2, the string invalidate, then an array of the keys, or a null when everything it cached should be forgotten. A connection that redirects its invalidations to a connection that has gone receives >2, the string tracking-redir-broken and the id of that connection. A RESP2 connection cannot be pushed to: with REDIRECT its invalidations arrive on the other connection as a pub/sub message on the channel __redis__:invalidate. See client-side caching.

Each connection can carry a name and the client library’s name and version, which show up in CLIENT LIST and CLIENT INFO:

  • CLIENT SETNAME (or HELLO ... SETNAME) sets the name. Names cannot contain spaces or non-printable characters.
  • CLIENT SETINFO LIB-NAME and CLIENT SETINFO LIB-VER record the library, with the same character rules. Client libraries usually send these when they connect.
  • CLIENT GETNAME and CLIENT ID read the name and ID back.

CLIENT LIST and CLIENT INFO describe each connection with these fields: id, addr, laddr, fd, name, age, idle, flags, db, sub, psub, ssub, multi, watch, qbuf, qbuf-free, omem, tot-mem, events, cmd, user, redir, resp, lib-name, lib-ver.

Other per-connection controls: CLIENT REPLY (ON, OFF, SKIP), CLIENT NO-EVICT, CLIENT NO-TOUCH, SELECT, and RESET, which returns the connection to its initial state.

Limit Value Configurable
Longest bulk string a client may send 512 MB proto-max-bulk-len, 1 MB to 4294967295 bytes
Most elements in one command (name plus arguments) 1,048,576 no
Unprocessed input per client 1 GB client-query-buffer-limit
Unprocessed input before authentication 1 MB no
Unsent output before authentication 64 KB no
Unsent output per client class see default client-output-buffer-limit

A request that breaks the protocol (a malformed header, a bulk string longer than proto-max-bulk-len, too many elements) gets ERR Protocol error: invalid RESP data, and the server then closes the connection. A client that passes its input or output limit is disconnected. See Limits for the other limits.