🥊JSON vs Protobuf Size Comparator

Size both formats field by field with the real wire rules

No.TypeWireTagValueProtobufJSON
varint valueBytes it takes

Protobuf bytes follow the wire rule that one field is a tag (field number << 3 | wire type, as a varint) plus its value. A varint grows by one byte every 7 bits, and string or bytes fields are tag plus length varint plus content. Negative int32 and int64 values sign-extend to 64 bits and cost 10 bytes, which is why the sint types pay off when negatives are common. The JSON side counts the real UTF-8 length of the minified document.

You Might Also Need

How to use this JSON vs Protobuf size comparator

List one field per line with its number, type, JSON key and value, and the page sizes both formats field by field. Columns split on commas or tabs, and anything after the third comma counts as the value, so values containing commas are safe. Nothing is estimated.

How it is calculated

Protobuf counts one field as a tag plus a value, where the tag is the field number shifted left by three bits with the wire type added, written as a varint. A varint takes 1 byte for 0 to 127, 2 bytes for 128 to 16,383, 3 bytes for 16,384 to 2,097,151, and one more byte every 7 bits after that. The fixed32 family costs 4 bytes and fixed64 costs 8. The JSON side counts the UTF-8 length of the minified document. Figures follow the Protocol Buffers encoding specification as of October 2026.

Limits and cautions

Nested messages, repeated fields, packed arrays and maps are out of scope; only flat fields are counted. The proto3 behaviour of omitting fields equal to their default is not modelled either. Applying transport compression shrinks the JSON side sharply and narrows the gap.

Frequently asked questions

Why is Protobuf smaller?

It never sends field names. JSON ships the key, its quotes, a colon and a comma with every field, while Protobuf writes only a field number in one or two bytes. That is exactly why the receiving side must hold the schema; the bytes alone cannot be interpreted.

What is the average saving?

There is no meaningful average. Payloads full of small integers shrink a lot, while payloads of long strings come out nearly identical, because both formats carry string contents verbatim. This page therefore reports no rule-of-thumb percentage and sizes each field instead.

Which type should hold negative numbers?

sint32 or sint64. A negative value in int32 or int64 sign-extends to 64 bits and costs 10 bytes on its own. The sint types use zigzag encoding, which keeps small negative numbers in few bytes.