YaFF: a zero-copy wire format for Protobuf schemas
YaFF is a high-performance C++ serialization library that provides a zero-copy wire format for the Protobuf ecosystem.
At a glance
- What is it?
- YaFF keeps your .proto files as the single source of truth but changes how the data is laid out in memory, so a server that reads fields pays no parsing cost, and less performance-sensitive code can still parse the same bytes back into ordinary Protobuf messages.
- Who is it for?
- YaFF fits a team that has Protobuf schemas already and a hot path where parsing shows up in profiles, since YaFF keeps the schema and changes only the physical representation, and it fits anyone who wants to adopt it one service at a time because the interface emulates the standard proto one.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The idea: keep the schema, change the bytes
YaFF, short for Yet another Flat Format, is a high-performance C++ serialization library that provides a zero-copy wire format for the Protobuf ecosystem. The way it frames the problem is precise. While the .proto schema remains your single source of truth, YaFF changes the physical representation of data to eliminate runtime overhead, which gives performance-critical applications direct, zero-parsing access through a proto-like interface while allowing less performance-sensitive components to parse the wire format back into Protobuf messages. That last clause is the part that makes it an engineering choice rather than a format war, because it means a service can have a fast path and a slow path over the same bytes. The documentation lives at yaff.tech/docs, the licence is Apache 2.0, the last push to the repository was on 2026-10-14, and the single release so far is v0.1.0 from 2026-06-16.
How it relates to FlatBuffers and where it goes differently
YaFF shares the zero-copy foundations of FlatBuffers, but the readme is specific about the difference in emphasis. It concentrates on server-side runtimes and adaptive layout strategies that bring read performance close to native C++ structs, while preserving interoperability with Protobuf. So the borrowing is of the general idea of a flat, mmap-friendly layout that can be read in place without deserialising, and the divergence is in the target workload and the schema ecosystem. FlatBuffers asks you to move to its own schema and its own generated accessors, while YaFF asks you to keep the .proto file you already have. That difference is the whole pitch for anyone with an existing Protobuf estate, and it also explains why the project describes itself as Protobuf native, using existing .proto files and respecting Protobuf semantics.
The quick start, and what it feels like to use
The claim that working with YaFF feels close to Protobuf is meant literally, because the interface is proto-like rather than unfamiliar. The pattern is a serialize step followed by a read step, with no parsing step in between.
// Turn a Protobuf message into a zero-copy YaFF representation...
const auto buffer = yaff::Serialize<protoyaff::feed::FeedResponse>(proto);
// ...then access fields instantly with zero parsing overhead
const auto& response = yaff::ReadMessage<protoyaff::feed::FeedResponse>(buffer.Data());
std::string_view authorName = response.items(0).author().name();Two things are worth pulling out of those few lines. The first is that the buffer is produced from an existing Protobuf message, so the writer side keeps using the type you already have. The second is that the read side returns a view over the buffer rather than a new object, and the field access looks like chained accessors, here items(0).author().name(), which is the FlatBuffers style of reaching into a nested structure without copying. The result is a string_view rather than a std::string, which is the point, because no allocation happened to hand you those characters. The full walkthrough is in the Quick Start guide in the documentation.
Adaptive layouts, the part that is genuinely unusual
The feature list calls out adaptive layouts, described as allowing explicit configuration or runtime adjustment to manage the tradeoffs between speed, memory overhead and schema flexibility. The roadmap section explains why that is possible, and the explanation is the most interesting design statement in the repository. YaFF's core design decouples schema definitions from the underlying physical memory layout, and that separation allows the exact same data structures to support multiple runtime representations, enabling optimization for specific access patterns without changing the source schema. In other words, a layout is a runtime choice rather than a property of your schema, so a service can pick a layout that favours the access pattern of one hot path and a different one for a bulk scan, while both read the same .proto definition. The trade-off being managed is explicit, and it is speed against memory overhead against schema flexibility.
Incremental adoption, and the two-way conversion
The fourth feature is the one that decides whether anyone tries this. Incremental adoption is described as emulating standard proto interfaces and providing two-way message conversion for easy module-by-module integration. That combination is the practical answer to the usual objection about a new serialization library, which is that adopting it means rewriting everything at once. Here you can put a YaFF-backed implementation behind an interface that already looks like the Protobuf one, and where you need the old behaviour you convert back. The rest of the feature list is short. Zero-copy speed eliminates parsing entirely with mmap-compatible layouts, and mmap compatibility is worth dwelling on for a second, because it means the buffer can be backed by a file mapping rather than a heap allocation, which is the case where the zero-copy property pays off most, since there is no copy between the page cache and your data structure.
Integrating it, and the three CMake targets
YaFF can be added to a project in two ways. With CMake you build and install YaFF and then use find_package, and with Conan you build YaFF into the local Conan cache and then declare it as a dependency. Both methods expose the same set of CMake targets and the same yaff_generate() helper function, which is the kind of symmetry that saves you a migration when the packaging policy changes. The targets are listed with a type and a note on when to use them. yaff::core is an INTERFACE library, always needed, providing all the runtime headers under include/yaff. yaff::proto is a STATIC library, for when you are reading or writing Protobuf-backed YaFF messages. yaff::protoc_plugin is an executable used internally by yaff_generate() and not linked by consumers. Most applications only need yaff::core and yaff::proto, and the step-by-step instructions are in the integration document.
What is planned, and what the repository looks like
YaFF is under active development, and three items are named as planned or in progress. Columnar layout is a compact representation for large repeated fields, optimized for analytics and ML pipelines, which is a natural fit for a layout system that can change representation without changing the schema. Automated adaptivity is layout selection driven automatically by data analysis or through profile-guided modes, which is the natural conclusion of having layouts as a runtime decision. Multi-language bindings would extend the zero-copy data access to languages beyond C++. The repository shows the same structure. There are include/ and src/ for the library, tests/ and test_package/ for the test suites and the package test, benchmarks/ for the performance work, examples/ with a feed_api and a trading example alongside doc_views, cmake/ for the build logic, and a conanfile.py for the Conan route. Contributions are welcome, with the contributor's guide explaining how to report issues and submit pull requests, and there is a Telegram channel in English and Russian.
Editorial conclusion
YaFF fits a team that has Protobuf schemas already and a hot path where parsing shows up in profiles, since YaFF keeps the schema and changes only the physical representation, and it fits anyone who wants to adopt it one service at a time because the interface emulates the standard proto one. It does not fit a project that needs a stable release to pin, because the only tag is v0.1.0 from June 2026 and the project is under active development with three large features still planned. It also does not fit a team outside C++, because multi-language bindings are on the roadmap rather than in the release. Before you adopt it, read the Quick Start and the integration guide, decide between CMake and Conan, and note that most applications need only two of the three CMake targets, yaff::core and yaff::proto.
Frequently asked questions
What is YaFF and what problem does it solve?
YaFF, short for Yet another Flat Format, is a high-performance C++ serialization library that provides a zero-copy wire format for the Protobuf ecosystem. It keeps your .proto schema as the single source of truth but changes the physical representation of data so that reading fields involves no parsing step, while less performance-sensitive components can still parse the format back into Protobuf messages.
How is YaFF different from FlatBuffers?
YaFF shares the zero-copy foundations of FlatBuffers but concentrates on server-side runtimes and adaptive layout strategies that bring read performance close to native C++ structs, while preserving interoperability with Protobuf. You keep your existing .proto files rather than moving to a different schema.
What are adaptive layouts in YaFF?
They let you choose or adjust the physical representation at runtime to manage the tradeoffs between speed, memory overhead and schema flexibility. The core design decouples schema definitions from the underlying physical memory layout, so the same data structures support multiple runtime representations and can be optimized for specific access patterns without changing the source schema.
How do I integrate YaFF into a C++ project?
Two routes are supported. With CMake you build and install YaFF and then use find_package, and with Conan you build YaFF into the local Conan cache and declare it as a dependency. Both expose the same CMake targets, yaff::core for the runtime headers, yaff::proto for Protobuf-backed messages and yaff::protoc_plugin which is used internally, plus the yaff_generate() helper function.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yandex-yaff)Was this useful?