Skip to content

Compatibility matrix

This is the authoritative compatibility table for the z4j ecosystem. Each row shows the upstream framework / engine / scheduler version range the matching z4j adapter is tested and shipped against.

  • Min is the lowest upstream version z4j’s adapter still imports cleanly and exposes the full action surface against. Older releases may work for read-only paths; we do not test them.
  • Cap is an explicit upper bound, set only where the upstream library has shipped (or is about to ship) a breaking-major that rewrites the API surface z4j depends on. “none” means newer is fine.
  • Python is the runtime floor for the adapter package. The z4j brain and the z4j-bare / z4j-scheduler companion processes require Python 3.11+; the user-side adapter packages require Python 3.10+.
  • Pip pin is a copy-pasteable line you can drop into a requirements.txt or pip install invocation alongside the z4j package.
Component Python Notes
z4j (brain) 3.11+ PostgreSQL 17+ for production; bundled SQLite for single-node.
z4j-bare (agent harness) 3.11+ Pure-Python runtime; no framework or engine pinned.
z4j-scheduler (companion process) 3.11+ Fans out to whichever engines you install on the same host.
z4j-core (shared protocols) 3.10+ Transitive dependency; 3.11+ inside the brain.
z4j package Upstream Min Cap Python Pip pin
z4j-django Django 5.0 none 3.10+ pip install "z4j-django" "django>=5.0"
z4j-flask Flask 3.1.3 none 3.10+ pip install "z4j-flask" "flask>=3.1.3"
z4j-fastapi FastAPI 0.95 none 3.10+ pip install "z4j-fastapi" "fastapi>=0.95"
z4j package Upstream Min Cap Python Pip pin
z4j-celery Celery 5.2 none 3.10+ pip install "z4j-celery" "celery>=5.2"
z4j-rq RQ 1.10 <3 3.10+ pip install "z4j-rq" "rq>=1.10,<3"
z4j-dramatiq Dramatiq 1.14 <3 3.10+ pip install "z4j-dramatiq" "dramatiq>=1.14,<3"
z4j-huey Huey 2.4 <3 3.10+ pip install "z4j-huey" "huey>=2.4,<3"
z4j-arq arq 0.26 <1 3.10+ pip install "z4j-arq" "arq>=0.26,<1"
z4j-taskiq TaskIQ 0.11 <1 3.10+ pip install "z4j-taskiq" "taskiq>=0.11,<1"
z4j package Upstream Min Cap Python Pip pin
z4j-celerybeat Celery + django-celery-beat 5.3 + 2.5 none 3.10+ pip install "z4j-celerybeat" "celery>=5.3" "django-celery-beat>=2.5"
z4j-rqscheduler rq-scheduler 0.11 none 3.10+ pip install "z4j-rqscheduler" "rq-scheduler>=0.11"
z4j-apscheduler APScheduler 3.8 <4 3.10+ pip install "z4j-apscheduler" "apscheduler>=3.8,<4"
z4j-hueyperiodic Huey 2.4 <4 3.10+ pip install "z4j-hueyperiodic" "huey>=2.4,<4"
z4j-arqcron arq 0.26 <1 3.10+ pip install "z4j-arqcron" "arq>=0.26,<1"
z4j-taskiqscheduler TaskIQ 0.11 <1 3.10+ pip install "z4j-taskiqscheduler" "taskiq>=0.11,<1"

The upper caps exist only where upstream has shipped or imminently ships a breaking-major:

  • RQ <3 – RQ 3.0 is a Worker / Queue API rewrite. The cap lifts once z4j-rq ships a 3.x-compatible code path.
  • Dramatiq <3 – conservative breaking-major guard; the active tested range is the 2.x line.
  • Huey <3 for the engine adapter, <4 for the periodic-task adapter – Huey 3 reshapes the signal surface the engine subscribes to; the periodic adapter is registry-based and tolerates 2.x and 3.x but caps at <4 as the next conservative ceiling.
  • APScheduler <4 – APScheduler 4.x is a full rewrite (new scheduler / data-store API). Stay on 3.x until a 4.x branch ships.
  • arq <1, TaskIQ <1 – both libraries are still pre-1.0; the caps prevent silent breakage when their 1.0 lines land.

No cap is applied to Django, Flask, FastAPI, Celery, rq-scheduler, or django-celery-beat. Their deprecation policies have historically been gradual enough that adapter breakage surfaces as a feature gap rather than an import error.

Framework adapters expose [engine] extras that pull the engine adapter AND its companion scheduler in one shot:

Terminal window
pip install "z4j-django[celery]" # z4j-celery + z4j-celerybeat
pip install "z4j-django[rq]" # z4j-rq + z4j-rqscheduler
pip install "z4j-django[dramatiq]" # z4j-dramatiq + z4j-apscheduler
pip install "z4j-django[huey]" # z4j-huey + z4j-hueyperiodic
pip install "z4j-django[arq]" # z4j-arq + z4j-arqcron
pip install "z4j-django[taskiq]" # z4j-taskiq + z4j-taskiqscheduler
pip install "z4j-django[all]" # every engine (CI / kitchen sink)

The same extras exist on z4j-flask, z4j-fastapi, and z4j-bare. Pip resolves the matching adapter version automatically; you only need to pin the upstream library when your application already pins it elsewhere.

A fleet does not upgrade all at once, so a supported amount of skew is part of the contract rather than something you get away with.

The brain leads and agents follow. The brain may run up to one minor version ahead of an agent within the same major line. A brain and an agent on the same minor is the steady state; a brain one minor ahead is the supported rolling-upgrade state.

Pairing Supported
Same minor Yes
Brain one minor ahead of agent Yes, this is the rolling-upgrade window
Brain two or more minors ahead No, upgrade the agent
Agent ahead of brain No, upgrade the brain first
Different majors No

The practical consequence is the upgrade order: upgrade the brain first, watch it, then roll the agents on your own schedule. You do not need a window in which everything moves together.

The agent reports its version on every connection, so an unsupported pairing is something the brain can see rather than infer from behaviour. Adapter package floors are coordinated across a release for the same reason, so a current adapter cannot be installed beside a dispatcher too old to honour its contract.

If you skip a minor on the brain, stop at the intermediate release long enough to roll the agents before going further. The schema will span the jump, but the agents will not.

All agents and brains within the same major line talk over the same wire protocol. Cross-version mismatches inside a major surface as a dashboard banner; cross-major mismatches close the WebSocket with 4426 (Upgrade Required). See versioning and the changelog for the per-release numbers.