Skip to content

Upgrades

  • 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.

  1. Upgrade z4j (the brain) first. Newer brains accept older agents within the same major.
  2. Upgrade agents on a schedule. Rolling restarts are fine; agents auto-reconnect.
  3. Watch the dashboard for the per-agent “outdated” badge – the brain renders it when an agent’s last advertised protocol_version is older than the brain’s current protocol.

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:

Terminal window
docker run --rm \
-e Z4J_DATABASE_URL=... \
-e Z4J_AUTO_MIGRATE=false \
z4jdev/z4j:latest z4j migrate upgrade head

Then deploy the new image to the brain replicas.

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:

Terminal window
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.

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).

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_ID and Z4J_PROJECT_ID to the real UUIDs shown on the brain’s agents page (the agent logs this instruction). WebSocket deployments are unaffected.
  • Queue purges. The purge_queue confirm-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, set Z4J_ACCEPT_LEGACY_PURGE_TOKEN=1 on the agents for the grace window only.

Every release ships a CHANGELOG entry at /reference/changelog. Breaking changes are flagged explicitly.

z4j supports Postgres 17 and 18. Use pg_upgrade or logical replication; z4j is agnostic to which migration path you choose.