Skip to main content

One Schedules page. Every Python scheduler.

z4j surfaces every Python task scheduler in one dashboard: celery-beat, rq-scheduler, APScheduler, Huey periodic, arq cron, and taskiq. Plus z4j-scheduler, an engine-agnostic dynamic scheduler that drives any of the six engines from one service with live editing and a tamper-evident audit log of edits.

Engine-agnostic dynamic scheduler

z4j-scheduler

One service that drives Celery, RQ, Dramatiq, Huey, arq, and taskiq. Schedules live in z4j's database; edit live from the dashboard or REST without restarting any daemon. To our knowledge it is the only Python scheduler that combines engine-agnostic dispatch, live editing, HA leader election, and a tamper-evident HMAC-chained audit log of edits in one binary.

Engine-agnostic dispatch

One scheduler binary, six engines. Run Celery + RQ + Huey side by side and edit them all from the same dashboard.

Live editing, no restart

Create, pause, rename, or delete a schedule from the dashboard or REST API; the next tick (one second later) picks it up. No pod restart, no static config redeploy.

HA leader election

Run multiple instances; only one ticks. Postgres advisory-lock leader, rolling-restart safe, no missed fires during handover.

Importer + exporter, no lock-in

Import existing schedules from celery-beat, rq-scheduler, APScheduler, Huey, arq, taskiq, or system crontab. Export back at any time, round-trip pinned by tests.

Full feature breakdown Read the docs Honest framing: scheduler is still not battle-tested at large scale; operate with a fast-response posture and check the CHANGELOG for recent load-test fixes.
Per-engine adapters

Or keep your existing scheduler. We ship an adapter for each.

If z4j-scheduler is more than you need, every native scheduler has a z4j adapter that surfaces its schedules in the same dashboard. You keep celery-beat / rq-scheduler / APScheduler running unchanged; z4j just reads from it (and writes back where the upstream tool supports it).

How to choose

Which scheduler for which engine?

Every engine has a default pairing. You can also pair any engine with APScheduler if you prefer a single scheduling runtime.

Engine Default scheduler Capabilities
Celery Celery Beat z4j-celerybeat List schedules, Create schedule, Update schedule, Delete schedule, Enable / disable, Trigger-now
RQ rq-scheduler z4j-rqscheduler List schedules, Enable / disable, Delete, Trigger-now
Dramatiq APScheduler z4j-apscheduler List, Read, Enable / disable, Delete, Trigger-now
Huey Huey @periodic_task z4j-hueyperiodic List, Read
arq arq cron_jobs z4j-arqcron List, Read
taskiq taskiq scheduler z4j-taskiqscheduler List, Read, Delete (when source supports it)
Quick install

Add a scheduler to your app

Install the scheduler package alongside your engine adapter. The agent auto-discovers periodic tasks on boot and keeps the dashboard in sync.

bash
# Celery + celery-beat
pip install z4j-celery z4j-celerybeat

# RQ + rq-scheduler
pip install z4j-rq z4j-rqscheduler

# Dramatiq + APScheduler (engine-agnostic scheduler)
pip install z4j-dramatiq z4j-apscheduler

# Huey with @periodic_task decorators
pip install z4j-huey z4j-hueyperiodic

# arq with WorkerSettings.cron_jobs
pip install z4j-arq z4j-arqcron

# taskiq schedule sources
pip install z4j-taskiq z4j-taskiqscheduler

Need a scheduler for a custom stack?

APScheduler works with any engine. Or implement the SchedulerAdapter Protocol: six methods, ~200 LOC.