Skip to main content
José David Baena

On this page

Kafka Compatibility Is Not the Same as Portability

Banner.jpeg
Published on
/16 mins read

Hypothetical: A staging producer accepts a new bootstrap.servers value, authenticates, writes one record, and reads it back. The migration ticket turns green.

The rollback drill asks harder questions. Does acks=all, the producer mode that waits for every current in-sync replica, prove the same durability event? Can a read_committed consumer hide the same aborted records? Did the destination receive the consumer checkpoint before the source group stopped? If record files live in your object-storage bucket, can you reconstruct their topic, partition, and offset order without the vendor's metadata service?

Kafka compatibility means that some Kafka clients and tools can communicate with a target. Portability means that a workload can move while preserving its required behavior, state, recovery objectives, operating model, and commercial boundary.

The previous acquisition post grouped an exit into four planning planes. This final audit splits the application plane into client/API and behavioral semantics, then splits operations into durability/storage and control-plane work. The result is six test layers rather than a competing taxonomy.

Compatibility is an entrance test. Portability is a rehearsed exit.

For the byte-level contract behind the first test, read Kafka Wire Protocol: How Compatibility Survives Upgrades. This post starts where a successful handshake stops.

A green client test covers one layer out of six

A wire protocol is the binary request and response contract. An API surface is the set of operations and versions a server implements. A control plane creates, configures, secures, and coordinates the service around the record path.

Recovery point objective (RPO) is the maximum acceptable data loss. Recovery time objective (RTO) is the maximum acceptable outage or degraded period.

The portability test has six layers:

LayerQuestionEvidence that counts
Client and APICan every production client, authentication path, codec, and required Admin API work?ApiVersions, integration tests, malformed-request tests, effective-config reads
Behavioral semanticsDo ordering, retries, idempotence, transactions, timestamps, errors, retention, and groups preserve application invariants?Failure tests against declared invariants
StateCan records, offsets, schemas, access rules, topic settings, and processing state move together?Full-volume migration and rollback rehearsal
Durability and storageWhat event makes a write durable, and what metadata is needed to recover it?Acknowledgement-path analysis, fault injection, restore drill
Operations and control planeCan the team monitor, scale, upgrade, diagnose, secure, and recover the target?Runbooks executed by the owning on-call team
Contract and economicsDo license rights, service terms, support, commitments, data transfer, and exit cost fit?Governing terms and a peak, replay, dual-run, and termination cost model

A wire-compatible endpoint can remove an application rewrite. It cannot answer the other five rows.

The survey uses current first-party evidence, not a conformance badge

The product pins below reflect primary sources checked on August 1, 2026:

I did not run a vendor-neutral conformance suite against these systems. Vendor tests and compatibility statements are evidence of vendor intent, not third-party certification.

The decision rule is strict: when a pinned source does not establish a required feature, or first-party pages conflict, classify the feature as unverified. For a correctness requirement, unverified means unavailable until the exact target advertises and passes it.

Different implementations preserve different parts of Kafka

The systems fall into distinct architecture classes:

Target classCurrent exampleWhat compatibility can preservePortability boundary
Reference implementationApache Kafka 4.3.1The upstream protocol, coordinator, storage, and feature-level modelYou still own operations, upgrades, recovery, and infrastructure
Managed named Kafka releaseAmazon MSK 4.2.x; Google Managed Kafka 3.7.1A known upstream code line and broad client behaviorProvider identity, storage access, configs, versions, metrics, and service APIs
Independent compatible brokerRedpanda 26.2.1Core Kafka clients, produce, consume, classic groups, and transactionsDifferent replication, storage, feature set, configs, and license
Object-storage-first engineWarpStream Agent v826Kafka clients, groups, transactions in normal mode, and selected Admin APIsVendor metadata defines offsets and ordering; operating modes can change semantics
Kafka-derived storage replacementAutoMQ OSS 1.7.2Large parts of Kafka 3.9.1 compute and coordinator behaviorS3Stream, write-ahead log, object metadata, and a 3.9.1 source base
Proprietary managed Kafka engineConfluent Cloud KoraConfluent claims broad Kafka client features, including exactly-once semanticsNo Apache broker release maps to the service; tier and control plane matter
Protocol facade over another serviceAzure Event HubsProduce, consume, groups, offsets, and selected Kafka client featuresAzure resource model, service limits, Admin gaps, and conflicting transaction docs

The rows do not rank products. They identify which assumption must be tested next.

Running Apache Kafka does not make the service control plane portable

Amazon MSK and Google's managed service both run named Apache Kafka releases, but the surrounding contract differs.

Amazon's supported-version table lists Kafka 4.2.x on Express brokers and excludes KIP-932 Queues for Kafka. With AWS Identity and Access Management (IAM) authorization, Kafka ACL APIs can succeed while having no authorization effect on IAM identities. The request worked; the policy did not move.

Google's service overview pins brokers to Kafka 3.7.1, hides the backing Cloud Storage buckets, and does not expose Java Management Extensions (JMX) metrics. It supports IAM-backed Simple Authentication and Security Layer (SASL) and mutual TLS (mTLS), but not common mechanisms such as Salted Challenge Response Authentication Mechanism (SCRAM) or Generic Security Services API (GSSAPI), often used with Kerberos. Broker code compatibility does not transfer authentication, metrics, storage custody, or upgrade control.

For a managed named release, test the upstream APIs and the provider control plane as separate products.

Redpanda keeps familiar requests while changing broker invariants

Redpanda's current documentation says it validates Kafka 4.x-capable clients across core produce, consume, and transaction operations. Its 26.2.1 source also shows important boundaries.

The pinned handler list contains classic JoinGroup, SyncGroup, and Heartbeat handlers, but no ConsumerGroupHeartbeat or ConsumerGroupDescribe handlers. A classic group test therefore says nothing about group.protocol=consumer.

Redpanda's compatibility page states that it does not implement KIP-890's server side. Kafka 4.x clients fall back to the original transaction protocol. That may fit the workload, but the transaction generation belongs in the test record.

The 26.2.1 topic-config source accepts several Kafka property names as no-ops, including min.insync.replicas and flush.messages. A successful Admin response is not proof that the target changed runtime behavior.

This is the larger lesson: configuration-name compatibility can be more dangerous than an explicit error because it turns a rejected assumption into a green deployment.

For Redpanda, read back effective configuration, then inject the failure that the setting was meant to control.

Object ownership is not stream ownership

An object-storage engine separates record files from the metadata that gives those files Kafka meaning.

WarpStream's architecture documentation places record data in customer object storage and keeps Virtual Cluster metadata in a vendor-operated service. Its read-path documentation says files can reach object storage out of order; the metadata store maps files to topic-partition offset ranges and provides the authoritative order.

Owning the bucket therefore gives custody of bytes. It does not, by itself, give a documented procedure for rebuilding the ordered log.

WarpStream's normal mode supports Kafka transactions and exactly-once semantics. Other modes have different contracts:

  • Orbit Auto Migration at Agent v826 does not support transactional produce while a topic is in PROXY or MIGRATING.
  • Ripcord keeps Produce available during control-plane loss, but Fetch stops, returned offsets are zero, idempotent producers and transactions must be disabled, and external consistency is not guaranteed.

Those modes are useful because they make trade-offs explicit. They also prove that a product name is not a semantic pin. Record the exact mode.

AutoMQ creates a different object-storage boundary. The 1.7.2 release artifact is named automq-1.7.2_kafka-3.9.1.tgz, and its tagged gradle.properties sets the base version to 3.9.1. AutoMQ replaces Kafka's log storage with S3Stream, its object-backed stream library, and uses a write-ahead log (WAL) to protect the write path.

AutoMQ's documentation claims full Kafka compatibility. The source pin gives a more precise starting question: which Kafka 3.9.1 behavior remains unchanged, which later APIs did AutoMQ add, and which recovery steps depend on S3Stream data and operation metadata?

Bucket access is necessary. An executable reader for the metadata and object layout is the portability asset.

Kora and Event Hubs show two kinds of version ambiguity

Confluent Cloud runs Kora, a proprietary engine that does not track one Apache Kafka release. Confluent claims all client features since Kafka 0.10, including exactly-once semantics, and documents KIP-848 support for current Java and librdkafka clients. The semantic pin still includes the service tier: Freight does not support transactions.

Azure Event Hubs creates a different ambiguity. Microsoft describes it as a Kafka endpoint over Event Hubs rather than a Kafka broker. Topic administration uses Azure APIs, and broker configurations are unavailable.

Its first-party transaction documentation conflicts:

Until Microsoft publishes one unambiguous, tier-specific contract and the target namespace passes failure tests, treat transactions as unsupported. Conflicting primary sources are not a tie. They are a stop signal.

Durable authority decides what an acknowledgement proves

Durable authority is the state from which a system can reconstruct an acknowledged record. Different authorities create different failure and exit paths.

System or modeDurable authority before acknowledgementMetadata needed for recoveryExit question
Apache Kafka 4.3.1In-sync replica progress under the selected Kafka settings; acks=all does not itself require per-request disk flushKRaft metadata plus partition logsCan another cluster receive records, offsets, configs, and required visibility within RPO and RTO?
Redpanda local storagePartition Raft and the configured flush or write-cache policyController and partition Raft stateDoes the target preserve the accepted crash and storage-loss outcome?
WarpStream normal modeObject write plus commit to Virtual Cluster metadataVendor metadata maps files to ordered offsetsCan both records and ordering metadata be exported before service loss?
WarpStream RipcordObject-storage journal before asynchronous metadata commitJournal replay plus later control-plane recoveryDoes write availability without read progress or external consistency fit?
AutoMQConfigured WAL and object-storage path through S3StreamKafka-derived control state plus S3Stream operation metadataCan a supported replacement interpret both object classes?
Managed Kafka serviceProvider-managed broker and storage pathKafka state plus provider control planeWhich state is exportable, and who controls the recovery clock?

The same Kafka client call can sit above a local replica quorum, an object store plus metadata service, or another cloud event system. Match the failure you can tolerate, not the spelling of acks.

Migration copies checkpoints, not live coordination

A consumer offset is a stored checkpoint. A group generation identifies a coordinator's current membership and assignment epoch. Replication can copy a checkpoint. It does not move live sockets, in-flight callbacks, or a running generation into another coordinator.

A transaction marker records commit or abort state in a Kafka partition. Moving record bytes without the required marker visibility can change what a read_committed consumer observes. Active producer IDs, epochs, and open transaction-coordinator state also belong to the source.

Migration pathDirection and stopping pointOffset behaviorSemantic boundary
Apache MirrorMaker 2Each flow is directional, such as A -> B; reverse needs another flowEmits checkpoints and can synchronize translated committed offsetsTarget consumers form new generations; the docs do not claim to transfer live membership or open transaction-coordinator state
Confluent Cluster LinkingSource to mirror topic; promote stops mirroring and offset sync for that topicDefault offset sync is 30 seconds; data lag must reach the checkpointMirror topics do not support transactions or exactly-once semantics
WarpStream Orbit Auto Migration v826Source to WarpStream; COMPLETE is terminalSource offsets must be preserved and verified for consumersPROXY and MIGRATING do not support transactional produce
Amazon MSK ReplicatorAsynchronous source to target; reverse is another designReplicates consumer offsets, topic configuration, and a subset of literal topic ACLs; IAM policies and roles do not moveDocumentation does not claim to move live group or transaction-coordinator state
MirrorMaker to Azure Event HubsSource to Event HubsExisting consumer offsets do not arrive; consumers choose a reset pointAzure resource and transaction boundaries replace Kafka broker behavior

Before any promotion, record:

  1. source and destination log-start and log-end offsets per partition;
  2. replication lag in offsets and time;
  3. the committed offset for every moving group;
  4. whether the destination contains the record visible at that checkpoint;
  5. active producers, consumers, and transactions still on the source;
  6. the first operation after which writes cannot safely return;
  7. measured cutover and rollback RPO and RTO.

If the runbook cannot name the irreversible operation, it is not a rollback runbook.

Real failures reveal the hidden contract

Observed bugs and documented limits carry different weight, but both belong in the decision.

EvidencePrimary recordWhat it proves
Upstream regressionKAFKA-19444A client can depend on an API version through authentication even when application code never calls it
Accepted no-op configRedpanda 26.2.1 topic config sourceAdmin success can hide unchanged runtime behavior
Mode-specific semantic downgradeWarpStream RipcordAvailability mode can disable idempotence, transactions, reads, and ordering guarantees
First-party conflictAzure transaction page and configuration pageProduct documentation can be too inconsistent to support a correctness claim

Do not rewrite a limitation as an outage or an outage as a universal product property. Use each record to design the next test.

Normalize semantics before measuring performance

Vendor benchmarks help select hypotheses. They do not provide a neutral ranking.

Test dimensionPin before load generationFailure prevented
Durabilityacks, quorum rule, flush or write cache, replication, object commitComparing different loss envelopes under one label
Producer correctnessIdempotence, transaction generation, retries, in-flight requestsGiving one target safer or cheaper retries
Consumer behaviorGroup protocol, assignor, read_committed, offset resetComparing different visibility or reassignment contracts
Data shapeRecord-size distribution, keys, entropy, codec, batch size, lingerGiving one engine easier payloads
Storage stateEmpty, warm cache, cold object read, aged retention, compaction backlogPublishing a hot-cache replay result
LoadFixed offered-load points through saturation, achieved throughput, errorsCalling a lower-load run faster
Distributionp50, p95, p99, p99.9, max, retries, sample count, repeated runsHiding queueing and failures behind an average
RecoveryProcess, zone, control-plane, storage, credential, and network faultsMeasuring only healthy steady state
CostVendor meter, infrastructure, transfer, object requests, support, and dual-run monthMoving cost into an omitted invoice

For Redpanda, setting min.insync.replicas=2 without checking effective behavior does not normalize durability. For WarpStream, Agent version and normal, Orbit, or Ripcord mode belong in the result. For AutoMQ, Kafka base, WAL type, object store, and cache state belong there. For managed services, tier and region are part of the implementation.

A tested exit is the only credible portability claim

A decision is ready only when three artifacts exist:

ArtifactWhat it must proveInvalid substitute
Versioned conformance reportThe pinned target passes every required check across the six layers defined at the startA vendor compatibility page or one producer-consumer smoke test
Full-volume migration and rollback recordData, offsets, recovery metadata, operators, and tooling meet measured RPO and RTO under failureA paper runbook or a sample-topic copy
Signed dependency recordOwners accept any unportable feature, license term, control-plane dependency, and exit costCalling an untested requirement "standard Kafka"

Ordinary at-least-once transport may pass with modest work. Stateful stream processing, strict transactional visibility, cloud-native IAM, or years of retained history raise the bar. Sometimes the current platform still wins. The useful result is knowing which requirement made it win.

Kafka compatibility opens the door. Portability begins when the team has walked out and back in.

The course is complete. Turn the Kafka Engineering series into one migration rehearsal against your own workload.

Sources and References

Apache Kafka

Redpanda 26.2.1

WarpStream Agent v826

AutoMQ OSS 1.7.2

Managed services and migration

Share this post

HNPost to Hacker News
Subscribe:RSS feed

Keep reading