Why do methods 2 and 3 exist at all? I don't understand the reason for the overlap between them. I would expect there to exist only one automatic (deriving) method of serialization and one manual.

Method 2 (the ToJson trait) is specific to encoding JSON. It returns JSON objects, instead of writing to a stream. One example of use is for mapping to custom representations - see this example in the documentation.

Method 3 (implementing Encodable ) has to exist for method 1 to work.

Am I right in assuming that method 2 will build a Json enum in memory (besides the struct itself) and is a worse fit for huge documents (multi megabytes), while method 3 is streaming and safer for huge documents?

Yes. ToJson creates a nested Json enum of the whole object, while Encodable streams to a Writer .

If I want manual serialization, which method should I choose and why? Why does rust stdlib use method 3 even for primitives, while not using method 2 internally?