A warehouse order service publishes OrderReleased to Kafka; the broker accepts the batch; three consumer groups process the event — but the PostgreSQL row never committed because the producer fired before the transaction closed. Apache Kafka 4.0 removed ZooKeeper from the critical path in March 2025, yet ops runbooks written for ZK ensembles still govern how teams think about metadata recovery, controller loss, and cutover windows. KRaft-only is not a footnote; it is a forcing function to revalidate every assumption about who holds truth when the bus and the database disagree.
Metadata plane migration in engineering terms
ZooKeeper historically stored broker registration, topic configuration, controller election, and ACL metadata. KRaft embeds that consensus into a Raft quorum of Kafka controllers. Fewer moving parts until you realise dashboards, backup policies, and incident triage paths were all ZK-shaped. Industrial event platforms — order propagation across sites, equipment fault broadcasts, digital twin ingest — depend on Kafka because throughput and replay matter. Kafka 4.0 forces revalidation of partition leadership, metadata recovery, upgrade ordering, and consumer offset semantics under broker restarts that no longer consult a separate ensemble.
sequenceDiagram
participant P as Producer service
participant K as KRaft broker quorum
participant C1 as Consumer group: fulfillment
participant C2 as Consumer group: analytics
P->>K: produce OrderReleased (acks=all)
K-->>P: offset committed
K->>C1: deliver to fulfillment partition
K->>C2: deliver to analytics partition
C1-->>K: commit offset
Note over P,K: Metadata via Raft — no ZooKeeper
Figure 1: Producer through KRaft broker to multiple consumer groups — metadata and data plane unified.
{
"streamRouting": {
"clinical-adjacent": {
"broker": "kafka-kraft-prod",
"consistency": "read-after-write-required",
"consumerLagAlertMs": 5000,
"notes": "Route to strongly consistent projection — not reporting replica"
},
"plant-analytics": {
"broker": "kafka-kraft-prod",
"consistency": "eventual-ok",
"consumerLagAlertMs": 120000,
"sink": "read-replica-dashboard"
},
"cross-site-fanout": {
"broker": "kafka-kraft-dr",
"consistency": "at-least-once-idempotent",
"partitionKey": "siteId"
}
}
}
Why vendor docs under-specify KRaft cutover
Release notes emphasise feature removal; they rarely budget the migration work platform teams actually face. Lift-and-shift fantasies die when metadata migration tooling meets production ACL complexity, when old producer libraries pretend the world still looks like Kafka 2.8, or when monitoring rewires because ZK metrics simply vanish. A useful broader framing — brokers, queues, streaming contracts, and when each pattern fits — appears in Digital Applied’s 2026 event-driven architecture engineering reference, which situates Kafka 4.0 as one node in a mesh of delivery guarantees and idempotency choices rather than an isolated upgrade ticket.
Platform engineers should treat KRaft migration like a database engine upgrade: parallel environments, explicit rollback criteria, and write/read freeze windows where topic metadata cannot change mid-cutover. Event-driven systems do not forgive ambiguous states — a producer writing to a cluster whose controller quorum is split-brain during migration weekend will surface as duplicate messages, stuck consumers, or worse, silent offset gaps that finance reconciles manually for weeks.
Three design pressures intensify after ZooKeeper removal:
- Ordering versus scale: higher partition counts still do not deliver global order; design aggregates per partition key
- Exactly-once illusions: EOS configurations trade operational complexity for semantics many domains absorb with idempotent consumers instead
- Schema governance: incompatible Avro or Protobuf payloads become production incidents at wire speed during rolling restarts
Event-driven platforms almost always feed read-optimised projections. Operators query dashboards backed by replicas or materialised views fed from consumer lag. When those read paths present stale state as authoritative, decisions go wrong — not because Kafka failed, but because the architecture blurred delivery with truth. That boundary is documented in Read Replicas Are Not Clinical Truth: a replica is a performance tool, not a contract for correctness. After a Kafka 4.0 migration, consumer lag spikes during broker rolling restarts; if your UI hides that lag, you ship operational risk to the shop floor.
| Workload type | Kafka 4.0 KRaft | AWS EventBridge | NATS JetStream |
|---|---|---|---|
| High-throughput event log with replay | Primary choice — partition scale, retention | Poor fit — no durable log semantics | Possible — smaller retention windows |
| Cross-account SaaS fan-out | Requires self-managed ops | Strong fit — native IAM routing | Edge / leaf-node fan-out only |
| Sub-10ms control-plane signals | Overkill — broker overhead | Latency variable | Strong fit — lightweight subjects |
| Analytics pipeline (eventual OK) | Strong — consumer groups, lag metrics | Moderate — pay per event | Moderate — limited ecosystem |
| Transactional outbox relay target | Strong — idempotent consumers + keys | Moderate — no ordering guarantee | Weak — at-most-once defaults |
Architecture rule: KRaft migration does not change delivery semantics — treat broker durability and end-to-end consistency as separate contracts; never infer database truth from consumer lag alone.
Implementable checklist: ZooKeeper to KRaft
Testable from a staging cluster that mirrors production topic counts and ACL sets:
- Deploy KRaft staging with production-scale partition counts; verify metadata migration tooling on a full topic export
- Validate backup and restore for KRaft metadata log segments — not legacy ZK snapshots
- Rehearse controller quorum loss: document expected leader election timing and alert thresholds
- Pin client library versions against broker 4.x; reject producers still on pre-3.0 protocols in CI
- Instrument end-to-end lag from domain commit to consumer offset — not broker metrics alone
- Freeze schema registry changes during cutover windows; incompatible payloads amplify rollback cost
- Run read-after-write tests on clinical or safety-adjacent projections after each rolling restart
- Document rollback criteria: metadata version, consumer offset drift ceiling, maximum acceptable lag duration
Delivery guarantees and the outbox question
Kafka upgrades shine a light on a problem that predates KRaft: writing to a database and publishing to a topic atomically. Dual writes — commit the row, then fire-and-forget to Kafka — fail in the gap between transactions. The transactional outbox pattern remains the industrial answer: persist the outbound event in the same database transaction as your state change, then relay asynchronously. Manufacturing systems use this constantly: a production order row moves to Released and an outbox row records OrderReleased with the same commit boundary. Relay processes read the outbox, publish to Kafka, and mark delivery — retries do not double-release because the domain transaction already happened once.
Skipping the outbox because “Kafka 4.0 is more reliable now” confuses broker durability with end-to-end consistency. KRaft improves metadata resilience; it does not join your SQL transaction. Routing policy JSON above separates clinical-adjacent streams — where read-after-write proof is mandatory — from plant-analytics streams where eventual consistency is acceptable if lag is visible on the dashboard.
Ops gates: SLO, incident class, sign-off
No production cutover without platform engineering and integration owner sign-off. Define SLOs before migration weekend:
- Metadata recovery: controller quorum re-elects within documented p95; page if exceeded
- Producer error rate: zero sustained NotLeaderForPartition after rolling restart completes
- Consumer lag: fulfillment group and analytics group on separate alert thresholds — tune to workload
- Incident class: dual-write gaps (message without DB row) escalate as P1 — same registry as data-loss events
Disaster recovery drills should include broker rolling restarts with consumer groups at production lag levels — not greenfield staging with empty topics. Measure leader election time during controller loss; document expected recovery before go-live sign-off. Blue-green broker deploys that shift producers without client library verification repeat the same outage with new infrastructure.
Kafka 4.0 dropping ZooKeeper is the moment to modernise how you run the bus and how services join it — migrate metadata planes deliberately, recentre delivery guarantees around idempotent consumers and transactional outboxes, and treat read-side projections as eventually consistent unless measured otherwise.

