Engine-agnostic dynamic scheduler for the z4j stack (Apache 2.0)
Project description
z4j-scheduler
The engine-agnostic dynamic scheduler for z4j.
One service drives Celery, RQ, Dramatiq, Huey, arq, and TaskIQ from a single dashboard. Schedules live in z4j's database, you edit them live without restarting anything, every change is recorded in an HMAC-chained audit log, and importers + exporters keep the door open in either direction. This is the canonical scheduler when you want one place to manage cron / interval / one-shot / solar schedules across mixed engines.
What makes z4j-scheduler different
z4j-scheduler is a deliberate alternative to in-language schedulers like celery-beat, rq-scheduler, and APScheduler. The differences that matter day to day:
- Engine-agnostic. One scheduler service for every supported Python task engine. A project running Celery for legacy services and arq for a FastAPI rewrite uses the same scheduler for both, with one dashboard and one audit trail.
- Live editing. Schedules live in z4j's Postgres database. Create, edit, pause, resume, rename, and delete from the dashboard or REST API without a daemon restart. celery-beat needs a beat-process restart for static-config edits, rq-scheduler stores schedules in Redis but has no editing UI, APScheduler edits are in-process.
- HMAC-chained audit log. Every schedule mutation (who, what, when, from which IP) is recorded in a tamper-evident audit chain alongside the brain's other audit rows. celery-beat keeps no record. django-celery-beat keeps a partial record only if you wired up django-auditlog.
- HA-ready. Multiple scheduler instances can run against the same Postgres database. Postgres advisory locks elect one leader to tick; followers stay warm. Rolling restarts and leader failovers are seconds, not minutes, with no missed-fire window beyond the per-schedule catch-up policy.
- Reversible by design. Importers cover celery-beat (static and
django-celery-beat), rq-scheduler, APScheduler jobstores, Huey
@periodic_task, arq cron, taskiq schedule sources, and system crontab. Exporters write any schedule back to those same formats. Round-trip integrity is pinned by tests so you can leave whenever you want; the schedule definitions are yours, not ours.
What it ships
| Capability | Notes |
|---|---|
| Schedule kinds | cron, interval, one-shot, solar (sunrise / sunset / dawn / dusk / noon / midnight at a given lat / lon) |
| Live editing | dashboard, REST API, declarative config; no restart required |
| Engine fan-out | Celery, RQ, Dramatiq, Huey, arq, TaskIQ |
| Importers | celery / django-celery-beat / rq-scheduler / apscheduler / huey-periodic / arq-cron / taskiq-scheduler / cron |
| Exporters | every native format above; round-trip integrity tested |
| HA leader election | Postgres advisory lock, followers stay warm |
| Audit log | every mutation HMAC-chained, tamper-evident |
| Catch-up policy | per-schedule: skip, fire one missed, fire all missed |
| Timezones | IANA zones validated at the boundary; DST fall-back fold fixed (no double-fires); spring-forward gap handled |
| Trigger surface | brain dispatches trigger_now over a private gRPC channel so the scheduler's last-fire cache stays consistent |
Install
Standalone (recommended for production):
pip install z4j-scheduler
z4j-scheduler serve
Embedded inside z4j (recommended for homelab and small teams):
pip install 'z4j[scheduler-embedded]'
# enable in brain settings: Z4J_EMBEDDED_SCHEDULER=true
Migrate existing schedules in:
pip install 'z4j-scheduler[celery-import]'
z4j-scheduler import \
--from celery \
--celery-app myapp.celery:app \
--project myproject \
--brain-url https://brain.example.com \
--api-token "$Z4J_SCHEDULER_BRAIN_API_TOKEN"
The other importer subcommands follow the same shape (--from rq,
--from apscheduler, --from django-celery-beat, etc.). All run in
--dry-run mode by default; you review the diff before any write.
When to choose z4j-scheduler
You probably want it if:
- You run more than one Python task engine and want one schedule surface across all of them.
- An auditor or a security review asks who paused the nightly billing job last Tuesday and you don't have a clean answer.
- You're tired of restarting celery-beat to change a cron expression.
- You want HA scheduling without standing up a second control plane.
- You're considering a one-time migration from celery-beat / rq-scheduler / APScheduler and want a reversible path.
You probably don't need it if:
- You run a single engine (typically Celery), have no compliance pressure, and the in-language scheduler already meets your needs. Stay where you are; we ship z4j-celerybeat / z4j-rqscheduler / z4j-apscheduler as observation-only adapters that surface those schedules in the z4j dashboard without taking ownership.
Documentation
Full docs at z4j.dev/scheduler/. The migration guide at z4j.dev/scheduler/migrating-from-celery-beat/ walks the importer + dashboard verification path step by step.
License
Apache-2.0, see LICENSE. Importing z4j-scheduler does not affect your application's licensing. z4j (server + dashboard + API) is AGPL v3, isolated in its own process; the scheduler is separate.
Links
- Homepage: https://z4j.com
- Documentation: https://z4j.dev
- PyPI: https://pypi.org/project/z4j-scheduler/
- Issues: https://github.com/z4jdev/z4j-scheduler/issues
- Changelog: CHANGELOG.md
- Security: security@z4j.com (see SECURITY.md)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file z4j_scheduler-1.4.0.tar.gz.
File metadata
- Download URL: z4j_scheduler-1.4.0.tar.gz
- Upload date:
- Size: 147.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a37e8e26c76256bd0d4274e727f9b589393cdd3e4881e2c588de21cf1d1fb5e
|
|
| MD5 |
c3c89a88d11a2598ed7f2d3f48c0a4a5
|
|
| BLAKE2b-256 |
aeb1e42cd01671302b45fc7b8dbce706bd674cf14856a0d4feee159504aa715e
|
File details
Details for the file z4j_scheduler-1.4.0-py3-none-any.whl.
File metadata
- Download URL: z4j_scheduler-1.4.0-py3-none-any.whl
- Upload date:
- Size: 187.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db8906ffbd541505d2b936becfe971d12fecd6718e4ba4e0ee6d8691a7e9850c
|
|
| MD5 |
1f495cefca5cae14e9a9903d1da76476
|
|
| BLAKE2b-256 |
e975343f35198fd0e1c1043ec9c070e1fd683d33198580d716a8593094df5f01
|