Favicon of FlatBuffers

FlatBuffers

FlatBuffers is Google's Apache-2.0 cross-platform serialization library, built for performance-critical code: data is accessed directly in the serialized buffer without unpacking, the only memory needed is the buffer itself, and schemas evolve with forwards and backwards compatibility.

LicenseOpen source (permissive)· Apache-2.0
DeploymentSelf-hostedManaged
PricingFree
Operational complexityLow
WorkloadInteractive
LanguageC++, Java, Go, Rust, TypeScript

Use it when

  • The reader has no memory budget: games, mobile, and embedded clients access fields directly in the buffer, with no heap beyond the buffer itself.
  • You are building a format or system whose metadata must be readable without full deserialization; Arrow IPC, TensorFlow Lite, and the Nimble and Vortex footers all chose it for exactly that.
  • Fields come and go: vtables make absent fields free and defaults unwritten, with evolution against old buffers in both directions.
  • Language reach matters for a zero-copy format: flatc generates for fifteen languages.

Think twice when

  • A schema registry governs the platform; no Kafka registry accepts FlatBuffers.
  • Every field read pays a vtable indirection; Cap'n Proto computes offsets instead, which is the sharper choice when tables never omit fields.
  • Discipline is thin: fields must only ever be appended and never removed, reordering breaks readers without explicit ids, and changing a default is a silent break.
  • You want a formal, versioned specification; stability is a property of the design, written down nowhere, and releases are date-stamped.

How it runs

flatc compiles schemas into accessor code; a Verifier walks untrusted buffers before use, bounded by table count and depth. The same compiler converts to and from JSON and checks evolution with --conform. FlexBuffers, shipped alongside, drops the schema entirely for the cases where self-description is worth the bulk.

Details

Compare

How FlatBuffers answers the questions Serialization Formats turns on.

Serialization Formats
How it works
EncodingA vtable per table, which is the one structural idea separating this row from Cap'n Proto. Values sit little-endian and self-aligned in the buffer, reached through 32-bit unsigned offsets (deliberately 32-bit so a buffer means the same thing on 32- and 64-bit machines) while each table is preceded by a signed offset to a vtable listing where each of its fields lives. Fields that are absent hold a zero in the vtable and cost nothing, and defaults are never written at all. Structs are the other half of the design: fixed layout, no vtable, stored inline, for the cases where the flexibility is not worth the indirection. Strings are length-prefixed and also NUL-terminated, vectors carry a 32-bit count, and nesting vectors directly is not supported
Random accessThe other design that removes the parse step, and worth reading against Cap'n Proto rather than beside it. Both hand back a live view of a mapped buffer with no decoding, allocation or copying; the difference is how a field is found. Cap'n Proto computes the position from the schema, so the read is arithmetic. FlatBuffers reads the vtable first and then the value, so every field costs one extra indirection, the price of letting fields be absent. Reading untrusted bytes as a live object graph creates the same problem it does for Cap'n Proto, and the answer here is an explicit Verifier that walks a buffer before use, bounded by a maximum table count and a depth limit that defaults to 64
Self-describingNot at all, and then also yes, because the project ships two formats. A FlatBuffer carries no field names and no types, the vtable gives positions, the schema gives meaning, and without the .fbs file the bytes are unreadable. Alongside it the same project ships FlexBuffers, which is schema-less and encodes keys and type information into the buffer itself, so it can be read with nothing but the library, and which can be embedded inside a FlatBuffer field through the flexbuffer attribute. The trade is stated plainly in the documentation: no schema needed, still no parsing, but bulkier, slower, no strong typing, and map lookups become binary searches
Schema evolutionAppend-only by rule, and the documentation is imperative about it: new fields "MUST be added to the end of the table definition", and you "MUST not remove a field from the schema, even if you don't use it anymore", retire it with the deprecated attribute instead, which stops the generator emitting accessors while leaving the slot occupied. Because position comes from the vtable slot, reordering silently breaks readers unless every field carries an explicit id attribute, which is the documented escape from the ordering rule. Changing a default is a compatibility break in disguise, since old data relies on the generated one. flatc --conform checks a new schema against an old one, which is the closest thing in this capability to a registry's compatibility check run locally
Type systemScalars from bool and byte through 64-bit integers and doubles, string, vector, enum, union, and the two composite forms the design turns on (table, where fields are optional and evolvable, and struct, where the layout is fixed and everything is present. There is no map type: the idiom is a vector of tables with a key attribute on one field, which flatc keeps sorted so lookups are binary searches. Attributes carry the rest of the semantics) required to force presence, deprecated to retire a slot, id for explicit numbering, force_align for alignment-sensitive data, bit_flags for enum sets, and nested_flatbuffer or flexbuffer for embedded buffers
RPCDeclared but thin, which is a third position beside Thrift's full framework and Avro's unused specification. The schema language has rpc_service declarations defining calls that take and return FlatBuffers, and the project describes what is built on them exactly once and without ambition: "there is preliminary support for GRPC through the --grpc code generator". So the definitions exist in the IDL and the transport comes from gRPC rather than from FlatBuffers, where Thrift ships protocols, transports and servers of its own and Cap'n Proto builds an entire capability system into the format
Spec versionsStable in practice, extended rather than revised, and nowhere written down (there is no versioned format specification and no stability policy to point at, which makes this the least formal answer in the capability. What exists instead is a property of the design: a vtable bounds check is what "protects against newer code reading older data", and the white paper is careful to scope that to tables, since "naked" structs "do not offer forwards/backwards compatibility" in exchange for being smaller. So how stable your data is depends on which construct you reached for. The extension worth naming is 64-bit offsets, added to lift the 32-bit ceiling on buffer size and landed for C++ first, which widens the format without disturbing anything already written. Releases are date-stamped rather than semantic) 25.12.19 is a date, so the version number says when, not what
Adoption and maturityThe most widely embedded format in this capability, and the evidence is what other formats are built out of. Arrow's IPC metadata is FlatBuffers, in the org.apache.arrow.flatbuf namespace; TensorFlow Lite model files are a FlatBuffers schema; and in this catalog's own file-format leaf both Nimble and Vortex chose it for their footers, with Parquet carrying an active proposal to do the same, Nimble's stated reason, "Flatbuffers instead of thrift/protobuf to more efficiently access large metadata sections", is this project's design goal quoted back by a user. About 26,300 stars and 3,600 forks, the largest in the capability, from a Google project written for game development and mobile. The qualification is cadence: commits continue, but the last tagged release dates to December 2025 with a re-tag in February 2026
Connections
Registry supportNone, the same as Cap'n Proto and Thrift. No registry in this catalog's schema-registry leaf accepts it (Confluent, Karapace and AWS Glue take Avro, JSON Schema and Protobuf, Buf takes Protobuf alone, Apicurio spends its nine artifact types elsewhere) so the Kafka-platform path is closed. The format's own answer to schema distribution is different in kind: schemas are compiled into both ends, and where they must travel, flatc can emit the schema itself as a binary FlatBuffer for reflection at runtime
Generated codeRequired, and the widest reach in this capability after Thrift's: flatc generates for fifteen languages (C, C++, C#, Dart, Go, Java, JavaScript, Kotlin, Lobster, Lua, PHP, Python, Rust, Swift and TypeScript) with the same compiler also converting between binary buffers and JSON, emitting binary schemas for reflection, and checking schema evolution through --conform. Feature coverage is not uniform across those targets, which is what the project's supported-configurations page exists to record. The escape from generation is FlexBuffers, which needs no schema and therefore no compiler at all

Share:

Alternatives to FlatBuffers

Favicon

 

  
  
Favicon

 

  
  
Favicon