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.
Reading the matrix
Section titled “Reading the matrix”- 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 the adapter declares no upper cap; it is not a guarantee about untested future releases.
- Python is the runtime floor for the package. All shipped z4j packages require Python 3.11+.
- Pip pin is a copy-pasteable line you can drop into a
requirements.txtorpip installinvocation alongside the z4j package.
Brain and companion processes
Section titled “Brain and companion processes”| 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+ | Installs no engine: fires go to the brain over gRPC, which dispatches them to the project's agents. Its *-import extras pull only the source scheduler libraries for the migration importers. |
z4j-core (shared protocols) |
3.11+ | Transitive dependency shared by every adapter. |
Framework adapters
Section titled “Framework adapters”| z4j package | Upstream | Min | Cap | Python | Pip pin |
|---|---|---|---|---|---|
z4j-django |
Django | 4.2 | none | 3.11+ | pip install "z4j-django" |
z4j-flask |
Flask | 2.3.3 | none | 3.11+ | pip install "z4j-flask" "flask>=2.3.3" |
z4j-fastapi |
FastAPI | 0.109.1 | none | 3.11+ | pip install "z4j-fastapi" "fastapi>=0.109.1" |
The adapter ranges express API compatibility, not a requirement to upgrade every host application to our development versions. Django 4.2 and 5.2 installations can keep their framework line; choose a Python version supported by that Django release. The current framework majors are covered by CI. An environment that installs django-celery-beat must also respect that package's own Django constraint.
Use supported upstream lines and current security patches for production. Legacy API compatibility does not certify the host application's security. Z4J's deployment locks and security audits remain separate from these public adapter ranges.
The shared core accepts Pydantic 2.9.2+ on Python 3.11 through 3.13 and Pydantic 2.12+ on Python 3.14+, plus typing-extensions 4.12.2+. CI tests older, LTS and current framework profiles, including core validation and real adapter discovery. The Brain and scheduler are separate services with their own audited dependency requirements.
Engine adapters
Section titled “Engine adapters”| z4j package | Upstream | Min | Cap | Python | Pip pin |
|---|---|---|---|---|---|
z4j-celery |
Celery | 5.2.2 | none | 3.11+ | pip install "z4j-celery" "celery>=5.2.2" |
z4j-rq |
RQ | 1.10.1 | none | 3.11+ | pip install "z4j-rq" "rq>=1.10.1" |
z4j-dramatiq |
Dramatiq | 1.14 | none | 3.11+ | pip install "z4j-dramatiq" "dramatiq>=1.14" |
z4j-huey |
Huey | 2.4 | none | 3.11+ | pip install "z4j-huey" "huey>=2.4" |
z4j-arq |
arq | 0.26 | none | 3.11+ | pip install "z4j-arq" "arq>=0.26" |
z4j-taskiq |
TaskIQ | 0.11 | none | 3.11+ | pip install "z4j-taskiq" "taskiq>=0.11" |
Scheduler adapters
Section titled “Scheduler adapters”| z4j package | Upstream | Min | Cap | Python | Pip pin |
|---|---|---|---|---|---|
z4j-celerybeat |
Celery + django-celery-beat |
5.3 + 2.5 | none | 3.11+ | pip install "z4j-celerybeat" "celery>=5.3" "django-celery-beat>=2.5" |
z4j-rqscheduler |
rq-scheduler |
0.11 | none | 3.11+ | pip install "z4j-rqscheduler" "rq-scheduler>=0.11" |
z4j-apscheduler |
APScheduler | 3.10.2 | none | 3.11+ | pip install "z4j-apscheduler" "apscheduler>=3.10.2" |
z4j-hueyperiodic |
Huey | 2.4 | none | 3.11+ | pip install "z4j-hueyperiodic" "huey>=2.4" |
z4j-arqcron |
arq | 0.26 | none | 3.11+ | pip install "z4j-arqcron" "arq>=0.26" |
z4j-taskiqscheduler |
TaskIQ | 0.11 | none | 3.11+ | pip install "z4j-taskiqscheduler" "taskiq>=0.11" |
z4j-rqscheduler depends on z4j-rq, so the rq>=1.10.1 floor applies to it as well.
Upper bounds
Section titled “Upper bounds”No z4j package caps a framework, an engine or a scheduler. A requirement that holds a dependency below its newest release also holds back that dependency's security fixes, so every range on this page is a floor. What keeps the pairing honest is testing, not the resolver: the release gate runs every adapter's suite on the newest upstream release it resolves, runs the adapters that have a measured floor environment (Celery, RQ, Huey, APScheduler and FastAPI) on that floor as well, and fails when any z4j requirement would keep a dependency below its latest.
A new upstream major therefore installs. Until the gate has run on it, hold the engine on the previous major in your own requirements if you need a tested pairing.
- APScheduler. APScheduler 4 is a different API.
z4j-apschedulerdrives the APScheduler 3 scheduler interface and refuses, at construction and by name, a scheduler object that lacks it. Install"apscheduler<4"alongside the adapter. - Huey. Both adapters run on Huey 2 and Huey 3; the gate runs their suites, with a real consumer, on Huey 2.4.0 and on Huey 3.4.0. Before Huey 2.5.3 there is no enqueue signal, so a task first appears when it starts and its arguments are not captured. Changing the major is one-way on the wire: a Huey 3 consumer reads work enqueued by Huey 2, but a Huey 2 consumer cannot read work enqueued by Huey 3 and drops it. Drain the queue and the schedule before downgrading Huey.
Django 6 requires Python 3.12+, which its own package metadata enforces. z4j-celerybeat declares its django-celery-beat>=2.5 floor in its django extra (pip install "z4j-celerybeat[django]"); the base package depends on Celery alone.
Engine pairing extras
Section titled “Engine pairing extras”Framework adapters expose [engine] extras that pull the engine adapter AND its companion scheduler in one shot:
pip install "z4j-django[celery]" # z4j-celery + z4j-celerybeatpip install "z4j-django[rq]" # z4j-rq + z4j-rqschedulerpip install "z4j-django[dramatiq]" # z4j-dramatiq + z4j-apschedulerpip install "z4j-django[huey]" # z4j-huey + z4j-hueyperiodicpip install "z4j-django[arq]" # z4j-arq + z4j-arqcronpip install "z4j-django[taskiq]" # z4j-taskiq + z4j-taskiqschedulerpip install "z4j-django[all]" # every engine (CI / kitchen sink)The same extras exist on z4j-flask and z4j-fastapi. z4j-bare has no engine extras, so install its adapters directly, for example pip install z4j-bare z4j-celery z4j-celerybeat. Pip resolves the matching adapter version automatically; you only need to pin the upstream library when your application already pins it elsewhere.
Brain and agent version skew
Section titled “Brain and agent version skew”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 brain logs a warning for an unsupported pairing rather than refusing the connection.
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.
Wire protocol
Section titled “Wire protocol”All agents and brains within the same major line talk over the same wire protocol. The brain closes an agent connection with 4426 (Upgrade Required) only when the agent advertises a wire-protocol version the brain does not accept. Package-version skew never disconnects: an agent outside the supported skew window is logged at warning level on the brain and shown with a per-agent version badge on the Agents page. Close code 4427 is reserved for version skew and is not sent. See versioning and the changelog for the per-release numbers.