Standards Docs
Guides

Redis & BullMQ

Wire Redis caching and BullMQ async job queues into a standards application.

standards uses Redis for read caching and BullMQ (Redis-backed) for async job queues. Both are wired through adapters.

Breaking in vNEXT: BullMQ and Redis implementations now live in dedicated packages — @stndrds/adapter-bullmq and @stndrds/adapter-redis. The deprecated re-exports from @stndrds/adapter-nestjs have been removed, as have the AGENT_ORCHESTRATOR_SERVICE / AGENT_RUNNER_SERVICE tokens (use AGENT_DEFINITION_SERVICE + AGENT_SESSION_SERVICE and AGENT_EXECUTION_SERVICE).

Setup

Parse REDIS_URL once and share the connection config across all adapters and queues.

// @noverify
import { BullMQQueueAdapter, BullMQWorkerAdapter } from "@stndrds/adapter-bullmq";
import { RedisCacheAdapter, RedisRealtimeTransport } from "@stndrds/adapter-redis";
import { Queue } from "bullmq";

const redisUrl = process.env.REDIS_URL ?? "redis://localhost:6379";
const parsedRedis = new URL(redisUrl);
const redisConnection = {
  host: parsedRedis.hostname,
  port: Number(parsedRedis.port) || 6379,
  ...(parsedRedis.password ? { password: parsedRedis.password } : {}),
};

const agentQueue = new Queue("agent-runs", { connection: redisConnection });

const cache = new RedisCacheAdapter({ url: redisUrl });
const transport = new RedisRealtimeTransport(redisUrl);
const queue = new BullMQQueueAdapter(agentQueue);

Why both

Redis caches read-heavy queries — records, schema definitions, view configs — so repeated fetches hit memory instead of Postgres. BullMQ runs async jobs on top of the same Redis instance: agent invocations, event processors, scheduled workflows. They share the connection config, so you only parse the URL once and pass the same redisConnection object everywhere.

Workers

BullMQWorkerAdapter consumes jobs from the queues. You can co-locate workers in the same API process (simpler setup) or run them as a separate process (recommended for production scale, lets you scale workers independently and avoid blocking the HTTP server under load).

// @noverify
import { BullMQWorkerAdapter } from "@stndrds/adapter-bullmq";

const worker = new BullMQWorkerAdapter({
  queueName: "agent-runs",
  connection: redisConnection,
  concurrency: 5,
});

Pass worker to SchemaModule.forRoot alongside queue to have the runtime route jobs to it automatically. The runtime registers a scheduled-job handler so cron-triggered agent runs reach launchRun — without it, scheduled payloads would be enqueued but never executed.

BullMQScheduleAdapter handles scheduled (cron-based) jobs and accepts the agent queue, not a raw connection config.

Env vars

  • REDIS_URLredis://[user:password@]host:port[/db]

Wire these in your SchemaModule.forRoot({ adapter, registry, cache, queue, transport, ... }). See the NestJS backend guide for the full wiring.

On this page