Protobuf
Google's binary serialisation format with schema-driven code generation.
What it is
Protocol Buffers (Protobuf) is a language-neutral, platform-neutral, and extensible mechanism for serializing structured data. In C++, it allows defining message schemas and efficiently serializing/deserializing structured data for inter-process communication, data storage, and network protocols.
In C++, Protobuf uses generated classes from `.proto` files. You can serialize messages to binary strings or streams, parse messages from them, and use features like nested messages, enums, repeated fields, and optional fields for efficient and structured data representation.
- Licence
- BSD 3-clause
- Watch for
- Never reuse a field number — that is what preserves compatibility
When to use it
The question documentation cannot answer for you — because it cannot recommend something else.
Reach for it when
- Service-to-service communication where payload size and parse speed matter
- You need a schema that multiple languages share, with forward and backward compatibility
Look elsewhere when
- Humans need to read the payload — JSON is far better for debugging and public APIs
- You want zero-copy access to large messages, where FlatBuffers or Cap'n Proto win
Installation
sudo apt install protobuf-compiler libprotobuf-devGetting started
The smallest useful thing you can do with it, and what each part means.
// person.proto
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
}# Terminal command
protoc --cpp_out=. person.proto#include "person.pb.h"
#include <fstream>
int main() {
Person p;
p.set_name("Alice");
p.set_id(123);
p.set_email("alice@example.com");
std::ofstream out("person.bin", std::ios::binary);
p.SerializeToOstream(&out);
return 0;
}#include "person.pb.h"
#include <fstream>
#include <iostream>
int main() {
Person p;
std::ifstream in("person.bin", std::ios::binary);
if (p.ParseFromIstream(&in)) {
std::cout << p.name() << ", " << p.id() << ", " << p.email() << std::endl;
}
return 0;
}Advanced usage
Where the library earns its place over a simpler alternative.
message Address {
string street = 1;
string city = 2;
}
message Person {
string name = 1;
Address address = 2;
}message Person {
string name = 1;
repeated string phone_numbers = 2;
}enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}// In .proto file
service PersonService {
rpc GetPerson(PersonRequest) returns (PersonResponse);
}
// Use protoc with gRPC plugin to generate C++ server/client stubsErrors and fixes
The failures you are most likely to hit, and what actually resolves them.
- ParseError
- Occurs when deserializing invalid or corrupted data. Ensure serialized data matches the expected message type.
- Type mismatch
- Assign correct data types to each field as defined in the `.proto` file.
Best practices
- Always assign unique tag numbers and never reuse deleted ones to maintain backward compatibility.
- Use `proto3` syntax for simplicity and default values.
- Keep messages concise for efficient serialization.
- Use nested messages and enums to organize complex structures.
- Validate data before serialization and after deserialization when needed.
Alternatives
Comparable options, and the reason you would pick one over the other.
Background
Why it exists, and what it was reacting to.
Protobuf was developed by Google to offer a compact and fast alternative to XML and JSON for data serialization. Developers write `.proto` files to define message structures, then generate C++ classes to handle serialization, deserialization, and validation, making it widely used in gRPC, distributed systems, and file storage.
