Skip to main content
Schemas change as the business changes. The Pulsar Schema Registry versions every schema on a topic and checks each new version against the old ones, so that a schema change doesn’t silently break the applications already reading that topic.
Schema evolution applies to Avro, JSON, Protobuf, and ProtobufNative schemas. Other schema types use a default checker that disables evolution entirely.
Two mechanisms govern evolution: the compatibility check, which decides whether a new schema is allowed at all, and AutoUpdate, which decides whether a passing schema is registered automatically.

Schema versioning

Every SchemaInfo stored with a topic carries a version, and versions are what make schema change manageable within a topic. Messages produced with a SchemaInfo are tagged with its schema version. When a client consumes one, it uses that version to retrieve the matching SchemaInfo and deserialize the data with the right schema. Once a producer is assigned a version, every subsequent message it sends carries that version. Suppose you create a producer like this:
Three things can happen when that producer connects:

Schema compatibility check

A compatibility check exists to guarantee that consumers already running can still process the messages a new schema introduces. When a broker receives a SchemaInfo from a producer, it identifies the schema type and runs that type’s compatibility checker against the topic’s existing schema, applying the configured strategy. Avro, JSON, and Protobuf each have their own checker; every other schema type falls back to a default checker that disables evolution.

Compatibility strategies

Suppose a topic holds three schema versions—V1 is the oldest, V3 the newest.
The default strategy depends on the schema type: FULL for Avro and JSON, and ALWAYS_INCOMPATIBLE for everything else. To change it, see Set the compatibility strategy.
A Pulsar cluster with the Kafka protocol enabled runs both registries, and they do not share a default. Pulsar defaults to FULL for Avro and JSON; the Kafka Schema Registry defaults to BACKWARD for every format. If you operate both on the same cluster, set the strategy explicitly on each rather than relying on either default.
For deeper background on what constitutes a compatible change in each format, see the Avro schema resolution rules and the Protobuf field rules.

Schema validation enforcement

Schema validation enforcement lets brokers reject producers and consumers that connect without a schema. It’s disabled for producers by default (isSchemaValidationEnforced is false), which means:
  • A producer with no schema can write anything to a topic that has one, so a misconfigured application can put garbage on a schematized topic.
  • Clients with no schema support can produce to a topic that has a schema.
Turn it on when a topic’s schema is a contract you need enforced. See Manage schema validation.

Schema AutoUpdate

AutoUpdate is enabled by default. When a schema passes the compatibility check, the producer registers it against the topic automatically.

On the producer side

  • If the topic has no schema—the data is raw bytes—Pulsar registers the schema automatically.
  • If the topic has a schema but the producer carries none, it produces raw bytes. Whether it’s allowed depends on schema validation enforcement: with enforcement off the producer connects and writes; with it on the producer is rejected.
  • If the topic has a schema and the producer carries one, the broker follows the producer-side workflow.

On the consumer side

  • A consumer connecting to a topic without a schema consumes raw bytes and connects with no compatibility check.
  • A consumer connecting to a topic with a schema follows the consumer-side workflow.

Order of upgrading clients

Which side you upgrade first is determined by the compatibility strategy—get this backwards and you break consumers in production even though every schema passed its check.

What’s next

Manage schemas

Set the compatibility strategy and manage schema versions.

Schema types

Which types support evolution, and how they’re defined.
Parts of this page are adapted from the Apache Pulsar documentation, licensed under the Apache License 2.0.