Overview
Zero-dependency built-in web UI for browsing jobs, configuring webhooks, tuning per-task runtime limits, and managing the queue.
Zero-dependency built-in web UI for browsing jobs, configuring webhooks, tuning per-task runtime limits, and managing the queue.
flexiq ships with a built-in web dashboard for monitoring jobs, inspecting dead letters (the DLQ — a holding area for jobs that exhausted their retries), configuring webhooks, tuning per-task runtime limits, and managing your task queue in real time. The dashboard is a single-page application served directly from the Python package — zero extra dependencies required.
Coming from Celery? This is flexiq's built-in equivalent of Flower — no separate monitoring service to install or run.

flexiq dashboard --app myapp:queueThe --app argument uses the same module:attribute format as the worker.
from flexiq.dashboard import serve_dashboard
from myapp import queue
serve_dashboard(queue, host="0.0.0.0", port=8080)By default the dashboard starts on http://localhost:8080.
| Flag | Default | Description |
|---|---|---|
--app | required | Module path to your Queue instance, e.g. myapp:queue |
--host | 127.0.0.1 | Bind address |
--port | 8080 | Bind port |
--auth | off | Enable session authentication (login/setup, CSRF, roles) |
# Bind to all interfaces on port 9000
flexiq dashboard --app myapp:queue --host 0.0.0.0 --port 9000The dashboard reads directly from the same database as the worker. You can run them side by side without any coordination:
# Terminal 1
flexiq worker --app myapp:queue
# Terminal 2
flexiq dashboard --app myapp:queueAuthentication is opt-in — without it, anyone who can reach the port
has full control. For production, enable it with
serve_dashboard(auth_enabled=True) or flexiq dashboard --auth, or
keep the dashboard on a private network. See
Authentication for the full
flow, including the env-var bootstrap path useful for managed
deployments.
The dashboard is grouped by intent — Monitoring (what's happening), Infrastructure (where it runs), Reliability (when it goes wrong), and Configuration (how to change it):
| Group | Page | What it does |
|---|---|---|
| Monitoring | Overview | Stats cards, throughput sparkline, queue-by-queue table |
| Monitoring | Jobs | Filterable job listing (status, queue, task, metadata, error, date range) |
| Monitoring | Job Detail | Full job info, error history, task logs, replay history, dependency DAG |
| Monitoring | Metrics | Per-task performance (avg, P50, P95, P99) with timeseries chart |
| Monitoring | Logs | Structured task execution logs with task/level filters |
| Infrastructure | Queues | Per-queue stats, pause and resume controls |
| Infrastructure | Workers | Worker cards with heartbeat status and queue assignments |
| Infrastructure | Resources | Worker DI runtime status — health, scope, init duration |
| Reliability | Dead Letters | Failed jobs that exhausted retries — retry or purge |
| Reliability | Circuit Breakers | Automatic failure protection state, thresholds, cooldowns |
| Reliability | System | Proxy reconstruction and interception strategy metrics |
| Configuration | Tasks | Decorator defaults + runtime overrides per task (guide) |
| Configuration | Webhooks | HTTP event subscriptions with delivery history + replay (guide) |
| Configuration | Settings | Dashboard branding, external links, integrations |
The full REST API surface is documented at Dashboard REST API.
The dashboard is a React 19 + Vite 8 + TypeScript SPA routed via TanStack
Router, styled with Tailwind v4 and shadcn/ui, and shipped as
hash-busted multi-file assets under sdks/python/flexiq/static/dashboard/.
localStorage and follows the system scheme by
default.⌘K / Ctrl+K opens a cmdk palette for route
navigation.The built SPA ships inside the Python wheel under
sdks/python/flexiq/static/dashboard/ and is served by the Python
dashboard process. No Node.js, no pnpm, no CDN at runtime — just
pip install flexiq. Node.js and pnpm are only needed by
contributors rebuilding the dashboard source.
By default there is no sign-in — the dashboard loads straight into the
overview. With authentication enabled (--auth /
serve_dashboard(auth_enabled=True)), the first visit shows the setup
form; after you create the first admin, every subsequent visit shows the
sign-in form.

See Authentication for the env
var-based bootstrap (FLEXIQ_DASHBOARD_ADMIN_USER /
FLEXIQ_DASHBOARD_ADMIN_PASSWORD) and the CSRF model.
The Jobs page shows a filterable, paginated table. Filters live in the sidebar panel: status, queue, task name, metadata search, error text, date range. Click any row to open the detail view with the full job state, error history, task logs, replay history, and a dependency DAG for jobs with relationships.

The Webhooks page lists every HTTP endpoint subscribed to job events. Add new endpoints with the + New webhook button. Each row has a dropdown menu — send a test event, enable/disable, rotate the signing secret, or view the delivery history. Full guide: Webhooks.

The Tasks page lists every registered task with its decorator defaults and any active runtime override. Click Edit to open a side sheet with two tabs: Overrides (rate limit, concurrency, retries, timeout, priority, paused) and Middleware (toggle each middleware on or off for the task). Full guide: Task & Queue Overrides.

The Queues page lists every queue mentioned by a registered task, showing pending/running counts and the current pause state. Pause and resume buttons take effect immediately on the running worker.

The Workers page lists every registered worker with heartbeat status, the queues it consumes from, tags, and registration time. Stale workers (no heartbeat for 30s) automatically transition to "offline".

Contributors who want to modify the dashboard source:
# Install dependencies (pnpm is pinned via the `packageManager` field)
cd dashboard && pnpm install
# Start Vite dev server (proxies /api/* to localhost:8080)
pnpm run dev
# In another terminal, start the backend
flexiq dashboard --app myapp:queue
# Build and copy to Python package
pnpm run buildRun corepack enable once (Node 16+) and pnpm will be provisioned
automatically from the version pinned in dashboard/package.json.
The build produces a static index.html plus hashed JS/CSS chunks
under sdks/python/flexiq/static/dashboard/. The built assets aren't
committed — release tooling runs pnpm -C dashboard build before
packaging so the wheel ships them.
Every dashboard screenshot in this documentation is produced by a
reproducible script that seeds a fresh queue, walks the UI in headless
Chrome via Playwright, and writes PNGs into docs/public/screenshots/dashboard/:
uv sync --extra docs # one-time
uv run python -m playwright install chromium # one-time
uv run python scripts/capture_docs_screenshots.pyPass --skip-capture to start the seeded demo dashboard in a browser
without running Playwright — useful when iterating on UI changes
locally.