Limitations
Known limitations and workarounds.
Schema Limitationsβ
Recursive Typesβ
Recursive types are supported but have limitations:
{
"type": "record",
"name": "TreeNode",
"fields": [
{"name": "value", "type": "string"},
{"name": "children", "type": {"type": "array", "items": "TreeNode"}}
]
}
Works: Self-referential through arrays or maps.
Limitation: Direct self-reference without container may cause issues in some languages.
Default Valuesβ
Not all Avro default value types are fully supported:
| Default Type | Support |
|---|---|
| Primitives | Full |
| Null | Full |
Empty array [] | Full |
Empty map {} | Full |
| Complex defaults | Partial |
Schema Evolutionβ
Typr Events generates code from schemas at generation time. Schema evolution rules:
- Adding optional fields: Safe (use
["null", "T"]with default) - Removing fields: Requires regeneration
- Renaming fields: Breaking change
- Changing types: Breaking change
Use Confluent Schema Registry for runtime compatibility checking.
Language Limitationsβ
Javaβ
- Requires Java 21+ for pattern matching on sealed types
- Records are final (cannot extend)
- No inline/value classes (wrapper types are full objects)
Kotlinβ
value classhas boxing overhead in some scenarios- Nullable primitives box to wrapper types
Scalaβ
- Opaque types require Scala 3
- Cross-compilation between Scala 2 and 3 may have edge cases
Wire Format Limitationsβ
Confluent Avroβ
- Requires Schema Registry infrastructure
- Schema ID overhead (5 bytes per message)
- Schema compatibility modes affect what changes are allowed
Plain Avroβ
- No automatic schema evolution
- Reader must know writer schema
- No schema versioning
JSONβ
- Larger message sizes
- No schema validation at wire level
- Union type discrimination can be ambiguous
Framework Integrationβ
Springβ
ReplyingKafkaTemplatehas timeout limitations- Reply topic partitioning must be handled carefully for scaling
Quarkusβ
KafkaRequestReplyis relatively new- Native compilation may have reflection issues
Performance Considerationsβ
Wrapper Typesβ
Wrapper types add minimal overhead:
- Java: Object allocation
- Kotlin: Inline classes avoid allocation in most cases
- Scala: Opaque types have zero runtime overhead
Precise Decimal Typesβ
Validation on construction adds overhead. Use unsafeForce when you've already validated.
Multi-Event Topicsβ
Pattern matching on sealed types is highly optimized by JVM.
Workaroundsβ
Schema Evolutionβ
For breaking changes:
- Create new topic/schema version
- Deploy consumers first (handle both versions)
- Deploy producers
- Migrate data if needed
Complex Defaultsβ
If complex defaults aren't supported:
- Use
["null", "T"]withnulldefault - Handle missing values in application code
Recursive Structuresβ
For deep recursion:
- Consider depth limits
- Use iterative algorithms instead of recursive
- Watch for stack overflow on very deep structures
Reporting Issuesβ
If you encounter limitations not documented here:
- Check GitHub issues for existing reports
- Create minimal reproduction case
- Include: Schema, options, generated code, error message