Compare ProtoBuf and CBOR in kotlinx.serialization: wire format, size, and when to choose each.
answer
- ProtoBuf: numbers only, smallest, schema-bound
- CBOR: keys inline, self-describing, RFC 8949
- CBOR underpins COSE/WebAuthn, IoT
- Own both ends → ProtoBuf; interop/self-describe → CBOR
- Both experimental, both ByteArray, separate artifacts
basics
~20 sProtoBuf stores only field numbers and values, so it is very compact but both sides need the same schema. CBOR also stores the keys, so it is a bit bigger but more self-describing, like a binary JSON.
solid answer
~40 sBoth are binary kotlinx formats reusing `@Serializable`. ProtoBuf encodes fields by **number** only (no names on the wire), giving the smallest payloads and fastest parsing, but it is schema-dependent — decoder and encoder must agree on numbers (`@ProtoNumber`). It is ideal for high-throughput RPC, mobile, and storage where you own both ends. CBOR (RFC 8949) is **self-describing**: it encodes keys/types inline, much like a binary JSON, so a generic decoder can read it without the schema; it is the basis of COSE/WebAuthn and common in IoT. The cost is larger payloads than ProtoBuf. Choose ProtoBuf for size/speed and controlled schemas; choose CBOR for interop with CBOR-based standards or when self-description matters. Both are `@ExperimentalSerializationApi` and live in separate artifacts (`-protobuf`, `-cbor`).
go deeper
Knows both are binary and reuse @Serializable; CBOR is like binary JSON.
Contrasts number-only ProtoBuf vs key-carrying CBOR and the size implication.
Gives a clear decision guide tied to schema control, interop (COSE/WebAuthn), and the experimental caveats.
Weighs ecosystem standards, cross-language interop, versioning governance, and risk of an experimental API for a long-lived system.
## Same model, two binary formats Both `ProtoBuf` and `Cbor` are kotlinx **format** objects that consume the compiler-generated serializer of a `@Serializable` class and emit a `ByteArray`. You swap one for the other without touching the model. ## ProtoBuf — schema-bound, smallest - Wire data = `(field_number, value)` pairs; **names are not stored**. - Identity comes from `@ProtoNumber`; the decoder must know the same numbers. - Uses compact encodings (e.g. varints for integers), so payloads are typically the smallest of the three formats. - Strength: throughput, bandwidth, storage. Weakness: you must control/version the schema on both ends. ```kotlin val bytes = ProtoBuf.encodeToByteArray(User(1, "Ada")) ``` ## CBOR — self-describing, interoperable - **Concise Binary Object Representation**, IETF **RFC 8949**. - Encodes keys and type/major-type information inline — think "binary JSON". A generic CBOR reader can walk the structure without your Kotlin classes. - Underpins **COSE** (CBOR Object Signing and Encryption) and **WebAuthn/FIDO2**, and is popular in constrained/IoT environments. - Larger than ProtoBuf because the keys travel with the data, but smaller and faster than text JSON. ```kotlin val bytes = Cbor.encodeToByteArray(User(1, "Ada")) ``` ## Decision guide - **Smallest/fastest, you own both ends** → ProtoBuf. - **Need self-description or must interop with CBOR/COSE/WebAuthn** → CBOR. - **Human-debuggable / browser-native** → JSON (neither binary format). ## Shared caveats - Separate Gradle artifacts: `kotlinx-serialization-protobuf`, `kotlinx-serialization-cbor` (add `-json` separately). - Both encode to `ByteArray` (`encodeToByteArray` / `decodeFromByteArray`), not String. - Both are `@ExperimentalSerializationApi`: opt-in required, API may shift, so pin versions and isolate behind your own boundary if used in production.
- Which format would you pick for a WebAuthn/FIDO2 integration and why?CBOR — the WebAuthn/COSE standards are defined in terms of CBOR, so using it gives direct interop without a translation layer.
- Why is ProtoBuf usually smaller than CBOR?ProtoBuf omits field names entirely (only numeric tags travel) and uses varint encoding, whereas CBOR carries keys inline for self-description.
ProtoBuf ships parts in numbered boxes with no labels (tiny, but you need the manifest); CBOR labels every box (bigger, but anyone can unpack it).
saying these in an interview costs you the question
- Says CBOR omits keys like ProtoBuf does
- Claims ProtoBuf is self-describing without a schema
- Recommends ProtoBuf for an open/interop CBOR standard like COSE
- Thinks one artifact provides both formats
- Ignores the experimental status when proposing production use