Turn FastAPI BackgroundTasks into a production-ready task system

Retries, control, resiliency and visibility without workers or brokers.

BackgroundTasks is fine, until it isn't

FastAPI's BackgroundTasks is great for simple work. But in production you hit the same gaps fast, tasks fail silently, nothing is tracked, and restarts wipe all state.

Without fastapi-taskflow

  • No retries on failure
  • No task IDs or status
  • No visibility into what ran
  • No history after restart
  • No metrics or duration
  • No logs or error traces

With fastapi-taskflow

  • Automatic retries with backoff
  • UUID per task, full lifecycle
  • Live dashboard over SSE
  • SQLite or Redis persistence
  • Success rate and duration metrics
  • Per-task logs and full stack traces

Looks like FastAPI. Works like a task system.

from fastapi import BackgroundTasks, FastAPI
from fastapi_taskflow import TaskAdmin, TaskManager, task_log

task_manager = TaskManager(snapshot_db="tasks.db")
app = FastAPI()
TaskAdmin(app, task_manager, auto_install=True)


@task_manager.task(retries=3, delay=1.0, backoff=2.0)
def send_email(address: str) -> None:
    task_log(f"Sending to {address}")
    ...  # your logic here


@app.post("/signup")
def signup(email: str, background_tasks: BackgroundTasks):
    task_id = background_tasks.add_task(send_email, address=email)
    return {"task_id": task_id}

The route signature does not change. auto_install=True handles the rest. Read the Quick Start →

Live visibility out of the box

Everything you need, nothing you don't

Automatic Retries

Configure retries, delay, and exponential backoff per function using a single decorator.

Task Lifecycle Tracking

Every task gets a UUID and moves through PENDING, RUNNING, SUCCESS, and FAILED states.

Live Dashboard

A real-time admin panel at /tasks/dashboard with filtering, search, and task detail.

Pluggable Persistence

SQLite out of the box. Redis available as an optional extra. Custom backends via a simple ABC.

Pending Requeue

Tasks that did not finish before shutdown are saved and re-dispatched on next startup. Tasks interrupted mid-execution are marked INTERRUPTED or requeued based on a per-task flag.

Zero-Migration Injection

Keep your existing background_tasks: BackgroundTasks signatures. One line at startup is all it takes.

Task Logging

Call task_log() inside any task to capture timestamped log entries. Logs and full stack traces appear in the dashboard detail panel.

File Logging

Write task logs to a plain text file alongside the dashboard. Works with tail -f, grep, and any log shipper (Loki, Datadog, Fluentd, CloudWatch). Supports automatic rotation and external rotation via logrotate.

Idempotency Keys

Pass an idempotency_key to add_task() to prevent the same logical operation from running twice, even across multiple instances.

Multi-Instance Support

Run multiple instances behind a load balancer with SQLite (same host) or Redis (any host). Requeue claiming is atomic. Task history is shared across all instances.

Not a Celery replacement

fastapi-taskflow does not compete with Celery, ARQ, Taskiq, or Dramatiq. Those tools are built for distributed workers, message brokers, and high-throughput task routing across separate machines.

This library is for teams using FastAPI's native BackgroundTasks who want retries, visibility, and resilience without adding worker infrastructure. It supports multi-instance deployments with a shared SQLite file (same host) or Redis (any host), including atomic requeue claiming, idempotency keys, and shared task history across instances.

If your tasks need to run on dedicated worker processes completely separate from your web application, use a proper task queue.

Get started →