04 / 05

How would you test schema compatibility before deploying a producer?

Difficulty: 8/10
Integration testing, Testcontainers, Contract testing

Testing Schema Compatibility Before Deploying a Producer

Testing schema compatibility before deploying a producer means verifying that the new schema version is compatible with the existing schema versions according to the topic's compatibility policy, and that consumers can still deserialize the records the producer will write. The standard approach is to integrate the schema registry's compatibility check into the CI pipeline. Before deploying a producer, the pipeline fetches the new schema, calls the schema registry's compatibility endpoint (or uses the registry's client library), and fails the build if the schema is not compatible. This catches breaking changes before they reach production, which is exactly where you want to catch them. The check should be run against the actual registry that the environment uses, or against a registry that has the same schema versions, so that the compatibility check reflects reality.

The mechanism for the compatibility check depends on the registry. Confluent Schema Registry exposes a POST /compatibility/subjects/{subject}/versions/latest endpoint that returns whether the provided schema is compatible. The pipeline can call this endpoint with the new schema and parse the response. Alternatively, the registry client library provides a testCompatibility method. The check should use the configured compatibility level for the subject; if the subject uses FULL_TRANSITIVE, the check is against all previous versions, not just the latest. This is important because a schema might be compatible with the latest version but not with an older one that some consumers still use. In addition to the registry check, you should have contract tests that verify the consumer can deserialize records produced with the new schema. This catches cases where the schema is technically compatible but the consumer code makes assumptions that break, such as assuming a field is always present when it is now optional. The trade-off is between the speed of the pipeline and the thoroughness of the check. A registry check is fast and catches most issues; contract tests are slower but catch code-level assumptions. Use both for critical topics.

A common mistake is to rely on the producer's auto.register.schemas setting to register the schema at runtime, without any pre-deployment check. This means a breaking schema can be registered and deployed, and consumers break in production. Another mistake is to set compatibility to NONE to avoid pipeline failures; this disables the safety net and is a recipe for incidents. A third mistake is to check compatibility only against the latest version when the subject uses a transitive policy; this misses incompatibilities with older versions. The trade-off is between strictness and developer velocity. A strict compatibility check slows down deployments but prevents breaking changes. A permissive check lets developers move fast but risks production incidents. For shared topics, strict is the right choice. Version note: Confluent Schema Registry's compatibility API has been stable, but the exact behavior depends on the compatibility level and the schema type (Avro, Protobuf, JSON Schema). If you use a different registry, such as AWS Glue Schema Registry or Apicurio, the API differs; check the documentation for the compatibility check endpoint. Also note that the registry's compatibility check is necessary but not sufficient; it does not catch semantic changes that are technically compatible but break business logic.

javascript
  1. 1

    Integrate the schema registry compatibility check into the CI pipeline before deployment.

  2. 2

    Call the compatibility endpoint with the new schema and fail the build if incompatible.

  3. 3

    For transitive policies, check against all previous versions, not just the latest.

  4. 4

    Add contract tests that verify consumers can deserialize records produced with the new schema.

  5. 5

    Do not rely on runtime auto-registration; it can register breaking schemas.

  6. 6

    Do not set compatibility to NONE to avoid pipeline failures.

  7. 7

    The registry check is necessary but not sufficient; it does not catch semantic changes.

Share

Share via WhatsApp, X, Facebook, LinkedIn or copy link. Open Graph preview enabled.