Not production ready

GroupMQ - per-group FIFO Queue for Node + Redis

Guaranteed ordering within a group, parallel processing across groups. Simple API, fast Lua scripts, and compatible with BullBoard.

GitHub
import Redis from "ioredis";
import { Queue, Worker } from "groupmq";

const redis = new Redis("redis://127.0.0.1:6379");

export const queue = new Queue<{ type: string; amount: number }>({
  redis,
  namespace: "orders",
});

await queue.add({
  groupId: "user:42",
  data: { type: "charge", amount: 999 },
});

const worker = new Worker({
  queue,
  handler: async (job) => {
    console.log("Processing:", job.data.type, job.data.amount);
  },
});

worker.run();
Waiting
3
Job 1
Job 2
Job 3
Active
0
Completed
0

Per‑Group FIFO

One in‑flight job per group, strict ordering guaranteed.

Jobs with the same groupId are processed sequentially. Different groups run in parallel for maximum throughput without conflicts.

Order by Timestamp

Respects orderMs; oldest timestamps first.

If orderMs is provided, the queue delays processing to ensure events arrive in the correct order, minimizing race conditions from late producers.

Idempotence

Safe to retry without duplicate side‑effects.

Deterministic job IDs and stable handlers make it straightforward to avoid double execution when retries occur.

Cron & Repeats

Simple repeatable jobs and cron patterns.

Use repeat.every for fixed intervals or repeat.pattern for cron syntax. Materialization occurs in the worker’s periodic cycle.

Delayed Jobs

Schedule work for the future.

Add jobs with a delay to control when they become eligible for processing, without blocking other groups.

Retries & Failures

Configurable backoff, attempts, and failure tracking.

Tune maxAttempts and backoff to your workload. Inspect counts and statuses to monitor and react to failures.

BullBoard Adapter

Drop-in monitoring UI using your existing BullBoard setup

import express from 'express';
import { createBullBoard } from '@bull-board/api';
import { ExpressAdapter } from '@bull-board/express';
import { BullBoardGroupMQAdapter } from 'groupmq/adapters/groupmq-bullboard-adapter';
import { queue } from './queue';

const app = express();
const serverAdapter = new ExpressAdapter();

createBullBoard({
  queues: [new BullBoardGroupMQAdapter(queue, { displayName: 'Orders' })],
  serverAdapter,
});

serverAdapter.setBasePath('/admin/queues');
app.use('/admin/queues', serverAdapter.getRouter());
app.listen(3000);

Inspired by BullMQ

GroupMQ is heavily inspired by BullMQ and have tried to keep the API as similar as possible. But with some differences to make it better for our use case.

BullMQ supports grouping but it's in there PRO package.

Read more about BullMQ

Open Source

MIT licensed. Contributions welcome.

github.com/openpanel-dev/groupmq

GroupMQ powering OpenPanel.dev

GroupMQ powers internal pipelines at OpenPanel.dev. We designed it to be small, reliable, and easy to operate.

Trusted by

This could be youOpenPanel.devThis could be you
This could be youOpenPanel.devThis could be you
This could be youOpenPanel.devThis could be you
This could be youOpenPanel.devThis could be you

GroupMQ reduced a lot of edge cases from simultaneous events for the same users. By controlling how many jobs per group run at once, we avoid race conditions and ensure events are processed in the right order.

Carl LindesvärdCarl Lindesvärd, Founder at OpenPanel.dev