Use Case

Add realtime to your app in 10 lines of code

KSUB is a new primitive built into Lux's storage engine. Subscribe to key patterns, get events on mutation. No WebSocket server, no message broker, no polling. Realtime that lives where your data already is.

The problem

Every realtime feature starts the same way: set up a WebSocket server, handle connections and reconnections, manage rooms and channels, figure out state synchronization, and pray it scales. Or use a hosted service like Pusher or Ably and pay per message, which gets expensive fast once you have any meaningful traffic. Redis pub/sub helps with fan-out but it's fire-and-forget with no persistence and no pattern matching on keys. You publish a message, and if nobody is listening, it's gone. So you end up layering Redis pub/sub on top of Redis state on top of a WebSocket server, and now you're maintaining three things that all need to agree on what the current state of the world is.

Without Lux

Four services to build, deploy, and keep in sync.

WebSocket Server

Connection handling

Redis Pub/Sub

Message fan-out

Reconnection Logic

Client-side retry

State Management

Conflict resolution

With Lux

State and subscriptions live in the same place. Write a key, subscribers get notified.

Lux + KSUB

State storage + realtime subscriptions + pattern filtering

Basic subscription

import { Lux } from "@luxdb/sdk"

const db = new Lux(process.env.LUX_DIRECT_URL ?? "lux://localhost:6379")

const sub = db.ksub(["game:room:*"], (event) => {
  console.log(event.key, event.operation)
})

await db.set("game:room:1:player:alice", JSON.stringify({ x: 10, y: 20 }))

Any client writing to a matching key triggers the callback instantly. The event includes the key name and the operation (set, del, hset, etc.).

How it works

KSUB is a new primitive built into Lux's storage engine. Subscribe to a key pattern like game:room:*, and get events whenever matching keys are mutated. Events include the key name and the operation (set, del, hset, etc.). This isn't a bolt-on feature or a compatibility layer. KSUB is part of the write path itself.

The key difference from Redis keyspace notifications: KSUB has zero overhead when nobody is listening. The check is a single atomic operation on the write path. If no subscribers match the key being written, the cost is effectively nothing. When subscribers do exist, event dispatch is fully async. Writers never block on subscriber fanout, no matter how many listeners are attached. Your write latency stays constant.

Compare this to how other systems solve the same problem. Supabase built an entire separate Go service (Realtime) that polls the Postgres WAL to detect changes and fan them out over WebSockets. That's a whole service to deploy, monitor, and scale. KSUB does the same thing from inside the write path in microseconds, because it's not polling anything. It fires on mutation.

Because Lux is also your state store, there's no split-brain problem. The data and the subscription live in the same process. When a key changes, subscribers know about it before the write response even reaches the caller. You don't need a separate WebSocket service, a separate pub/sub layer, or a separate state reconciliation system. It's all one thing.

Live collaboration with KSUB

import { Lux } from "@luxdb/sdk"

const db = new Lux(process.env.LUX_DIRECT_URL ?? "lux://localhost:6379")

const docId = "doc:abc123"
const userId = "user:alice"

await db.hset(`${docId}:cursors`, userId, JSON.stringify({
  x: 120, y: 340, color: "#7c3aed"
}))

await db.hset(`${docId}:content`, "title", "Project Roadmap")
await db.hset(`${docId}:content`, "body", "## Q3 Goals\n- Launch v2...")

db.ksub([`${docId}:*`], async (event) => {
  if (event.key.endsWith(":cursors")) {
    const cursors = await db.hgetall(event.key)
    renderCursors(cursors)
  } else if (event.key.endsWith(":content")) {
    const content = await db.hgetall(event.key)
    renderDocument(content)
  }
})

KSUB for notifications, KV/hashes for persistent state. Cursors and document content stored in Lux, subscribers notified on every change.

Feature deep-dive

Zero-Overhead Subscriptions

When nobody is listening, KSUB costs nothing. The write path checks a single atomic flag to see if any subscribers exist for the key pattern. If not, it skips event dispatch entirely. No background threads, no polling, no WAL tailing. You can have KSUB enabled on every key pattern in your application and pay zero performance cost until something actually subscribes.

Pattern-Based Filtering

Subscribe to exact keys or glob patterns. game:room:* captures every room update. doc:abc123:* watches all fields of a document. No need to subscribe to each key individually. Pattern matching happens at the engine level, so you get exactly the events you care about without client-side filtering.

Built-in Dashboard Inspector

The Lux Cloud dashboard shows active KSUB subscriptions, event throughput, and subscriber counts in real time. See which patterns are being watched, how many events per second are firing, and debug subscription issues without adding logging to your application code. It's observability for your realtime layer, built in from day one.

<1ms

Write to subscriber latency

Zero

Overhead when unused

None

Separate WebSocket service needed

Star on GitHub