Skip to main content

The wire and Redis compatibility

Structures speaks RESP2 and RESP3, the Redis protocol, over a raw TCP socket. redis-cli connects to it. So do the standard Python, Node, Go and Java client libraries, unchanged.

That is the adoption argument in one line: keep your clients, keep your command vocabulary, and gain everything a cache does not give you.

What a client gets​

PropertyDetail
RESP2 and RESP3Both protocol generations
Per-connection registrationClient state is registered once per connection, not per command, so transactions, watches and protocol state persist across a session the way a Redis client expects
Cluster semanticsThe Redis Cluster model: CRC16 over 16,384 slots, {hashtag} co-location for related keys, and MOVED and CROSSSLOT responses
KeyDB extensionsThe command surface extends beyond baseline Redis
ScriptingServer-side scripting with SHA-based caching and function libraries
Pub/sub and keyspace notificationsIncluding an in-process dispatcher and a keyspace notifier

The cluster semantics matter more than they look. A client library that already understands MOVED will follow a redirect to the owning cell without special handling, which is what makes multi-cell placement transparent to an application that was written against Redis Cluster.

The wire is not an authorization bypass​

This is the property that makes the compatibility safe to offer, and it is the first question a security reviewer should ask.

A standard Redis client connecting directly does not find an ungoverned back door:

  1. The connection is deny-by-default until it authenticates.
  2. The connection binds to a verified directory entity, not to a shared password.
  3. Every command re-enters the same engine-boundary authorizer the HTTP surface uses.

So a GET over RESP is subject to the same workspace scope, the same classification and the same grants as the equivalent call over HTTP. The protocol determines the syntax, not the authority.

Figure: the Redis wire, governed. Connecting is not authorization. The connection authenticates and binds to a directory entity, and then every command crosses the same authorizer an HTTP caller crosses.

Other ways in​

The wire is the compatibility surface, not the only one.

SurfaceFor
RESP2 / RESP3Existing Redis clients and tooling
An external HTTP faceCredential-authenticated callers that do not speak RESP
An in-process workspace clientCo-located callers inside the cell, including agents
An operator surfaceBrowsing and administering structures from the console
Agent toolsQuery and execute verbs exposed to a reasoning agent, including on a disconnected device

All of them land on the same engine behind the same authorizer.

What you gain over a cache​

The same set or sorted set that would sit in an ungoverned cache becomes, here:

  • Workspace-scoped, so it belongs to a boundary rather than to a shared namespace.
  • Classified, on the same ladder as a table.
  • Authorized per command, against real grants.
  • Audited, into the same record as everything else.
  • Replicated across cells, with conflict-free convergence.
  • Metered, so its consumption is attributable.

A cache gives you none of those, which is why a cache is where governance quietly ends in most estates.