Build on the supported package contract
Use @absolutejs/sync-bus-redis through its supported public entry points.
@absolutejs/sync-bus-redisv0.1.2betaData & SyncRedis pub/sub ClusterBus for @absolutejs/sync — cross-instance fan-out via PUBLISH/SUBSCRIBE. Sibling to @absolutejs/sync-bus-pg; faster fanout, better geo-replication story. Works with any Redis client (ioredis, node-redis, etc.) via a narrow tag-template interface.
bun add @absolutejs/sync-bus-redisRedis pub/sub ClusterBus for @absolutejs/sync. Sibling to @absolutejs/sync-bus-pg — same ClusterBus contract, different transport.
Docs: absolutejs.com/documentation/cluster-bus-overview#redis-adapter
Concern — sync-bus-redis — sync-bus-pg
Payload size — No cap — JSON through — 8KB NOTIFY cap (spill-table fallback)
Fan-out latency at 10+ subscribers — In-memory, low — WAL-replicated, higher
Geo-replication — Native (Redis Cluster, ElastiCache, Memorystore, Upstash) — Heavy ops (PG logical replication)
Delivery semantics — At-most-once (no message retention) — At-most-once (NOTIFY) + spill rows for oversized
Already in your stack? — If yes → win-win — If yes → win-win
The headline tradeoff. Redis is in-memory pub/sub — a subscriber that's disconnected when a message fires misses it. For cross-instance resume past shard reboot, pair with engine.exportChangeLog() / importChangeLog() (sync 1.19.0+) regardless of which bus you use.
Returns ClusterBus & { metrics() }. Pass to engine.connectCluster(bus).
bus.metrics()
Outcomes
Use @absolutejs/sync-bus-redis through its supported public entry points.
Hardening checklist
Follow in order
Working example for Usage with ioredis.
import { Redis } from 'ioredis';
import { createSyncEngine } from '@absolutejs/sync/engine';
import { createRedisClusterBus } from '@absolutejs/sync-bus-redis';
const publisher = new Redis(process.env.REDIS_URL!);
const subscriberClient = new Redis(process.env.REDIS_URL!);
// ioredis: a subscribed connection can't issue other commands.
// Bridge its EventEmitter API into our (channel, listener) shape:
const subscriber = {
subscribe: async (channel: string, listener: (msg: string) => void) => {
await subscriberClient.subscribe(channel);
const handler = (chan: string, msg: string) => {
if (chan === channel) listener(msg);
};
subscriberClient.on('message', handler);
return async () => {
subscriberClient.off('message', handler);
await subscriberClient.unsubscribe(channel);
};
},
};
const bus = createRedisClusterBus({ publisher, subscriber });
const engine = createSyncEngine({ instanceId: 'shard-A' });
await engine.connectCluster(bus);Working example for Usage with node-redis v4+.
import { createClient } from 'redis';
import { createRedisClusterBus } from '@absolutejs/sync-bus-redis';
const publisher = createClient({ url: process.env.REDIS_URL });
const subscriberClient = publisher.duplicate();
await Promise.all([publisher.connect(), subscriberClient.connect()]);
// node-redis: subscribe takes a callback directly.
const subscriber = {
subscribe: async (channel: string, listener: (msg: string) => void) => {
await subscriberClient.subscribe(channel, listener);
return async () => {
await subscriberClient.unsubscribe(channel);
};
},
};
const bus = createRedisClusterBus({ publisher, subscriber });Working example for API.
createRedisClusterBus({
publisher, // RedisPublisher — publish(channel, message)
subscriber, // RedisSubscriber — subscribe(channel, listener) → unsubscribe fn
channel?, // default 'absolutejs_sync_cluster'
onError?, // logger for parse / delivery failures
});Working example for bus.metrics().
{
published: number; // PUBLISH calls
received: number; // messages parsed + delivered to onMessage
publishErrors: number; // publisher.publish() rejections
subscribeErrors: number; // JSON.parse failures on incoming messages
totalSubscribersReached: number; // sum of counts Redis returned from PUBLISH
// — a drop to 0 when you expect peers signals
// subscriber disconnects (partition, restart)
}Supported entry points declared by this package manifest.
Package entry point declared in package.json.
Scripts declared by this package manifest.