Library / SDK
bee-queue/arena avatar
bee-queue/arena

bull-arena: a web dashboard for Redis backed job queues

An interactive UI dashboard for Bee, Bull and BullMQ packages

938 stars227 forksJavaScriptMIT

At a glance

What is it?
bee-queue/arena is an Express based web UI that renders the state of Bull, BullMQ and Bee Queue queues, including job details, stacktraces, retry and restart. It ships as an npm package that you mount or run standalone, and it holds no queue data of its own beyond the Redis connection you give it.
Who is it for?
Adopt bull-arena when you already run Bull, BullMQ or Bee Queue on Redis and need a readable view of queue state plus one click retry, since it is a thin rendering layer over a queue library rather than a queue implementation of its own.
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 84 days ago.
What is it written in?
Mainly JavaScript, 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 rendering layer over three queue libraries, not a queue itself

Arena does not run jobs. It reads them. The description is precise about this: it is an interactive UI dashboard for Bee Queue, Bull and BullMQ packages, and the README calls it "An intuitive Web GUI" for those three libraries. That framing explains the architecture, which is built on Express so that you can run Arena standalone or mount it in another app as middleware.

The practical consequence is that Arena is bound to Redis backed queues. There is no generic queue adapter layer in the documentation. The libraries themselves are the data source, and every queue you want to see has to be declared in a configuration object with a name, a human readable host identifier and a type. The library in use must be passed in explicitly, because the code cannot guess which queue implementation backs a given Redis keyspace.

It is worth being clear about who this serves. Operations and backend engineers looking at a stuck or failing queue while on call. It is a tool for looking, and for nudging individual jobs, not for scheduling, retry policy design or capacity planning.

Four things the queue overview actually gives you

The feature list is short, which is a strength when you are debugging under pressure. The README lists four capabilities: checking the health of a queue and its jobs at a glance, paginating and filtering jobs by state, viewing details and stacktraces of jobs with permalinks, and restarting or retrying jobs with one click.

The stacktrace support is the part that distinguishes Arena from a queue metrics exporter. A job that failed because of a bug in a payload transformer leaves a trace, and that trace is rendered in the browser next to the job's data. Permalinks mean you can paste a URL into a chat channel and have the other engineer land on the same failing job, which removes the usual excuse of describing a failure in words instead.

Filtering by state is the mechanism that keeps the view usable on a busy queue. Completed and failed jobs accumulate, and pagination with a state filter is how you isolate the active and the failed sets from the historical mass. The one thing you do not get is a history: nothing in the documented features covers job timing trends, throughput over time or queue depth alerting.

Declaring queues: name, hostId and the library you actually use

The configuration object is where most integration time goes, so it is worth reading closely. The README gives this shape for a queue definition, and the same pattern applies to a Bull or BullMQ setup with the relevant library passed in alongside the queues array.

js
const Arena = require('bull-arena');

// Mandatory import of queue library.
const Bee = require('bee-queue');

Arena({
  // All queue libraries used must be explicitly imported and included.
  Bee,

  // Provide a `Bull` option when using bull, similar to the `Bee` option above.

  queues: [
    {
      // Required for each queue definition.
      name: 'name_of_my_queue',

      // User-readable display name for the host. Required.
      hostId: 'Queue Server 1',

      // Queue type (Bull or Bee - default Bull).
      type: 'bee',

      // Queue key prefix. Defaults to "bq" for Bee and "bull" for Bull.
      prefix: 'foo',
    },
  ],

  // Optionally include your own stylesheet
  customCssPath: 'https://example.com/custom-arena-styles.css',

  // Optionally include your own script
  customJsPath: 'https://example.com/custom-arena-js.js',

  // Optionally expand a single host on the queues overview page by its `hostId`.
  // All other hosts start collapsed. When omitted, every host starts collapsed.
  activeHostId: 'Queue Server 1',
});

Two fields are mandatory inside each queue object, `name` and `hostId`, and the name has to match exactly what the queue library uses. The `hostId` is the grouping label you see in the overview, which is how you keep a production cluster and a staging cluster apart. The `prefix` field sets the Redis key prefix, defaulting to bq for Bee and bull for Bull, and mismatching it is the classic reason a configured queue shows up empty.

Three ways to point Arena at Redis, and the client difference underneath

Connection details can be given in three forms, and the third one exists because the two supported queue libraries use different Redis clients. The first is the explicit host and port form, where only the hostname is required and the port has a default.

jsonc
// In a queue object.
{
  // Hostname or IP. Required.
  "host": "127.0.0.1",

  // Bound port. Optional, default: 6379.
  "port": 6379,

  // Optional, to issue a redis AUTH command.
  "password": "hello",

  // Optional; default 0. Most of the time, you'll leave this absent.
  "db": 1
}

The second form replaces those fields with a single URL.

js
{
  "url": "[redis:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]"
}

The third form is the escape hatch. Bee uses the node redis client and Bull uses ioredis, and those two expect different configuration shapes, so a raw redis object is passed straight through to whichever client your queue uses.

js
{
  "redis": {}
}

Because the object is forwarded verbatim, a key that one client accepts and the other rejects will behave differently depending on your queue type. The documentation also flags a specific environment issue, noting that if you use Amazon Web Services ElastiCache as your Redis host you should check the linked article about Bull queue AWS autodiscovery, which is a sign that managed Redis topologies need extra care.

Mounting as middleware and the listen options you can change

Arena can be embedded in an existing Express application rather than run as its own service, and that is where the more interesting configuration lives. The second argument to Arena, listenOpts, controls the HTTP layer, and the documented keys are port, host, basePath, disableListen, useCdn and activeHostId, plus customCssPath for an external stylesheet.

js
const Arena = require('bull-arena');

const express = require('express');
const router = express.Router();

const arena = Arena({
  // Include a reference to the bee-queue or bull libraries, depending on the library being used.

  queues: [
    {
      // First queue configuration
    },
    {
      // Second queue configuration
    },
    {
      // And so on...
    },
  ],
});

router.use('/', arena);

The defaults are worth internalising: port 4567, host 0.0.0.0, basePath /. The 0.0.0.0 default means the standalone server binds all interfaces, which is exactly what you want inside a container and exactly what you may not want on a laptop on shared wifi. `disableListen` exists for the sub-app case, where the parent Express server owns the socket. `useCdn` defaults to true, meaning the front end assets load from a CDN, and setting it to false makes Arena serve the bundled js and css, which is the option you need when the host has no outbound internet access.

Embedding also unlocks dynamic configuration. The README lists fetching the available Redis queues from an AWS instance at server start, or plain reading from environment variables, as examples of configuration you can compute in your own code before handing it to Arena.

Standalone runs through Docker with a Redis 6 alpine container

A Docker image and a separate docker-arena repository exist for the standalone case, and the repository ships a compose file for the Redis side of that arrangement. The compose file is small, which tells you Arena itself is meant to be configured through its own options rather than through compose environment variables.

yaml
version: '3.2'
services:
  redis:
    image: redis:6-alpine
    container_name: redis-6
    ports:
      - 6379:6379

Note the port mapping. Redis is published on the host at 6379, so a locally running Arena on its default port 4567 talks to a Redis that is not local to it. If you start Arena inside another container, the host value in the queue configuration has to be the compose service name rather than 127.0.0.1, since 127.0.0.1 inside a container is that container.

For the local, non container case the install is a single npm command in your project folder.

shell
$ npm install bull-arena

The package name is bull-arena even though the repository and the newer queue libraries are broader than the original Bull project. Its package.json lists express, express-handlebars, handlebars, body-parser, lodash, moment and tablesort as runtime dependencies, which explains the server rendered page structure and the client side sorting of the job tables.

Version 4.x releases, a Node floor, and what the licence covers

Release history is recent but not constant. The listed releases are v4.10.0 on 2026-07-31, followed by v4.9.2 and v4.9.1 both on 2025-11-18, and the last push was on 2026-07-31, matching the newest tag. The repository is not archived. Releases are produced by semantic-release, and the scripts section of package.json shows a conventional commit workflow enforced with commitlint, plus a husky hook and lint-staged, so the release cadence follows the commit history rather than a hand managed schedule.

One constraint is stated twice and will bite on a legacy host. Arena is implemented using async and await, so it only supports Node 7.6 or newer. The repository also carries a .nvmrc file, which is the usual signal that a specific runtime version is used in development and CI.

The licence is MIT, which covers the software itself. That is worth separating from the data you point it at: Arena grants no rights over the jobs it displays, and a dashboard that shows a payload does not make that payload yours. For anything beyond reading a queue you already control, the authentication question needs an answer, and the documented listen options do not include one.

Editorial conclusion

Adopt bull-arena when you already run Bull, BullMQ or Bee Queue on Redis and need a readable view of queue state plus one click retry, since it is a thin rendering layer over a queue library rather than a queue implementation of its own. Do not adopt it for non Redis backends, for users who need role based access control, or as a replacement for alerting, because the documented options cover host, port, credentials and mount path but nothing about authentication on the dashboard. Verify first that the Redis instance you point it at is reachable with the credentials in your queue definition, that your Node version satisfies the stated minimum of 7.6, and that the queue names in the configuration match the names your workers register.

Frequently asked questions

How do I install bull-arena and mount it in an Express app?

Install the package with npm install bull-arena in your project, then require it along with the queue library you use, pass the queue definitions, and mount the returned handler on a router with router.use('/', arena). The README also documents a standalone path through the Docker image and the docker-arena repository.

Why does my bull-arena queue appear empty even though jobs are running?

The queue name has to match exactly what you defined in Bull, and the prefix key has to match the one your queue library uses, which defaults to bq for Bee and bull for Bull. If the host in the configuration does not resolve to the same Redis instance your workers write to, the dashboard will connect successfully and still show nothing.

Can bull-arena monitor BullMQ flows as well as queues?

The configuration accepts flow configuration alongside queue configuration, but the README notes that flow support applies to bullmq for now. There is an example file in the repository named bullmq_with_flows.js that shows the shape.

What Node version does bull-arena require?

The documentation states that Arena is implemented using async and await and therefore only supports Node 7.6 or newer. The repository includes a .nvmrc file for the runtime version used during development.

Official sources

  1. bee-queue/arena on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bee-queue-arena.svg)](https://hysenlabs.com/projects/bee-queue-arena)

Was this useful?