The most common question about kladde is how it relates to serde. The short answer: they solve different problems and compose badly, and if you are choosing between them you are probably choosing between “exchange” and “storage.”

The core difference

Serde serializes a value. You call to_vec(&value), you get bytes, you write them somewhere. The cost is proportional to the size of the whole value, every time.

Kladde stores a structure and records changes to it. You mutate it, and the cost is proportional to the size of the change.

For a 100 MB structure with a one-field edit:

serdekladde
cost of one small editrewrite 100 MBappend tens of bytes
cost of a readfree (already in memory)free (already in memory)
cost of openingparse 100 MBread the compact form, replay the journal
crash mid-editlose everything since the last writelose nothing acknowledged

The interesting column is the first one, and it is the whole reason kladde exists.

What serde does better

Interchange. Serde targets many formats — JSON, MessagePack, CBOR, YAML — and other systems can read them. A kladde file is a heap with an embedded schema. Another kladde implementation can read it; nothing else can.

Type coverage. Serde works on essentially any Rust type, including String, Vec<T>, HashMap, and third-party types with derives. Kladde needs its own container types.

Maturity. Serde is one of the most-used crates in the ecosystem. Kladde is early.

Zero setup. #[derive(Serialize)] and you are done. Kladde asks you to restructure your types around durable containers.

What kladde does better

Incremental durability. The one thing serde structurally cannot do. There is no serde-based design where a small edit to a large structure costs less than rewriting the structure, short of building an incremental format yourself — which is what kladde is.

Crash safety with no explicit save. With serde you choose when to write, and everything since the last write is at risk. With kladde, a mutation that has returned is durable.

In-place mutation of stored data. A kladde file is randomly addressable and mutable. A serde document is a byte stream you rewrite.

Language-independent tooling. A kladde file carries its own schema, so a generic tool can inspect and even compact it. A postcard blob is opaque without the writing program.

They are not exclusive

PersistableBlob<T> wraps any serde type as an opaque payload inside a kladde structure.

This is the right escape hatch for a foreign type you cannot change, and the wrong default for anything else: a blob is rewritten in full on every change, so it forfeits exactly the property you came for. Use it at the leaves, for things that change rarely.

Choosing

Use serde when the data leaves your process: config files people edit, API payloads, anything another program reads.

Use kladde when the data is your application’s state: it lives across runs, it is large relative to each change, and losing it to a crash is unacceptable.

Use both when your state is mostly kladde-shaped but contains a few foreign leaves.

An honest caveat

Serde is a safe default and kladde is not yet. If your structure is small enough that rewriting it is cheap — under a few megabytes, say, edited a few times a second — serde is simpler, better tested, and fast enough. Kladde starts winning when rewriting starts hurting.