Skip to main content

Avro

Apache Avro is a data serialization system that provides rich data structures and a compact, fast, binary data format. Originally developed within the Apache Hadoop ecosystem, Avro is designed for schema evolution and language-neutral data exchange.

Binary Layout

SectionInternal NameDescriptionPossible Values / Format
File Headermagic4-byte magic number identifying Avro filesASCII: Obj followed by 1 byte (hex: 4F 62 6A 01)
metaMetadata map storing key-value pairs (e.g., schema, codec)Map of string keys to byte values (e.g., "avro.schema" → JSON schema string)
sync16-byte random sync marker used between blocks16 random bytes (unique per file)
Data BlockblockCountNumber of records in the blockLong (variable-length zigzag encoding)
blockSizeSize in bytes of the serialized records (after compression, if any)Long
blockDataSerialized records (optionally compressed)Binary-encoded data per schema
syncSync marker repeated after each blockSame 16-byte value as in header

Schema Types (Stored in Metadata)

TypeInternal NameDescriptionExample / Format
Primitivenull, boolean, int, long, float, double, bytes, stringBasic types`"type": "string"
RecordrecordNamed collection of fields{ "type": "record", "name": "Person", "fields": [...] }
EnumenumNamed set of symbols{ "type": "enum", "name": "Suit", "symbols": ["SPADES", "HEARTS"] }
ArrayarrayOrdered list of items{ "type": "array", "items": "string" }
MapmapKey-value pairs with string keys{ "type": "map", "values": "int" }
UnionJSON arrayMultiple possible types[ "null", "string" ]
FixedfixedFixed-size byte array{ "type": "fixed", "name": "md5", "size": 16 }

JSON Schema Definition

Avro schemas are themselves JSON. A schema authored in this format drives both .avro serialization and VirtualMetric's per-field type coercion before writing. Any schema conforming to the Apache Avro 1.11 specification serializes correctly; the tables below describe which parts VirtualMetric actively understands for validation.

A schema is a single JSON object representing an Avro record:

{
"type": "record",
"name": "MyEvent",
"namespace": "org.example.events",
"fields": [
{ "name": "id", "type": "string" },
{ "name": "created", "type": ["null", { "type": "long", "logicalType": "timestamp-millis" }], "default": null }
]
}
PropertyRequiredDescription
typeYMust be record at the top level
nameYRecord name (used by Avro for type identity)
namespaceNDotted namespace, e.g. org.example.events
fieldsYArray of field definitions

Field Definition

Each entry in fields is an object:

PropertyRequiredDescription
nameYField name; used as the key in the message produced by VirtualMetric
typeYField type — a string, a JSON object, or an array (union)
defaultNDefault value when the field is absent; honored by the encoder

Other Avro field properties (doc, order, aliases) are accepted by the encoder and ignored by VirtualMetric.

Primitive Types

A primitive type is declared as a string, e.g. { "name": "user_id", "type": "string" }. Each maps to a VirtualMetric internal type:

Avro typeInternal typeDescription
stringSTRINGUTF-8 string
booleanBOOLEANBoolean
intINT3232-bit signed integer
longINT6464-bit signed integer
floatFLOAT32-bit floating point
doubleDOUBLE64-bit floating point
bytesBYTE_ARRAYVariable-length byte string
nullUsed inside unions only

Nullable Fields

Declare an optional field as a union with null:

{ "name": "email", "type": ["null", "string"], "default": null }

VirtualMetric reads the union, skips the null branch, and treats the field as the non-null type. Member order does not matter for the validator, though encoders typically expect null first when default is null.

Logical Types

A logical type annotates a primitive with extra semantics, declared as a nested object:

{ "name": "created_at", "type": { "type": "long", "logicalType": "timestamp-millis" } }

VirtualMetric recognizes these logicalType values:

logicalTypeBacking typeInternal typeDescription
timestamp-millislongDATETIMEMilliseconds since the Unix epoch
timestamp-microslongDATETIMEMicroseconds since the Unix epoch
dateintDATETIMEDays since the Unix epoch
decimalbytes / fixedDECIMALFixed-point decimal

Other Avro logical types (uuid, time-millis, time-micros, local-timestamp-millis, duration) are accepted by the encoder but not coerced — they pass through as the underlying primitive. A DATETIME field accepts RFC 3339 timestamps, 2006-01-02 15:04:05 (UTC), or a numeric epoch (seconds, milliseconds, microseconds, or nanoseconds, auto-detected).

Validation Scope

The schema is consumed by two layers. The validator extracts the top-level field-name-to-type mapping and coerces each top-level field into its declared type before encoding (so a string "42" on an int field becomes a real integer). The encoder consumes the full Avro 1.11 specification. Automatic coercion applies only to top-level scalars, top-level nullable unions of primitives, and the four logical types above; nested record, array, map, enum, and fixed types serialize correctly but their values pass through without per-element coercion. Keep fields you want coerced at the top level.

Reference Example

{
"type": "record",
"name": "AuditLog",
"namespace": "org.example.audit",
"fields": [
{ "name": "id", "type": "string" },
{ "name": "received_at", "type": { "type": "long", "logicalType": "timestamp-millis" } },
{ "name": "actor_id", "type": ["null", "string"], "default": null },
{ "name": "severity", "type": "int" },
{ "name": "success", "type": "boolean" },
{ "name": "amount", "type": ["null", { "type": "bytes", "logicalType": "decimal", "precision": 18, "scale": 4 }], "default": null },
{ "name": "tags", "type": ["null", { "type": "array", "items": "string" }], "default": null }
]
}

Schemas in this format can be registered as reusable Library entries and referenced by name from the Enforce Schema and Check Schema processors, or supplied inline.

Metadata Keys (in meta)

KeyDescriptionExample Value
avro.schemaJSON-encoded schemaJSON string defining the schema
avro.codecCompression codec used (optional)"null" (default), "deflate", "snappy", "bzip2", "xz", "zstandard"

Compression Codecs

Required Codecs

CodecDescriptionBest For
nullNo compression appliedSmall files or testing
deflateStandard ZIP compression (RFC 1951)General-purpose compression

Optional Codecs

CodecDescriptionBest For
snappyFast compression/decompression with CRC32 checksumReal-time streaming applications
bzip2High compression ratioStorage-constrained environments
xzXZ compression libraryMaximum compression efficiency
zstandardFacebook's Zstandard compression with configurable levelsBest balance of speed and compression ratio