Upgrades
Semver promise
Section titled “Semver promise”- Major – breaking wire-protocol changes. Plan a coordinated upgrade.
- Minor – additive features, fully backward-compatible within the major.
- Patch – bug fixes, no behavior changes.
See versioning for the full policy.
Upgrade order
Section titled “Upgrade order”- Upgrade z4j (the brain) first. Newer brains accept older agents within the same major.
- Upgrade agents on a schedule. Rolling restarts are fine; agents auto-reconnect.
- Watch the dashboard for the per-agent “outdated” badge – the brain renders it when an agent’s last advertised
protocol_versionis older than the brain’s current protocol.
Database migrations
Section titled “Database migrations”Alembic migrations run automatically on brain start when Z4J_AUTO_MIGRATE=true (the default). For multi-replica deploys, set Z4J_AUTO_MIGRATE=false on the runtime replicas and run migrations from a one-shot job ahead of the rollout:
docker run --rm \ -e Z4J_DATABASE_URL=... \ -e Z4J_AUTO_MIGRATE=false \ z4jdev/z4j:latest z4j migrate upgrade headThen deploy the new image to the brain replicas.
Rolling back
Section titled “Rolling back”Every Alembic revision ships a working downgrade() plus a CI roundtrip test (upgrade head -> downgrade base -> upgrade head against real Postgres), so a schema-level rollback is the supported path:
docker run --rm \ -e Z4J_DATABASE_URL=... \ z4jdev/z4j:latest z4j migrate downgrade <previous-revision>Then deploy the previous brain image. See database migrations for the bidirectional-schema contract: schema round-trips cleanly, but downgrade drops tables, so row data is lost in the process. For data-preserving rollback, restore from a Postgres backup before the upgrade.
Version skew tolerance
Section titled “Version skew tolerance”| Brain | Agent | Behavior |
|---|---|---|
| same major, same minor | same major, same minor | Full feature parity. |
| same major, newer | same major, one minor older | Works. New brain-side features may be unavailable on older agents; the dashboard shows the “outdated” badge. |
| same major, newer | same major, more than one minor older | Works but flagged loudly. Plan the agent rollout. |
| any | major mismatch | Rejected at the handshake with WebSocket close code 4426 (Upgrade Required). |
Rolling-upgrade caveats
Section titled “Rolling-upgrade caveats”The primary WebSocket transport is protocol-compatible across a same-major minor gap, so the steady-state event, heartbeat, and command data plane keeps flowing in both directions while a fleet is mid-upgrade. Two paths need operator awareness during the mixed-version window:
- Long-poll fallback (corporate-proxy path only). The long-poll HMAC
binds the agent and project identity the brain advertises in its
response headers, so long-poll delivery only works when the brain and
agent are on the same release. If you rely on the HTTPS long-poll
fallback rather than WebSocket, upgrade the brain and agents together,
or set
Z4J_AGENT_IDandZ4J_PROJECT_IDto the real UUIDs shown on the brain’s agents page (the agent logs this instruction). WebSocket deployments are unaffected. - Queue purges. The
purge_queueconfirm-token is a keyed HMAC. A purge issued across a version boundary is refused (it fails safe – it never purges the wrong queue). Do not issue queue purges until the whole fleet is on the new release. If you must purge against a not-yet-upgraded brain, setZ4J_ACCEPT_LEGACY_PURGE_TOKEN=1on the agents for the grace window only.
Reading release notes
Section titled “Reading release notes”Every release ships a CHANGELOG entry at /reference/changelog. Breaking changes are flagged explicitly.
Upgrading Postgres
Section titled “Upgrading Postgres”z4j supports Postgres 17 and 18. Use pg_upgrade or logical replication; z4j is agnostic to which migration path you choose.