redis-smq puts a full message queue API on top of a Redis connection
RedisSMQ: A high-performance Redis message queue for Node.js
At a glance
- What is it?
- RedisSMQ is a Redis backed message queue for Node.js, published as a pnpm and lerna monorepo where the core library, the REST API, the web UI and the benchmarks ship as separate packages. The queue model is richer than plain Redis lists, with FIFO, LIFO and priority queues, exchanges, consumer groups, retries and dead letter queues, and the release train currently sits on pre-release v11 tags.
- Who is it for?
- Adopt redis-smq if you already run Redis and want a Node.js queue with priority ordering, retries, dead letter handling, scheduling and an administration UI without adding a separate broker. Do not adopt it if your runtime cannot move to Node.js 22, since the package requires it, or if you need a stable release today, since the published versions are v11.0.0-next pre-releases.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 11 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A monorepo of six packages, not one library
redis-smq is presented as a high-performance Redis message queue for Node.js, but the npm surface is a set of packages under a pnpm workspace managed by lerna. The root package.json is private, the workspace uses [email protected] as its package manager, and the packages/ directory holds six published pieces.
The core library is redis-smq, described as the core message queue library. Next to it, redis-smq-common holds shared utilities and configuration, redis-smq-rest-api is a REST API with Swagger for administration, redis-smq-web-ui is a web dashboard for queue monitoring, redis-smq-web-server combines the UI and the API into one server, and redis-smq-benchmarks is a performance testing suite.
That layout has a direct consequence for installation, and the README is blunt about it: always use matching versions across packages. There is a version compatibility guide inside the core package docs, and a separate language-agnostic version matrix in the redis-smq-docs repository, which the README also points at for cross-implementation compatibility. If you install the core library and the REST API at different versions, you are outside the combination the maintainer tested.
The repository also carries a CHANGELOG.md, a release-notes/ directory, a commitlint config, husky hooks, eslint and prettier configuration, and a vitest config, so the tooling around the code is a conventional TypeScript monorepo setup.
Node.js 22 and a persistent Redis are the entry requirements
The requirements section is short and specific. Node.js must be at least 22, and the root package.json narrows that further with an engines field of ^22.14.0. Redis must be 4 or later, and the README adds the condition that persistence should be enabled for durability.
That persistence note matters more than it looks. A queue that acknowledges a message and then loses it when the Redis process restarts is a queue that drops work, so the durability story depends on how Redis is configured rather than on something redis-smq does for you. Treat that as a deployment requirement to verify, not a default that comes with the package.
Redis itself is not bundled. Instead you pick one of two supported clients, ioredis, which the README marks as recommended, or @redis/client from the node-redis project. The choice is passed at initialization time through the client enum, so the library does not force a specific client on you, but it does require you to declare which one you use.
The development setup in the repository reflects the same choices. Both ioredis 5.9.2 and @redis/client 5.12.1 appear as devDependencies of the root package, along with bluebird, uuid, supertest and the vitest runner.
Initialization is a one time call that names the client and the connection
The library is initialised once per process, and the call takes a client type plus connection options and a callback. The same flow in Promise form looks like this:
import { RedisSMQ, EQueueType, EQueueDeliveryModel } from 'redis-smq';
import { ERedisConfigClient } from 'redis-smq-common';
try {
// Initialize
await RedisSMQ.initialize({
client: ERedisConfigClient.IOREDIS,
options: { host: 'localhost', port: 6379 },
});
// Create queue
const queueManager = RedisSMQ.createQueueManager();
await queueManager.save(
'my_queue',
EQueueType.LIFO_QUEUE,
EQueueDeliveryModel.POINT_TO_POINT,
);
// Produce message
const producer = RedisSMQ.createProducer();
await producer.run();
const message = RedisSMQ.newProducibleMessage()
.setQueue('my_queue')
.setBody({ hello: 'world' });Two details in that snippet are worth pulling out. The client is selected by enum value, ERedisConfigClient.IOREDIS, and the options object is what the underlying client consumes, here a host and a port. And the queue is created through a queue manager with a save method that takes a name, a queue type and a delivery model.
The enums define the queue semantics. EQueueType offers LIFO_QUEUE, FIFO and PRIORITY, and EQueueDeliveryModel offers POINT_TO_POINT or PUB_SUB. So the same Redis installation can hold a strict first in first out queue, a last in first out stack for quick draining, and a priority queue where ordering follows a key you attach, and each can be either a work queue or a broadcast channel.
The README states that all methods support both callbacks and Promises, which is why the same flow appears twice in the documentation.
Messages are built with a fluent builder and a retry threshold
Producing a message means building an object with a chain of setters and handing it to a producer. The builder starts at RedisSMQ.newProducibleMessage(), then names the queue with setQueue, attaches a payload with setBody, and can set a retry threshold with setRetryThreshold, which the README marks as optional.
The producer itself is created with RedisSMQ.createProducer() and has a run method that takes a callback. The produce method then takes the built message and a callback that receives the message ids, so the caller learns the identifiers of what was sent.
The body is a plain JavaScript value. In the quick start it is an object, setBody({ hello: 'world' }), which means the payload is structured data rather than a string, and the consumer on the other end receives it as a message with a body field.
The retry threshold is the piece that turns this from a list into a queue. A message that fails repeatedly needs somewhere to go, and the reliability features the README lists include acknowledgements, dead letter queues, retries and message persistence. Combining a retry threshold with the acknowledgement model is what lets a consumer reject a message that cannot be processed and have the system take it further rather than dropping it silently.
Consumption is acknowledge or reject, with a delivery model chosen per queue
The consumer side mirrors the producer. RedisSMQ.createConsumer() gives you a consumer, run starts it, and consume takes a queue name, a handler and a callback. The handler receives a message and a done function.
That done function is the whole acknowledgement contract. Calling it acknowledges the message, and the README documents the alternative of passing an error to it to reject the message instead. Everything about reliability in this library reduces to that choice at the point where your handler finishes.
The handler shape is worth comparing with a typical Node.js consumer. There is no explicit subscribe call separate from the handler, no manual polling loop, and no batch size parameter in the example. The consumer is told a queue and given a function, and the library handles the delivery. The delivery model you selected on the queue then determines whether a message goes to one consumer or is published to many.
A point to point queue and a pub sub queue are the two ends of the range. Point to point is the work queue case, where one consumer takes the message and others do not see it. Pub sub is the broadcast case, where a message is fanned out to every interested consumer. The library lists pub/sub and exchanges among its features alongside the queue types, so the same connection can carry both patterns.
Scheduling, consumer groups and rate limiting come with the same Redis instance
The feature list in the README covers more than queues: FIFO, LIFO, priority queues, pub/sub, exchanges, scheduling, consumer groups and rate limiting, with acknowledgements, dead letter queues, retries and message persistence on the reliability side.
Scheduling is the one that changes the operational picture, because a delayed or scheduled job needs a timer somewhere. Doing that on Redis means the queue has to track when a message becomes eligible, and every worker has to agree on that. Consumer groups address a different problem, distributing messages across workers and tracking which group member has what. Rate limiting sits in the same family, bounding how much work a producer can push into the system.
The point worth making is that none of this requires a second system. The requirement list mentions only Node.js and Redis, and no separate broker, scheduler or coordinator appears anywhere in the setup. That is the appeal of the package for teams that already operate Redis and do not want to add and monitor another stateful service.
The administration story is similarly self-contained. The REST API package ships with Swagger for administration, and the web UI package is a dashboard for queue monitoring, with a combined web server package for running both together. Monitoring is therefore a feature of the distribution rather than something you build against a separate console.
The pre-release tags and the matching version rule are the adoption friction
The release history explains why the documentation tells you to check compatibility guides twice. The three most recent releases are v11.0.0-next.0 on 2026-10-10, v11.0.0-next.1 on 2026-10-11 and v11.0.0-next.2 on 2026-10-12, three consecutive days of pre-release builds. The default branch is next, and the README notes that the @next tag pulls the latest development version from the next branch, while @latest, or no tag at all, gives the stable release.
So the tags are not interchangeable, and a project that installs without thinking gets the stable line, while a project that follows the next branch gets a moving target. Both are legitimate choices, but the version numbers in play look like a major version still in progress.
The matching version rule compounds this. Because the core library, the common package, the REST API, the web UI and the web server are published separately, a project assembling the administration stack has to line up several version numbers, and the compatibility guide is the reference for doing that. The maintenance cost is therefore not one upgrade but a coordinated one.
The last push was on 2026-10-12, the repository is not archived, and the licence is MIT, which the root package.json records and which carries no copyleft obligation for a commercial deployment. That is a licensing note rather than legal advice, and it does not cover the Redis server itself.
The Go implementation and the language-agnostic spec are the alternatives to read
The README points at two sibling projects, and they answer different questions. go-redis-smq is the same queue model implemented in Go, and redis-smq-docs holds the language-agnostic concepts, described as architecture, queues, exchanges and more.
The Go port is the interesting alternative when your system is polyglot. If producers live in Go and consumers in Node.js, the question is whether the two implementations interoperate against the same Redis data, and the language-agnostic version matrix in the redis-smq-docs repository is where that is answered. The docs project is also the better place to learn the model itself, because it is written to be independent of any one language binding.
That is the difference in approach compared with reaching for a dedicated broker. A dedicated broker gives you a protocol, a storage engine and an operations story you do not maintain, at the cost of another service to run and a different client library. redis-smq keeps the data in Redis and the client in your own language, and asks you to accept the responsibility that follows from owning both halves, including persistence configuration and version alignment across packages.
The benchmarks package in the distribution is the place to look if throughput claims matter to you, since performance claims about any queue are only meaningful against the workload you have. The README describes it as a performance testing suite rather than publishing a single figure, which is the right shape for a claim you should verify yourself.
Editorial conclusion
Adopt redis-smq if you already run Redis and want a Node.js queue with priority ordering, retries, dead letter handling, scheduling and an administration UI without adding a separate broker. Do not adopt it if your runtime cannot move to Node.js 22, since the package requires it, or if you need a stable release today, since the published versions are v11.0.0-next pre-releases. Verify first that every redis-smq package in your dependency tree is on the same version, that the client you choose matches the one you pass to RedisSMQ.initialize, and that Redis persistence is enabled, because the README lists that as the condition for durability.
Frequently asked questions
How do I install redis-smq and set up a Redis connection?
Install the core packages with npm install redis-smq redis-smq-common, then add a Redis client, either ioredis which the README recommends or @redis/client. Call RedisSMQ.initialize once per process with the client enum and your connection options.
Which queue types and delivery models does redis-smq support?
EQueueType covers LIFO_QUEUE, FIFO and PRIORITY, and EQueueDeliveryModel covers POINT_TO_POINT or PUB_SUB. A queue is created with queueManager.save, passing the name, the type and the delivery model.
How do I acknowledge or reject a message in redis-smq?
The consumer handler receives a message and a done function. Call done() to acknowledge the message, or pass an error to it to reject it, which is what the retry and dead letter handling is built around.
What are the runtime requirements for redis-smq?
Node.js 22 or later, with the root package.json specifying ^22.14.0, and Redis 4 or later with persistence enabled for durability. You also need ioredis or @redis/client as the client.
Do all redis-smq packages have to be on the same version?
Yes. The README says to always use matching versions across packages, and points to a version compatibility guide in the core package docs plus a language-agnostic version matrix in the redis-smq-docs repository. The packages ship separately as redis-smq, redis-smq-common, redis-smq-rest-api, redis-smq-web-ui and redis-smq-web-server.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/weyoss-redis-smq)Was this useful?