new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Runtime · all subjects

bun apis/redis

41 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Redis (Valkey) client APIs: Bun.RedisClient and Bun.redis

Bun provides Bun.RedisClient and Bun.redis for Redis/Valkey client connectivity.

Import Redis client

Import the Redis client with `import { redis, RedisClient } from "bun";`

Default Redis client environment variables

The default Redis client reads connection information from environment variables in this order of precedence: REDIS_URL, VALKEY_URL. If neither is set, it defaults to "redis://localhost:6379".

Create custom RedisClient

Create a custom RedisClient instance with: new RedisClient("redis://[username:password@]localhost:6379"). The connection is not made until a command is executed.

Redis client connection lifecycle

The Redis client automatically handles connections. No connection is made when the client is created. The first command initiates the connection. The connection remains open for subsequent commands. Close explicitly with client.close().

Manually connect and disconnect Redis client

Call await client.connect() to explicitly connect to Redis. Call client.close() to disconnect when done.

String operations in Redis

Redis string operations include: set(key, value), get(key), getBuffer(key) returns Uint8Array, del(key), exists(key), expire(key, seconds), ttl(key) returns seconds to live.

Numeric operations in Redis

Redis numeric operations include: incr(key) increments by 1, decr(key) decrements by 1. Use set(key, value) to initialize the counter.

Hash operations in Redis

Redis hash operations include: hmset(key, [field, value, field, value, ...]), hmget(key, [field1, field2, ...]) returns array of values, hget(key, field) returns single value or null, hincrby(key, field, amount), hincrbyfloat(key, field, amount).

Set operations in Redis

Redis set operations include: sadd(key, member), srem(key, member), sismember(key, member), smembers(key) returns all members, srandmember(key) returns random member, spop(key) removes and returns random member.

Redis Pub/Sub availability

Bun provides native bindings for Redis Pub/Sub protocol, added in Bun 1.2.23. Redis Pub/Sub is experimental in Bun.

Publish to Redis channel

Publish messages using: await client.publish(channelName, message);

Subscribe to Redis channel

Subscribe to channels using: await client.subscribe(channel, (message, channel) => {}). The callback receives the message and channel name.

Unsubscribe from Redis channel

Unsubscribe with: await client.unsubscribe() to unsubscribe from all channels, await client.unsubscribe(channel) to unsubscribe from a particular channel, or await client.unsubscribe(channel, listener) to unsubscribe a particular listener.

Redis subscription connection limitation

A RedisClient with subscriptions can only call RedisClient.prototype.subscribe(). To send other commands to Redis while subscribed, create a separate connection using await redis.duplicate().

Automatic command pipelining in Redis

The Redis client automatically pipelines commands by default, improving performance by sending multiple commands in a batch and processing responses as they arrive.

Disable Redis auto-pipelining

Disable automatic pipelining by passing enableAutoPipelining: false in the options when creating a RedisClient: new RedisClient(url, { enableAutoPipelining: false })

Execute raw Redis commands

Use the send method to run any Redis command: await redis.send(commandName, [arg1, arg2, ...]) where commandName is a string and the second argument is an array of string arguments.

Redis connection event handlers

Register handlers for connection events: client.onconnect = () => {} called when successfully connected, and client.onclose = (error) => {} called when disconnected from Redis server.

Check Redis connection status

Check if connected with client.connected which returns a boolean. Check buffered data in bytes with client.bufferedAmount.

Redis response type conversion

The client automatically converts Redis responses: Integer responses become JavaScript numbers, bulk strings become JavaScript strings, simple strings become JavaScript strings, null bulk strings become null, array responses become JavaScript arrays, error responses throw JavaScript errors, RESP3 boolean responses become JavaScript booleans, RESP3 map responses become JavaScript objects, RESP3 set responses become JavaScript arrays. Special handling: EXISTS returns boolean (1→true, 0→false), SISMEMBER returns boolean.

Redis commands that disable auto-pipelining

The following commands disable automatic pipelining: AUTH, INFO, QUIT, EXEC, MULTI, WATCH, SCRIPT, SELECT, CLUSTER, DISCARD, UNWATCH, PIPELINE, SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE, UNPSUBSCRIBE.

RedisClient connection options

Connection options for new RedisClient(url, options): connectionTimeout (milliseconds, default 10000), idleTimeout (milliseconds, default 0 = no timeout), autoReconnect (boolean, default true), maxRetries (number, default 20), enableOfflineQueue (boolean, default true), enableAutoPipelining (boolean, default true), tls (boolean or object with rejectUnauthorized, ca, cert, key paths, default false).

Redis client reconnection behavior

When connection is lost, the client automatically attempts to reconnect with exponential backoff. It starts with 50ms delay and doubles with each attempt, capped at 2000ms. It attempts up to maxRetries times (default 20). Commands executed during disconnection are queued if enableOfflineQueue is true (default), or rejected if false.

Supported Redis URL formats

RedisClient supports: standard redis://localhost:6379, with auth redis://username:password@localhost:6379, with database redis://localhost:6379/0, TLS rediss://localhost:6379 or redis+tls://localhost:6379, Unix socket redis+unix:///path/to/socket, TLS over Unix socket redis+tls+unix:///path/to/socket.

Redis error codes

Common Redis error codes: ERR_REDIS_CONNECTION_CLOSED (connection was closed), ERR_REDIS_AUTHENTICATION_FAILED (failed to authenticate), ERR_REDIS_INVALID_RESPONSE (received invalid response from server).

Redis implementation details

Bun's Redis client is implemented in Rust and uses the Redis Serialization Protocol (RESP3). It reconnects automatically with exponential backoff and pipelines commands to send multiple commands without waiting for replies.

Redis transactions limitation

Transactions (MULTI/EXEC) must be done through raw commands using the send method.

Unsupported Redis features

Redis Sentinel and Redis Cluster are not supported in Bun's Redis client.

Basic Redis example

Example showing basic Redis operations: ```ts import { redis } from "bun"; // Set a key await redis.set("greeting", "Hello from Bun!"); // Get a key const greeting = await redis.get("greeting"); console.log(greeting); // "Hello from Bun!" // Increment a counter await redis.set("counter", 0); await redis.incr("counter"); // Check if a key exists const exists = await redis.exists("greeting"); // Delete a key await redis.del("greeting"); ```

Redis connection creation example

Example showing how to create and use a Redis client: ```ts import { redis, RedisClient } from "bun"; // Using the default client (reads connection info from environment) await redis.set("hello", "world"); const result = await redis.get("hello"); // Creating a custom client const client = new RedisClient("redis://username:password@localhost:6379"); await client.set("counter", "0"); await client.incr("counter"); ```

Redis Pub/Sub publisher example

Example showing how to publish messages: ```typescript import { RedisClient } from "bun"; const writer = new RedisClient("redis://localhost:6739"); await writer.connect(); writer.publish("general", "Hello everyone!"); writer.close(); ```

Redis Pub/Sub subscriber example

Example showing how to subscribe to messages: ```typescript import { RedisClient } from "bun"; const listener = new RedisClient("redis://localhost:6739"); await listener.connect(); await listener.subscribe("general", (message, channel) => { console.log(`Received: ${message}`); }); ```

Redis duplicate connection for subscriptions

Example showing how to use duplicate() to create a separate connection for other commands while subscribed: ```ts import { RedisClient } from "bun"; const redis = new RedisClient("redis://localhost:6379"); await redis.connect(); const subscriber = await redis.duplicate(); await subscriber.subscribe("foo", () => {}); await redis.set("bar", "baz"); ```

Redis raw commands example

Example showing how to execute raw Redis commands: ```ts // Run any Redis command const info = await redis.send("INFO", []); // LPUSH to a list await redis.send("LPUSH", ["mylist", "value1", "value2"]); // Get list range const list = await redis.send("LRANGE", ["mylist", "0", "-1"]); ```

Redis connection events example

Example showing how to register and handle connection events: ```ts const client = new RedisClient(); // Called when successfully connected to Redis server client.onconnect = () => { console.log("Connected to Redis server"); }; // Called when disconnected from Redis server client.onclose = error => { console.error("Disconnected from Redis server:", error); }; // Manually connect/disconnect await client.connect(); client.close(); ```

Redis caching use case example

Example showing how to implement caching with Redis: ```ts async function getUserWithCache(userId) { const cacheKey = `user:${userId}`; // Try to get from cache first const cachedUser = await redis.get(cacheKey); if (cachedUser) { return JSON.parse(cachedUser); } // Not in cache, fetch from database const user = await database.getUser(userId); // Store in cache for 1 hour await redis.set(cacheKey, JSON.stringify(user)); await redis.expire(cacheKey, 3600); return user; } ```

Redis rate limiting use case example

Example showing how to implement rate limiting with Redis: ```ts async function rateLimit(ip, limit = 100, windowSecs = 3600) { const key = `ratelimit:${ip}`; // Increment counter const count = await redis.incr(key); // Set expiry if this is the first request in window if (count === 1) { await redis.expire(key, windowSecs); } // Check if limit exceeded return { limited: count > limit, remaining: Math.max(0, limit - count), }; } ```

Redis session storage use case example

Example showing how to implement session storage with Redis: ```ts async function createSession(userId, data) { const sessionId = crypto.randomUUID(); const key = `session:${sessionId}`; // Store session with expiration await redis.hmset(key, ["userId", userId.toString(), "created", Date.now().toString(), "data", JSON.stringify(data)]); await redis.expire(key, 86400); // 24 hours return sessionId; } async function getSession(sessionId) { const key = `session:${sessionId}`; // Get session data const exists = await redis.exists(key); if (!exists) return null; const [userId, created, data] = await redis.hmget(key, ["userId", "created", "data"]); return { userId: Number(userId), created: Number(created), data: JSON.parse(data), }; } ```

Redis client version requirement

Bun's Redis client supports Redis server versions 7.2 and up.

Redis error handling example

Example showing how to handle Redis errors: ```ts try { await redis.get("non-existent-key"); } catch (error) { if (error.code === "ERR_REDIS_CONNECTION_CLOSED") { console.error("Connection to Redis server was closed"); } else if (error.code === "ERR_REDIS_AUTHENTICATION_FAILED") { console.error("Authentication failed"); } else { console.error("Unexpected error:", error); } } ```

Give your agent this brain