Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Schema Registry

Schema Registry provides centralized schema management for Apache Kafka, ensuring data compatibility between producers and consumers.

Schema Registry is a Separate Service

Schema Registry is not part of Apache Kafka. It is a standalone service that runs separately from Kafka brokers and must be deployed, operated, and scaled independently.


Schema Registry is an external service that stores and manages schemas for Kafka messages. Producers and consumers communicate with Schema Registry via REST API to register, retrieve, and validate schemas, while continuing to read and write data through Kafka brokers.

Schema Registry (separate service)OrderUserKafka Clusterv1: id=101v2: id=273v1: id=83Topic: ordersProducerConsumerserialize - lookup id=273lookup id=273produce [id=273|payload]consume [id=273|payload]

Apache Kafka is designed to be a high-performance, schema-agnostic message broker. Kafka brokers store and deliver bytes without understanding the structure of message content.

Design DecisionRationale
Broker simplicityBrokers focus on storage and delivery, not data validation
PerformanceNo parsing or validation overhead in the critical path
FlexibilityApplications choose their own serialization formats
Independent scalingSchema operations scale separately from message throughput

Schema enforcement happens at the client level—producers serialize with a schema, consumers deserialize with a schema—while the broker remains unaware of message structure. Schema Registry provides the coordination layer that makes this work across distributed applications.


Multiple Schema Registry implementations exist, each with different licensing, features, and deployment models.

A high-performance, API-compatible Kafka Schema Registry written in Go. Drop-in replacement for Confluent Schema Registry with enterprise features and flexible storage backends.

AspectDetails
LicenseApache 2.0 (fully open source)
FormatsAvro, Protobuf, JSON Schema
StoragePostgreSQL, MySQL, Cassandra (no Kafka dependency)
DeploymentSingle binary, Docker, Kubernetes
Memory~50MB (vs ~500MB+ for Java-based registries)

Key advantages:

  • No Kafka dependency - Uses standard databases for storage, simplifying operations
  • Enterprise security - Built-in LDAP, OIDC, mTLS, API keys, RBAC, audit logging
  • Lightweight - Single Go binary with minimal resource footprint
  • API compatible - Drop-in replacement for Confluent Schema Registry

AxonOps Schema Registry Operations for deployment and configuration

The original Schema Registry, created by Confluent (the company founded by Apache Kafka's creators). First released as part of Confluent Platform around 2015.

AspectDetails
LicenseConfluent Community License (source-available, not open source)
FormatsAvro, Protobuf, JSON Schema
StorageKafka topic (_schemas)
DeploymentSelf-managed or Confluent Cloud
EcosystemLargest ecosystem of client libraries, connectors, tools

Confluent Schema Registry is the de facto standard—most documentation, tutorials, and client libraries assume this implementation.

Open source registry developed by Red Hat, supporting multiple artifact types beyond Kafka schemas.

AspectDetails
LicenseApache 2.0 (fully open source)
FormatsAvro, Protobuf, JSON Schema, OpenAPI, AsyncAPI, GraphQL, WSDL
StorageKafka, PostgreSQL, or SQL Server
DeploymentSelf-managed or Red Hat OpenShift
EcosystemConfluent SerDe compatible mode available

Apicurio is the choice for organizations requiring open source licensing or needing to manage API specifications alongside Kafka schemas.

Open source drop-in replacement for Confluent Schema Registry, developed by Aiven.

AspectDetails
LicenseApache 2.0 (fully open source)
FormatsAvro, Protobuf, JSON Schema
StorageKafka topic
DeploymentSelf-managed or Aiven Cloud
EcosystemAPI-compatible with Confluent Schema Registry

Karapace aims for 1:1 compatibility with Confluent Schema Registry API, enabling migration without client changes.

Fully managed schema registry integrated with AWS services.

AspectDetails
LicenseProprietary (AWS managed service)
FormatsAvro, JSON Schema, Protobuf
StorageAWS managed
DeploymentAWS only (serverless)
EcosystemIntegrates with MSK, Kinesis, Lambda, Glue ETL

AWS Glue Schema Registry is appropriate for AWS-centric architectures using Amazon MSK.

Schema registry for Azure Event Hubs, supporting Kafka protocol.

AspectDetails
LicenseProprietary (Azure managed service)
FormatsAvro, JSON
StorageAzure managed
DeploymentAzure only
EcosystemIntegrates with Event Hubs, Azure Functions
RegistryLicenseStorageConfluent APIEnterprise Security
AxonOpsApache 2.0PostgreSQL/MySQL/Cassandra✅ LDAP, OIDC, RBAC
ConfluentCommunity LicenseKafka topic✅ (reference)⚠️ Enterprise only
ApicurioApache 2.0Kafka/PostgreSQL/SQL Server⚠️ Limited
KarapaceApache 2.0Kafka topic⚠️ Limited
AWS GlueProprietaryAWS managed✅ IAM
AzureProprietaryAzure managed✅ Azure AD

Recommendation

For new deployments, AxonOps Schema Registry provides the best combination of open source licensing, enterprise features, and operational simplicity (no Kafka dependency for schema storage).


A schema is a formal definition of data structure—it specifies the fields, their types, and constraints that data must conform to.

AspectDescription
FieldsNamed elements that make up the data (e.g., id, name, timestamp)
TypesData type of each field (e.g., string, integer, boolean, array)
ConstraintsRules fields must follow (e.g., required, nullable, valid range)
RelationshipsHow nested structures and references work
ApproachCharacteristics
Schema-basedStructure defined upfront; validated at write time; compatible evolution enforced
SchemalessFlexible structure; validated at read time (if at all); evolution is implicit

Kafka itself is schemaless—brokers store bytes without understanding their structure. Schema Registry adds schema enforcement on top of Kafka.

{
"type": "record",
"name": "User",
"fields": [
{"name": "id", "type": "long"},
{"name": "name", "type": "string"},
{"name": "email", "type": ["null", "string"], "default": null},
{"name": "created_at", "type": {"type": "long", "logicalType": "timestamp-millis"}}
]
}

This Avro schema specifies:

  • id must be a 64-bit integer
  • name must be a string
  • email is optional (nullable with null default)
  • created_at is a timestamp represented as milliseconds

Any data that does not conform to this structure is rejected at serialization time.


Kafka topics are schema-agnostic—the broker stores bytes without understanding their structure. This flexibility becomes problematic when multiple applications produce and consume the same topics.

Without Schema RegistryProducer A(version 1)Producer B(version 2)Kafka TopicConsumerConsumer receives inconsistent data:- Different field names- Different data types- No way to validate{"name":"John","age":30}{"fullName":"Jane","age":"25"}???
ProblemImpact
Format inconsistencyProducers use different field names, types, or structures
Silent breakageSchema changes break consumers without warning
No contract enforcementDocumentation becomes stale; no runtime validation
Difficult evolutionCannot safely add or remove fields
Debugging complexityHard to understand data format across systems

Schema Registry is a separate service that stores schemas in a Kafka topic (_schemas) and provides a REST API for schema operations.

ProducerSchema Registry_schemasKafka BrokerConsumerProducerProducerSchema RegistrySchema Registry_schemas_schemasKafka BrokerKafka BrokerConsumerConsumerProducer Registration1. Register schemaStore schema2. Return schema IDMessage Production3. Send [schema_id + payload]Message Consumption4. Deliver [schema_id + payload]5. Lookup schema by ID6. Return schema7. Deserialize with schemaRegistry provides:- Schema storage- Compatibility checking- Version management- ID assignment

Messages produced with Schema Registry include a schema ID prefix:

| Magic Byte (1) | Schema ID (4) | Payload (variable) |
| 0x00 | 00 00 00 01 | [serialized data] |
ComponentSizeDescription
Magic byte1 byteAlways 0x00 (indicates Schema Registry format)
Schema ID4 bytesBig-endian integer identifying the schema
PayloadVariableSerialized data (Avro, Protobuf, or JSON)

This format allows consumers to deserialize messages without prior knowledge of the schema—they retrieve the schema from the registry using the embedded ID.


Schema Registry supports three serialization formats:

Avro is the most widely used format with Kafka due to its compact binary encoding and rich schema evolution support.

{
"type": "record",
"name": "User",
"namespace": "com.example",
"fields": [
{"name": "id", "type": "long"},
{"name": "name", "type": "string"},
{"name": "email", "type": ["null", "string"], "default": null}
]
}
CharacteristicAvro
EncodingBinary (compact)
Schema requiredFor both serialization and deserialization
Evolution supportExcellent (defaults, unions)
Language supportJava, Python, C#, Go, others
Typical use caseData pipelines, Kafka Connect

Protobuf offers efficient binary encoding with strong typing and is popular in gRPC-based systems.

syntax = "proto3";
message User {
int64 id = 1;
string name = 2;
optional string email = 3;
}
CharacteristicProtobuf
EncodingBinary (compact)
Schema requiredFor both serialization and deserialization
Evolution supportGood (field numbers, optional)
Language supportExcellent (official support for many languages)
Typical use caseMicroservices, systems already using gRPC

JSON Schema validates JSON documents and is useful when human readability is required.

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"},
"email": {"type": "string"}
},
"required": ["id", "name"]
}
CharacteristicJSON Schema
EncodingJSON (human-readable)
Schema requiredOnly for validation
Evolution supportLimited
Language supportUniversal (JSON everywhere)
Typical use caseAPIs, debugging, human inspection
AspectAvroProtobufJSON Schema
Message sizeSmallSmallLarge
Serialization speedFastFastModerate
Human readableNoNoYes
Schema evolutionExcellentGoodLimited
Kafka ecosystem supportExcellentGoodGood

Schema Formats Guide


Schema Registry enforces compatibility rules when schemas evolve. Compatibility ensures that schema changes do not break existing producers or consumers.

Backward CompatibleForward CompatibleData writtenwith v1Data writtenwith v2Consumerusing v2 schemaData writtenwith v1Data writtenwith v2Consumerusing v1 schemaNew schema reads old dataUpgrade consumers firstOld schema reads new dataUpgrade producers first
ModeRuleUpgrade Order
BACKWARDNew schema can read data written with old schemaConsumers first
BACKWARD_TRANSITIVENew schema can read data from all previous versionsConsumers first
FORWARDOld schema can read data written with new schemaProducers first
FORWARD_TRANSITIVEAll previous schemas can read new dataProducers first
FULLBoth backward and forward compatibleAny order
FULL_TRANSITIVEFull compatibility with all versionsAny order
NONENo compatibility checkingNot recommended
Change TypeBACKWARDFORWARDFULL
Add optional field with default
Remove optional field with default
Add required field
Remove required field
Add optional field (Avro union with null)
Remove optional field (Avro union with null)

Compatibility Guide


Schemas are organized into subjects. The subject naming strategy determines how schemas are associated with topics.

StrategySubject NameUse Case
TopicNameStrategy<topic>-key, <topic>-valueOne schema per topic (default)
RecordNameStrategy<record-namespace>.<record-name>Multiple record types per topic
TopicRecordNameStrategy<topic>-<record-namespace>.<record-name>Multiple types with topic isolation
Topic: orders
Key subject: orders-key
Value subject: orders-value

Most deployments use TopicNameStrategy—each topic has one schema for keys and one for values.

Topic: events
Records: com.example.OrderCreated, com.example.OrderShipped
Subjects: com.example.OrderCreated, com.example.OrderShipped

RecordNameStrategy allows multiple record types in a single topic, useful for event sourcing where different event types share a topic.


Schema evolution allows schemas to change over time while maintaining compatibility with existing data.

Schema Evolution TimelineData in Topicv1(id, name)v2(id, name, email)v3(id, name, email, phone)Messages with v1Messages with v2Messages with v3ConsumerConsumer with v3 schema can readall messages (v1, v2, v3) due tobackward compatibilityadd email(optional)add phone(optional)read with v3 schemaread with v3 schemaread with v3 schema
PracticeRationale
Use optional fieldsAllow safe addition and removal
Provide defaultsEnable backward compatibility
Never change field typesType changes break compatibility
Never reuse field namesPrevious data may have different semantics
Add to end of recordsMaintains wire compatibility
Use aliases for renamingProvides backward compatibility for renamed fields

Schema Evolution Guide


# Schema Registry URL
schema.registry.url=http://schema-registry:8081
# Key serializer (for Avro keys)
key.serializer=io.confluent.kafka.serializers.KafkaAvroSerializer
# Value serializer (for Avro values)
value.serializer=io.confluent.kafka.serializers.KafkaAvroSerializer
# Auto-register schemas (default: true)
auto.register.schemas=true
# Use latest schema version (default: false)
use.latest.version=false
# Schema Registry URL
schema.registry.url=http://schema-registry:8081
# Key deserializer
key.deserializer=io.confluent.kafka.deserializers.KafkaAvroDeserializer
# Value deserializer
value.deserializer=io.confluent.kafka.deserializers.KafkaAvroDeserializer
# Return specific record type (vs GenericRecord)
specific.avro.reader=true

Key server configurations:

PropertyDefaultDescription
kafkastore.bootstrap.servers-Kafka bootstrap servers for _schemas topic
kafkastore.topic_schemasTopic for schema storage
kafkastore.topic.replication.factor3Replication factor for schemas topic
compatibility.levelBACKWARDDefault compatibility mode
mode.mutabilitytrueAllow changing compatibility mode

Schema Registry provides a REST API for schema operations.

Terminal window
curl -X POST \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "{\"type\":\"record\",\"name\":\"User\",\"fields\":[{\"name\":\"id\",\"type\":\"long\"},{\"name\":\"name\",\"type\":\"string\"}]}"}' \
http://schema-registry:8081/subjects/users-value/versions

Response:

{"id": 1}
Terminal window
curl http://schema-registry:8081/subjects/users-value/versions/latest
Terminal window
curl -X POST \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "{...}"}' \
http://schema-registry:8081/compatibility/subjects/users-value/versions/latest
EndpointMethodDescription
/subjectsGETList all subjects
/subjects/{subject}/versionsGETList versions for subject
/subjects/{subject}/versionsPOSTRegister new schema
/subjects/{subject}/versions/{version}GETGet specific version
/schemas/ids/{id}GETGet schema by global ID
/configGET/PUTGlobal compatibility config
/config/{subject}GET/PUTSubject-level compatibility

For production deployments, Schema Registry should be deployed with high availability.

Schema Registry ClusterKafka ClusterPrimary(leader)Replica 1(follower)Replica 2(follower)_schemasLoad BalancerPrimary handles writesReplicas handle readsElection via Kafka group protocolwritesreadsreadswritereadread
AspectRecommendation
Instance countMinimum 2, typically 3 for high availability
Leader electionUses Kafka consumer group protocol
Read scalingAdd replicas for read throughput
Write scalingSingle primary (not horizontally scalable for writes)
Schemas topicReplication factor ≥ 3, min.insync.replicas = 2