Bun provides a built-in Redis/Valkey client exposed as RedisClient on the bun module. This page covers the RedisClient API: construction, connection management, command execution, auto-pipelining, pub/sub, and TLS. For SQL databases (PostgreSQL, MySQL, SQLite) see 9.5 For the low-level socket layer that backs this client see 5.5
RedisClient is exported directly from "bun". Its full TypeScript declaration lives in packages/bun-types/redis.d.ts
RedisClient class diagram:
Sources: packages/bun-types/redis.d.ts1-120
url defaults to process.env.VALKEY_URL, then process.env.REDIS_URL, then "valkey://localhost:6379".| Scheme | Transport |
|---|---|
redis:// | Plain TCP |
rediss:// | TLS |
redis+unix:// | Unix domain socket |
Authentication and database selection are embedded in the URL:
redis://username:password@host:port/db
Sources: packages/bun-types/redis.d.ts57-70 test/js/valkey/test-utils.ts127-132
RedisOptions| Option | Type | Default | Description |
|---|---|---|---|
connectionTimeout | number | 10000 | MS before connection attempt fails |
idleTimeout | number | 0 | MS of inactivity before disconnect; 0 = none |
autoReconnect | boolean | true | Reconnect on connection loss |
maxRetries | number | 10 | Max reconnect attempts |
enableOfflineQueue | boolean | true | Queue commands while disconnected |
tls | boolean | Bun.TLSOptions | — | Enable TLS |
enableAutoPipelining | boolean | true | Batch concurrent commands into one write |
Sources: packages/bun-types/redis.d.ts2-44
Connection lifecycle:
Sources: test/js/valkey/valkey.connecting.fixture.ts18-29 packages/bun-types/redis.d.ts72-103
The test suite demonstrates all supported connection types via ConnectionType in test/js/valkey/test-utils.ts63-70:
Sources: test/js/valkey/test-utils.ts63-132 test/js/valkey/test-utils.ts234-293
| Property | Type | Description |
|---|---|---|
connected | readonly boolean | Whether the socket is currently connected |
bufferedAmount | readonly number | Bytes queued in the write buffer |
onconnect | ((this: RedisClient) => void) | null | Fired when connection is established |
onclose | ((this: RedisClient, error: Error) => void) | null | Fired on disconnect |
Sources: packages/bun-types/redis.d.ts74-92
send(command: string, args: string[]): Promise<any> sends any RESP command directly. The return type reflects the RESP3 server response:
Sources: test/js/valkey/valkey.test.ts37 test/js/valkey/reliability/error-handling.test.ts158-168
RedisClient negotiates RESP3 with the server. Response types are automatically coerced:
| RESP3 Type | JS Type | Example command |
|---|---|---|
| Simple String | string | SET → "OK" |
| Bulk String | string | null | GET |
| Integer | number | INCR, DEL, LLEN |
| Boolean | boolean | EXISTS |
| Map | object | HGETALL |
| Set | Array | SMEMBERS |
| Null | null | GET on missing key |
| Double | string | INCRBYFLOAT |
Sources: test/js/valkey/reliability/error-handling.test.ts124-150 test/js/valkey/reliability/protocol-handling.test.ts19-80
The client ships a large set of typed method wrappers. A representative sample:
Strings
| Method | Signature | Returns |
|---|---|---|
get | (key) | Promise<string | null> |
getBuffer | (key) | Promise<Uint8Array | null> |
set | (key, value, ...opts) | Promise<"OK" | string | null> |
del | (...keys) | Promise<number> |
incr / decr | (key) | Promise<number> |
incrby / decrby | (key, amount) | Promise<number> |
incrbyfloat | (key, amount) | Promise<string> |
exists | (key) | Promise<boolean> |
expire / pexpire | (key, ms) | Promise<number> |
ttl / pttl | (key) | Promise<number> |
mget | (...keys) | Promise<Array<string | null>> |
mset | (...kvPairs) | Promise<"OK"> |
append | (key, value) | Promise<number> |
getdel | (key) | Promise<string | null> |
getex | (key, ...opts) | Promise<string | null> |
strlen | (key) | Promise<number> |
Hashes
| Method | Description |
|---|---|
hset(key, fields) | Set one or more fields |
hget(key, field) | Get a field |
hmget(key, ...fields) | Get multiple fields |
hgetall(key) | Get all fields as object |
hdel(key, ...fields) | Delete fields |
hincrby / hincrbyfloat | Increment hash field |
hexpire / hpexpire | Per-field TTL (Redis 7.4+) |
hgetdel / hgetex / hsetex | Atomic get+expire, set+expire (Redis 8+) |
Lists, Sets, Sorted Sets — full definitions in packages/bun-types/redis.d.ts
The set method supports all standard option flags via overloaded signatures:
Sources: packages/bun-types/redis.d.ts118-225
When enableAutoPipelining is true (the default), multiple commands dispatched in the same microtask tick are automatically batched into a single network write:
This avoids per-command round-trip latency without requiring explicit pipeline management. Each command still returns its own Promise.
The offline queue (enableOfflineQueue: true) extends this: commands issued before connect() completes (or during reconnection) are held in the queue and flushed once the connection is established.
Sources: packages/bun-types/redis.d.ts40-44 packages/bun-types/redis.d.ts30-33
The client supports the standard Redis pub/sub model. A connection in subscriber mode can only use SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, and PING.
The StringPubSubListener callback type is (message: string, channel: string) => void.
Uncaught exceptions inside a subscriber callback propagate to the process uncaughtException handler — they do not terminate the subscription. This is exercised by test/js/valkey/valkey.failing-subscriber.ts and test/js/valkey/valkey.failing-subscriber-no-ipc.ts
Pub/Sub flow:
Sources: test/js/valkey/valkey.failing-subscriber.ts38-57 packages/bun-types/redis.d.ts46-52
TLS is enabled by setting tls in RedisOptions or by using the rediss:// scheme:
The tls field accepts any Bun.TLSOptions (the same options used by Bun.serve and Bun.connect). Certificate verification is enforced when rejectUnauthorized is true or unspecified.
TLS verification behavior is tested independently in test/js/valkey/valkey-tls-verify.test.ts: a client connecting with the wrong CA or hostname must fail certificate validation.
Sources: packages/bun-types/redis.d.ts36-38 test/js/valkey/test-utils.ts80-98 test/js/valkey/valkey-tls-verify.test.ts
Connection errors propagate as rejected Promises on any in-flight command:
Invalid arguments are rejected synchronously (before any network I/O):
Server errors (wrong number of arguments, unknown command, etc.) reject the command's Promise with the server's error message:
Auto-reconnect is controlled by autoReconnect (default true) and maxRetries (default 10). When disabled, any post-close command throws immediately:
Sources: test/js/valkey/reliability/error-handling.test.ts73-118 test/js/valkey/reliability/connection-failures.test.ts17-34 packages/bun-types/redis.d.ts18-26
The following table maps command groups to the available typed methods. For commands not listed as typed methods, use client.send(command, args).
| Category | Typed methods | Notes |
|---|---|---|
| Strings | get, getBuffer, set, del, incr, incrby, incrbyfloat, decr, decrby, mget, mset, msetnx, append, strlen, getrange, setrange, getdel, getex, getset, setnx, setex, psetex, substr | Full SET option matrix via overloads |
| Expiry | expire, expireat, pexpire, pexpireat, ttl, pttl, persist, expiretime, pexpiretime | All return counts per key |
| Key meta | exists, type, rename, renamenx, copy, dump, touch, scan, sort | exists returns boolean via RESP3 |
| Hashes | hset, hsetnx, hget, hmget, hmset, hdel, hexists, hlen, hkeys, hvals, hgetall, hincrby, hincrbyfloat, hrandfield, hexpire, hpexpire, hgetdel, hgetex, hsetex, hpersist | Per-field TTL requires Redis 7.4+ / Valkey |
| Lists | lpush, rpush, lpushx, rpushx, lpop, rpop, llen, lrange, lindex, lset, linsert, lrem, ltrim, lmove, blpop, brpop | Blocking variants: blpop, brpop |
| Sets | sadd, srem, smembers, sismember, smismember, scard, spop, srandmember, sunion, sinter, sdiff, sunionstore, sinterstore, sdiffstore | smembers returns Array via RESP3 |
| Sorted Sets | zadd, zrange, zrangebyscore, zrank, zscore, zincrby, zrem, zcard, zpopmin, zpopmax, bzpopmin, bzpopmax, zrandmember, zdiff, zunion, zinter | Full score range syntax |
| Bit ops | setbit, getbit, bitcount, bitop, bitpos | |
| HyperLogLog | pfadd, pfcount, pfmerge | Probabilistic cardinality |
| Geo | geoadd, geodist, geopos, geosearch, geosearchstore, geohash | |
| Streams | xadd, xread, xrange, xrevrange, xlen, xtrim, xdel, xgroup, xreadgroup, xack, xpending | |
| Pub/Sub | subscribe, unsubscribe, psubscribe, punsubscribe, publish | Mode-switching on subscription |
| Scripting | eval, evalsha, script | |
| Server | ping, select, dbsize, flushdb, flushall, info, keys, scan |
Full signatures for all methods are in packages/bun-types/redis.d.ts
Sources: packages/bun-types/redis.d.ts test/js/valkey/valkey.test.ts
The test suite under test/js/valkey/ uses a Docker Compose service (redis_unified) that provides both plain TCP (port 6379) and TLS (port 6380) listeners, ACL-controlled users, and Unix socket access via a proxy. The createClient factory in test/js/valkey/test-utils.ts234-293 constructs clients for each connection type.
Sources: test/js/valkey/test-utils.ts156-200 test/docker/docker-compose.yml159-175
Refresh this wiki
This wiki was recently refreshed. Please wait 1 day to refresh again.