Chris Collins

Tools · infra

Redis client

A redis-cli in the browser with a built-in Redis to practise on, Lua scripts and functions, a reference for 255 commands with runnable examples, per-connection history, a key browser, pub/sub and stream viewers — and connections to real Redis servers over a REST gateway or a WebSocket bridge.

Added · updated 30 October 2026

Works with

How to use it

The console works like redis-cli. Type a command and press Enter; replies look as they do in a terminal — (integer) 1, "quoted strings", (nil), numbered arrays. Three backends sit behind it:

  • Built-in Redis (the default) — an emulator of Redis 7.2 running in this page. Nothing to install, and every example in the docs runs against it. Tick Keep data in this browser to keep its data between visits (SAVE also saves); otherwise it lives as long as the page.

  • REST gateway — an Upstash-compatible HTTPS endpoint in front of a real Redis.

  • WebSocket bridge — a real Redis (including one on your own machine) through a small bridge you run, speaking RESP2 or RESP3.

The console

  • Quoting follows redis-cli: "double quotes" understand \n, \t, \", \\ and \xHH bytes; 'single quotes' are literal except \'. A number before a command repeats it (3 INCR hits). Paste several lines to run them in order; blank lines and lines starting with # are skipped.

  • Hints: after a command and a space, the rest of its syntax appears in grey, and the line below the prompt shows the full syntax and summary. Tab completes command names, options that can come next, and key names (Tab again cycles; ↑ ↓ pick from the list).

  • History: ↑ and ↓ walk through earlier commands. The History tab searches it, puts a command back in the console, runs it again, exports or clears it. History is kept per connection, only in this browser; commands carrying passwords (AUTH, HELLO … AUTH, ACL SETUSER, CONFIG SET requirepass) are never saved, as in redis-cli.

  • HELP SET and HELP @stream work as in redis-cli (HELP alone lists the groups); CLEAR empties the pane.

  • Open pane B adds a second connection beside the first: SUBSCRIBE in one and PUBLISH from the other, or watch a WATCH abort a transaction when the other pane changes the key. The prompt shows the database (builtin[1]>) and an open transaction ((TX)).

  • Show UTF-8 prints valid UTF-8 as text instead of redis-cli’s \xe2\x82\xac escapes; Show RESP adds each reply as it travels on the wire.

On a real server, FLUSHALL, FLUSHDB, KEYS, CONFIG SET, SHUTDOWN, DEBUG, SWAPDB, SCRIPT/FUNCTION FLUSH, REPLICAOF, CLIENT KILL and ACL SETUSER ask before they run.

Docs

The Docs tab describes every command the built-in Redis supports and the common ones it does not (marked not built in): syntax, a summary, complexity, the reply, the version that introduced it, and examples. Try it runs the examples in a fresh built-in Redis and shows the replies; Run in console runs them in pane A. Summaries and examples are written for this page; syntax, complexity and versions come from Redis 7.2’s own COMMAND DOCS, and each group links to its page on redis.io.

Keys, Pub/Sub and Streams

  • Keys lists keys with SCAN (never KEYS), filtered by pattern and type, 200 at a time, with each key’s type and TTL. Pick one to see its value — a string (JSON pretty-printed), list, hash, set, sorted set with scores, or the newest stream entries — with its encoding and memory use (MEMORY USAGE, an estimate in the built-in Redis), and set a TTL, persist or delete it.

  • Pub/Sub subscribes to channels and patterns on its own connection and shows each message with its time and channel; publish from the same tab and see how many subscribers received it.

  • Streams shows a stream’s length, last ID and groups (XINFO), each group’s consumers and pending entries (with an XACK button), the newest entries with paging, and lets you add entries, create a group and read as a consumer.

Connecting to a real Redis

Browsers cannot open TCP connections, so this page reaches a real Redis through the gitwebsite app, or (when the app is not running) in one of two other ways.

The gitwebsite app. If it is running on your computer, choose Real Redis (WebSocket) → ⚡ gitwebsite app, type the server’s host:port (127.0.0.1:6379 is on its TCP allow-list by default) and Connect: the app’s TCP relay replaces the bridge below.

REST gateway. Give the URL and token of an Upstash REST API (or anything compatible, such as the open-source serverless-redis-http in front of your own Redis). Each command is a POST of a JSON array with an Authorization: Bearer header; the gateway must allow this page’s origin (CORS) — serverless-redis-http does not answer CORS preflight requests, so put it behind a proxy that adds the Access-Control-Allow-* headers. A REST gateway is stateless, so MULTI … EXEC is collected here and sent as one /multi-exec request, and SUBSCRIBE, WATCH and SELECT are not available.

WebSocket bridge. Run a bridge that copies bytes between a WebSocket and Redis’s TCP port, then connect to ws://localhost:6380. With websockify:

websockify 6380 localhost:6379
# better: listen on this machine only
websockify 127.0.0.1:6380 localhost:6379

Or this Node script (npm install ws first), which also refuses web pages other than this site and localhost:

// redis-ws-bridge.js — node redis-ws-bridge.js [wsPort] [redisHost] [redisPort]
const net = require('net');
const { WebSocketServer } = require('ws');
const [port = 6380, host = '127.0.0.1', rport = 6379] = process.argv.slice(2);
const ok = o => o === 'https://geekychris.github.io' || /^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(o || '');
const wss = new WebSocketServer({ host: '127.0.0.1', port: +port, verifyClient: i => ok(i.origin) });
wss.on('connection', ws => {
  const redis = net.connect(+rport, host);
  redis.on('data', d => ws.send(d));
  ws.on('message', d => redis.write(d));
  redis.on('close', () => ws.close());
  redis.on('error', () => ws.close());
  ws.on('close', () => redis.destroy());
});
console.log(`ws://127.0.0.1:${port} -> redis ${host}:${rport}`);

The bridge forwards the RESP protocol unchanged, so everything works: AUTH (fill in username and password), SELECT (the database field), HELLO 3 (choose RESP3), transactions, blocking commands and pub/sub. The Keys and Streams tabs and the Pub/Sub tab use their own connections. Server info summarises INFO. Chrome and Firefox let this https page open ws://localhost; other hosts need wss:// (a bridge behind TLS). Anyone who can reach a bridge can use your Redis, so keep it on 127.0.0.1 and stop it when you are done.

Passwords and tokens stay in memory unless you tick Remember (then they are kept in this browser’s storage, readable by anyone using it). They never go into links or history.

Limits

  • The built-in Redis implements about 240 commands of Redis 7.2 — strings, keys and expiry, lists, hashes, sets, sorted sets, streams and consumer groups, bitmaps and BITFIELD, HyperLogLog, geospatial indexes (GEOADD, GEOSEARCH …), pub/sub (also sharded), keyspace notifications, client-side caching (CLIENT TRACKING), transactions with WATCH, Lua scripts (EVAL, EVALSHA, SCRIPT) and functions (FUNCTION LOAD, FCALL), SORT, SCAN and its relatives, 16 databases. It is tested against a real redis-server: the same scripts must give the same replies, errors included. Not built in: ACLs, replication, cluster, MONITOR, DUMP/RESTORE, GEORADIUS (use GEOSEARCH), eviction.

  • Lua runs on an interpreter of Lua 5.1 written for this page, with the libraries Redis scripts use (base functions, string with Lua patterns, table, math, cjson, bit) but not cmsgpack, struct or the debugger. A script that runs more than five million steps is stopped with an error, where a real server would keep going and answer BUSY to everyone else. Keyspace notification event names follow Redis for the common commands.

  • Blocking commands (BLPOP, XREAD BLOCK, …) never wait in the built-in Redis: with nothing to return they answer as a real server does when the timeout runs out, with a note.

  • Some replies differ by design: SCAN cursors and the order of big sets and hashes (Redis’s are pseudo-random), RANDOMKEY/SPOP/SRANDMEMBER, OBJECT IDLETIME (0), MEMORY USAGE and INFO (estimates), HyperLogLogs stored dense (so STRLEN of one differs; PFCOUNT matches). INCRBYFLOAT rounds like an x86-64 server; ARM servers print some sums differently.

  • Over REST, values that are not valid UTF-8 cannot travel in JSON.

Linking to an example

Links can be written by hand. Add the tab after #: console, keys, pubsub, streams, docs or history. A link never connects to a server and never carries a password or token.

Parameter Meaning Example

example

Load one of the scenarios below into the built-in Redis and run it

example=leaderboard

cmd

A console command: run in the built-in Redis, or filled in (not run) for a real server. Several lines are allowed (%0A between them)

cmd=ZRANGE%20game:scores%200%20-1%20WITHSCORES

doc

Open a command’s documentation

doc=XREADGROUP

q

A search in the Docs tab

q=expire

conn

builtin, rest or ws

conn=ws

ws

WebSocket bridge URL

ws=ws://localhost:6380

rest

REST gateway URL (without the token)

rest=https://example.upstash.io

db

Database for the WebSocket bridge

db=2

resp

Protocol for the WebSocket bridge: 2 or 3

resp=3

match, type

Pattern and type for the Keys tab

match=user:*&type=hash#keys

Presets for example=:

example= Shows

leaderboard

A game leaderboard in a sorted set: top three, ZINCRBY, a player’s rank, scores in a range (open)

rate-limiter

A fixed-window rate limiter with INCR and EXPIRE … NX (open)

job-queue

A reliable job queue: LPUSH, LMOVE to a processing list, LREM when done, and a blocking pop (open)

consumer-group

A stream with a consumer group: two consumers, XACK and the pending entries list (open; then the Streams tab)

pubsub-chat

Pane B subscribes to chat:*, pane A publishes (open)

session

A session hash with a sliding 30-minute TTL (open)

unique-visitors

Unique visitors counted with a set, a HyperLogLog and a bitmap (open)

cache-aside

A JSON cache entry with SET … EX, NX and GETEX (open)

transaction

MULTI/EXEC moving money between accounts, and WATCH aborting a transaction (open)

More: ?cmd=HELP%20@sorted-set lists the sorted-set commands; ?doc=ZRANGE#docs opens one command’s page.

Runs entirely in your browser — network requests go only to the services named on this page.