@pg-boss/dashboard
v1.1.0
Published
Web dashboard for monitoring and managing pg-boss job queues
Maintainers
Readme
pg-boss Dashboard
A web-based dashboard for monitoring and managing pg-boss job queues.
Features
- Overview Dashboard: Aggregate statistics, problem queues, and recent warnings at a glance
- Queue Management: Browse all queues with real-time stats (queued, active, deferred, total)
- Job Browser: View and manage individual jobs with smart filtering (defaults to pending jobs)
- Job Detail Inspector: View full job payloads, output data, and metadata
- Job Actions: Create, cancel, retry, resume, or delete jobs directly from the UI
- Warning History: Track slow queries, queue backlogs, and clock skew issues
- Multi-Database Support: Monitor multiple pg-boss instances from a single dashboard
- Pagination: Efficiently browse large datasets with cached statistics
- Mobile Responsive: Full functionality on mobile devices with collapsible sidebar
- Shareable URLs: Database selection and filters are preserved in URLs for easy sharing
Requirements
- Node.js 22.12+
- PostgreSQL database with pg-boss schema
- pg-boss 12.11+
Installation
npm install @pg-boss/dashboardQuick Start
For a quick local test:
DATABASE_URL="postgres://user:password@localhost:5432/mydb" npx pg-boss-dashboardOpen http://localhost:3000 in your browser.
Configuration
The dashboard is configured via environment variables:
| Variable | Description | Default |
|----------|-------------|---------|
| DATABASE_URL | PostgreSQL connection string(s) | postgres://localhost/pgboss |
| PGBOSS_SCHEMA | pg-boss schema name(s) | pgboss |
| PORT | Server port | 3000 |
Multi-Database Configuration
To monitor multiple pg-boss instances, separate connection strings with a pipe (|):
DATABASE_URL="postgres://host1/db1|postgres://host2/db2" npx pg-boss-dashboardYou can optionally name each database for better identification in the UI:
DATABASE_URL="Production=postgres://prod/db|Staging=postgres://stage/db" npx pg-boss-dashboardIf your databases use different schemas, specify them with matching pipe separation:
DATABASE_URL="postgres://host1/db1|postgres://host2/db2" \
PGBOSS_SCHEMA="pgboss|jobs" \
npx pg-boss-dashboardWhen multiple databases are configured, a database selector appears in the sidebar. The selected database is persisted in the URL via the db query parameter, making it easy to share links to specific database views.
Production Deployment
Option 1: Direct Node.js
npm install @pg-boss/dashboard
DATABASE_URL="postgres://user:pass@localhost:5432/db" \
node node_modules/@pg-boss/dashboard/build/server/index.jsOption 2: Docker
FROM node:24
WORKDIR /app
RUN npm install -g @pg-boss/dashboard
ENV PORT=3000
EXPOSE 3000
CMD ["pg-boss-dashboard"]docker build -t pgboss-dashboard .
docker run -d \
-e DATABASE_URL="postgres://user:pass@host:5432/db" \
-p 3000:3000 \
pgboss-dashboardOption 3: Docker Compose
services:
dashboard:
image: node:24
working_dir: /app
command: sh -c "npm install -g @pg-boss/dashboard && pg-boss-dashboard"
environment:
DATABASE_URL: postgres://user:pass@db:5432/mydb
PGBOSS_SCHEMA: pgboss
PORT: 3000
ports:
- "3000:3000"
depends_on:
- dbReverse Proxy
For production, place a reverse proxy in front of any of the above options. Example Nginx configuration:
server {
listen 80;
server_name pgboss.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Pages
Dashboard (/)
The overview page displays:
- Stats Cards: Total queues, total jobs, active jobs, and failed jobs
- Problem Queues: Queues exceeding their
warningQueueSizethreshold - Recent Warnings: Latest 5 warnings (requires
persistWarnings: truein pg-boss config) - Queue Summary: Table of first 10 queues with quick stats
Queues List (/queues)
Paginated list of all queues showing:
- Queue name (links to detail page)
- Policy type (standard, short, singleton, stately)
- Job counts: Queued, Active, Deferred, Total
- Last monitored timestamp
- Status indicator (Backlogged, Processing, Idle)
Queue Detail (/queues/:name)
Detailed view of a single queue:
- Stats Cards: Queued, Active, Deferred, Total counts
- Queue Info: Policy type badge and partition indicator
- Jobs Table: Paginated list of jobs (50 per page) with:
- Job ID (truncated UUID, click to copy full ID)
- State (created, retry, active, completed, cancelled, failed)
- Priority
- Retry count / limit
- Created timestamp
- Actions (View, Cancel, Retry, Resume, Delete - availability depends on job state)
Job Detail Dialog: Click "View" on any job to open a modal with complete job information:
- Full Job ID (with copy button)
- Priority, retry count/limit
- All timestamps (created, started, completed)
- Singleton key (if applicable)
- Group ID and tier (for grouped jobs)
- Dead letter queue (if configured)
- Job Data: Full JSON payload submitted with the job
- Job Output: Result data returned by the worker (if completed)
Filtering: Use the state dropdown to filter jobs by state. Available filters:
| Filter | Description |
|--------|-------------|
| Pending (default) | Shows only non-final state jobs: created, retry, and active. This is the default view to handle queues with large job history efficiently. |
| All States | Shows all jobs including completed, cancelled, and failed. Use with caution on queues with many historical jobs. |
| Individual states | Filter by specific state: Created, Retry, Active, Completed, Cancelled, or Failed |
Performance Note: The "Pending" filter is the default because queues can accumulate large numbers of completed/failed jobs over time. Showing all jobs by default could cause performance issues and make it harder to find actionable jobs.
Pagination Note: Job counts are displayed when available from cached statistics. For some filters (Created, Retry, Completed, Cancelled, Failed), exact counts require database queries and are not shown to maintain performance.
Job Actions (shown based on job state):
| Action | Available States | Description |
|--------|------------------|-------------|
| View | All states | Opens job detail dialog with full job information |
| Cancel | created, retry, active | Stops the job from being processed |
| Retry | failed | Re-queues the job for another attempt |
| Resume | cancelled | Restores a cancelled job back to created state |
| Delete | All except active | Permanently removes the job |
Warnings (/warnings)
History of pg-boss warnings with:
- Warning type (Slow Query, Queue Backlog, Clock Skew)
- Message
- Additional details (elapsed time, queue name, etc.)
- Timestamp
Filtering: Use the type dropdown to filter by warning type.
Note: Warnings are only recorded when pg-boss is configured with
persistWarnings: true.
Enabling Warning Persistence
To capture warnings in the dashboard, enable warning persistence in your pg-boss configuration:
const PgBoss = require('pg-boss');
const boss = new PgBoss({
connectionString: 'postgres://localhost/mydb',
persistWarnings: true // Enable warning persistence
});This creates a warning table in your pg-boss schema that stores:
slow_query: Queries taking longer than expectedqueue_backlog: Queues exceeding their warning thresholdclock_skew: Database clock drift detection
Tech Stack
- Framework: React Router 7 (framework mode)
- Server: Hono via react-router-hono-server
- Styling: Tailwind CSS v4
- Components: Base UI
- Database: pg (PostgreSQL client)
- Testing: Vitest + Testing Library
Development (Contributing)
To work on the dashboard from source:
# Clone the pg-boss repository
git clone https://github.com/timgit/pg-boss.git
cd pg-boss/packages/dashboard
# Install dependencies
npm install
# Initialize local database with pg-boss schema and test queues
npm run dev:init-db
# Start development server with hot reloading
npm run dev
# (Optional) Start a worker to process jobs
# Run this in a separate terminal to see jobs being processed
npm run dev:worker
# Build for production
npm run build
# Run production build
npm startThe dev:init-db script creates the pg-boss schema and populates it with sample queues and jobs for testing. It connects to postgres://postgres:[email protected]:5432/pgboss by default.
The dev:worker script starts a worker that processes jobs from the same pg-boss instance as the dashboard. This is useful for testing the dashboard while jobs are being processed. The worker will stay running until you stop it with Ctrl+C.
Project Structure
packages/dashboard/
├── app/
│ ├── components/
│ │ ├── layout/ # Sidebar, page layout
│ │ └── ui/ # Reusable UI components
│ ├── lib/
│ │ ├── db.server.ts # Database connection pool
│ │ ├── queries.server.ts # SQL queries
│ │ ├── types.ts # TypeScript types
│ │ └── utils.ts # Shared utilities
│ ├── routes/
│ │ ├── _index.tsx # Dashboard overview
│ │ ├── queues._index.tsx # Queues list
│ │ ├── queues.$name.tsx # Queue detail
│ │ └── warnings.tsx # Warnings history
│ ├── root.tsx # Root layout
│ ├── routes.ts # Route configuration
│ └── server.ts # Hono server setup
├── tests/
│ ├── frontend/ # React component tests
│ ├── server/ # Server-side tests (queries, utils)
│ └── setup.ts # Test setup (jsdom, mocks)
├── package.json
├── vite.config.ts
├── vitest.config.frontend.ts # Frontend test config
└── vitest.config.server.ts # Server test configRunning Tests
# All tests (frontend + server)
npm test
# Frontend tests only (React components)
npm run test:frontend
# Server tests only (queries, utils - requires PostgreSQL)
npm run test:server
# All tests with coverage
npm run cover
# Individual coverage reports
npm run cover:frontend
npm run cover:serverType Checking
npm run typecheckAPI Reference
The dashboard reads directly from pg-boss database tables:
{schema}.queue- Queue metadata and cached job counts{schema}.job- Individual jobs{schema}.warning- Warning history (whenpersistWarningsis enabled)
Queue Table Fields Used
| Field | Description |
|-------|-------------|
| name | Queue name |
| policy | Queue policy (standard, short, singleton, stately) |
| queued_count | Number of jobs waiting to be processed |
| active_count | Number of jobs currently being processed |
| deferred_count | Number of jobs scheduled for later |
| total_count | Total job count |
| warning_queued | Threshold for backlog warnings |
| monitor_on | Last monitoring timestamp |
Job States
| State | Description | Category |
|-------|-------------|----------|
| created | Job is queued and waiting | Pending (non-final) |
| retry | Job failed and is scheduled for retry | Pending (non-final) |
| active | Job is currently being processed | Pending (non-final) |
| completed | Job finished successfully | Final |
| cancelled | Job was cancelled | Final |
| failed | Job failed after exhausting retries | Final |
Pending vs Final States: Jobs in pending states (created, retry, active) are still being processed or waiting to be processed. Jobs in final states (completed, cancelled, failed) have finished processing. The dashboard's default "Pending" filter shows only non-final state jobs.
Troubleshooting
"Failed to load dashboard"
- Verify
DATABASE_URLis correct and the database is accessible - Ensure the pg-boss schema exists (run pg-boss at least once to create it)
- Check PostgreSQL logs for connection errors
No warnings showing
- Ensure
persistWarnings: trueis set in your pg-boss configuration - Warnings are only recorded after enabling this option
Queue stats seem stale
Queue statistics are cached in the queue table by pg-boss's monitoring system. They update based on your monitorStateIntervalSeconds configuration (default: 30 seconds).
License
MIT
