# Bull-Board
> Dashboard for Bull and BullMQ job queues.
## Guide
- [Introduction](/bull-board/guide/introduction.md): Bull-Board is a dashboard for BullMQ and Bull. It mounts into your existing HTTP server and shows you what's in Redis. You still use Bull or BullMQ to enqueue and process jobs, bull-board only visualises them. Want to see it before installing? Open the live demo.
## Reference
- [UIConfig](/bull-board/configuration/ui-config.md): Applies to: all adapters. UIConfig controls the visual shell of the dashboard: title, logo, favicon, locale, polling, misc links. Pass it via setUIConfig() on the server adapter, or forward it through createBullBoard({ options: { uiConfig } }).
## Others
- [Production checklist](/bull-board/configuration/production-checklist.md): Quick gate before exposing the dashboard to real traffic.
- [Set up with an AI agent](/bull-board/guide/ai-agent-setup.md): If you work with a coding agent (Claude Code, Cursor, Copilot, Windsurf, whatever), you don't have to hand-wire bull-board. Paste the prompt below and let the agent do the mechanical part: install the packages, mount the adapter, match the base path. Then read the diff.
- [Exploring the dashboard](/bull-board/guide/exploring-the-dashboard.md): A tour of how the dashboard is laid out and the controls you'll use day to day: grouped queues, the collapsible sidebar, search, and the per-queue info panel.
- [Installation](/bull-board/guide/getting-started.md): Install the core @bull-board/api plus one adapter for your framework.
- [Your first dashboard](/bull-board/guide/your-first-dashboard.md): Express and BullMQ. Every other adapter follows the same three-step shape, see the adapter pages for specifics.
- [BullAdapter](/bull-board/queue-adapters/bull.md): For the Bull queue library.
- [BullMQ Pro](/bull-board/queue-adapters/bullmq-pro.md): For the BullMQ Pro queue library. Import BullMQProAdapter instead of BullMQAdapter to get awareness of Pro groups: group counts are folded into the waiting/delayed/paused job counts, jobs from waiting/limited/maxed/paused groups are listed alongside regular jobs in those tabs, and the group id is shown next to the job name in the UI.
- [BullMQAdapter](/bull-board/queue-adapters/bullmq.md): For the BullMQ queue library.
- [Queue Adapters](/bull-board/queue-adapters/index.md): Queue adapters wrap your Bull or BullMQ queue instances so the board can read and manipulate them. The core @bull-board/api ships with three built-in adapters; third-party queue systems can add their own.
- [Alerting on failed jobs](/bull-board/recipes/alerting.md): Applies to: all adapters. bull-board is a viewer, not a monitor. It shows the state of your queues while you have the tab open. It doesn't watch them for you and it sends nothing anywhere, so "how do I get alerted when a job fails?" isn't a question the dashboard answers. That part is on you, and it belongs in your worker code, not the board. BullMQ already emits the events you need. Wire your alerting to those, and use bull-board to investigate once an alert fires.
- [Add basic auth](/bull-board/recipes/basic-auth.md): The dashboard has no built-in auth. Don't expose it on the open internet without one. Here's the minimum per framework.
- [Polling interval](/bull-board/recipes/change-polling-interval.md): The dashboard polls GET /api/queues to refresh. Default is 5 seconds. Two knobs in UIConfig.
- [CSRF protection](/bull-board/recipes/csrf-protection.md): The dashboard's destructive actions (retry, clean, pause, obliterate) are state-changing PUT/POST calls. If the dashboard lives on the same origin as an untrusted user session, protect those calls with CSRF tokens. From examples/with-express-csrf. The example uses csrf-csrf (double-submit cookie pattern). The older csurf package is deprecated, don't reach for it. Two pieces are at play. doubleCsrfProtection rejects any non-GET request to /ui that lacks a valid token. The XSRF-TOKEN cookie is readable by the dashboard's bundled Axios, which mirrors it into the x-xsrf-token header on every request. That matches what getTokenFromRequest pulls off. The extra res.cookie dance exists because the base cookie set by csrf-csrf is httpOnly (tracked in a pending upstream PR). Dashboard JS needs a readable copy, hence the second cookie. If you're behind a login with SameSite=Lax session cookies, modern browsers already block most cross-site POSTs. Belt-and-suspenders CSRF on top doesn't hurt for high-value dashboards.
- [Link jobs to your own admin](/bull-board/recipes/external-job-url.md): If your jobs exist in your own admin app too (an order, an email, a rendered report), you can link each dashboard job card to the corresponding page in your app. Pass externalJobUrl to the queue adapter: The function receives the job's JSON representation and returns { href, displayText? }. The dashboard adds a link next to the job name pointing at your URL. Useful when debugging from the dashboard and you want to jump straight to the real-world record.
- [Formatters](/bull-board/recipes/formatters.md): Applies to: all adapters. Formatters rewrite how a job's fields render in the dashboard without touching producer or worker code. Useful when data, returnValue, name, or progress need a presentation layer: masking secrets, summarising big payloads, humanising enums, prefixing names in multi-tenant setups.
- [Global concurrency](/bull-board/recipes/global-concurrency.md): BullMQ supports a global cap on concurrent jobs across all workers for a queue. The dashboard exposes it as a text input on the queue detail page.
- [Historical metrics](/bull-board/recipes/historical-metrics.md): Applies to: BullMQ only.Beta: this feature ships in the opt-in @bull-board/metrics package. It is safe to run, but the API and Redis storage layout may still change in a minor release while it settles, so pin an exact version if you depend on the storage format. bull-board is a viewer, not a monitor, and its built-in throughput chart reflects that: it reads BullMQ's native queue.getMetrics(), a per-minute ring buffer capped at maxDataPoints, scoped to a single queue, and only as deep as that buffer's window. Restart the buffer's window, or just wait long enough, and the older points are gone. There's no long history and no cross-queue total, because BullMQ was never asked to keep one. @bull-board/metrics is an opt-in companion package that fills that gap. It doesn't replace the live chart, it adds a second, longer-retention path behind it: a recorder that snapshots the native metrics into Redis before they roll off, and a history provider you register with createBullBoard that lets the UI read them back.
- [Recipes](/bull-board/recipes/index.md): Most recipes link into the live demo so you can see the shape before porting it. Short, code-first walkthroughs for common setups. Each recipe is a page; each page ties back to a runnable example in the repo.
- [Job logs and flows](/bull-board/recipes/job-logs-and-flows.md): Two features people often miss.
- [Add and remove queues at runtime](/bull-board/recipes/manage-queues-at-runtime.md): Applies to: all adapters. createBullBoard isn't a one-shot call. It also returns four functions that change which queues the board shows while it's running, with no rebuild or restart: Use them when queues aren't all known at startup: per-tenant queues created on demand, queues discovered from a registry, or a dashboard that follows queues as workers spin them up and down.
- [Multiple dashboards in one app](/bull-board/recipes/multiple-dashboards.md): You might want separate dashboards for different queue groups. One per team, or one read-only and one read-write. From examples/with-multiple-instances. Each adapter is independent. Pass a different UIConfig per instance (boardTitle, boardLogo, environment badge) to make them visually distinct.
- [Next.js & Vercel](/bull-board/recipes/nextjs.md): There is no dedicated Next.js adapter — bull-board runs inside a Next.js API route using an existing adapter. Two runnable examples: examples/with-nextjs-app — App Router, @bull-board/hono adapter.examples/with-nextjs-pages — Pages Router, @bull-board/express adapter. Both deploy to Vercel. The mounting differs by router; the Vercel-specific config is identical and is the part most people miss.
- [Per-tenant visibility](/bull-board/recipes/per-tenant-visibility.md): Show each user only the queues they're allowed to see. One shared dashboard, per-request filtering. See also: Visibility guard for the full reference. From examples/with-fastify-visibility-guard (Fastify + cookie auth + JWT).
- [Read-only mode](/bull-board/recipes/read-only-mode.md): Applies to: all adapters. Read-only mode disables every destructive action on a queue. No retries, no removals, no queue operations (pause, resume, empty, clean, obliterate), no adding jobs. Use it to share the dashboard with stakeholders, support, or shared dev environments without risking anything.
- [Troubleshooting](/bull-board/recipes/troubleshooting.md): Applies to: all adapters. The failure modes below account for most "it won't load" reports. Nearly all of them come down to one thing: the path bull-board thinks it's mounted at doesn't match the path the browser actually requests.
- [Visibility guard](/bull-board/recipes/visibility-guard.md): Applies to: all adapters. A visibility guard is a per-request predicate on a queue adapter that decides whether the requester can see that queue. Use it for multi-tenant setups, or for role-based access on a shared dashboard.
- [Bun](/bull-board/server-adapters/bun.md): Bun. @bull-board/bun targets Bun's native HTTP server.
- [Elysia](/bull-board/server-adapters/elysia.md): Elysia on Bun. @bull-board/elysia is an Elysia plugin.
- [Express](/bull-board/server-adapters/express.md): Express.js. @bull-board/express mounts as a sub-router under any path.
- [Fastify](/bull-board/server-adapters/fastify.md): Fastify. @bull-board/fastify registers as a plugin.
- [H3](/bull-board/server-adapters/h3.md): H3. @bull-board/h3 plugs in as an H3 event handler.
- [Hapi](/bull-board/server-adapters/hapi.md): Hapi. @bull-board/hapi registers as a Hapi plugin.
- [Hono](/bull-board/server-adapters/hono.md): Hono. @bull-board/hono gives you a Hono sub-app.
- [Server Adapters](/bull-board/server-adapters/index.md): One server adapter per framework. The core @bull-board/api package is shared. Pick your framework below.
- [Koa](/bull-board/server-adapters/koa.md): Koa. @bull-board/koa gives you middleware to mount on your app.
- [NestJS](/bull-board/server-adapters/nestjs.md): NestJS. bull-board ships a NestJS module plus a plain adapter you can wire manually.