Lập trình 22/09/2026 6 phút

Protobuf wire format: mổ từng byte để hiểu vì sao nó gọn hơn JSON

Protobuf gọn hơn JSON nhiều — nhưng vì sao? Bài này mổ xẻ wire format tới từng byte: mỗi field là một tag ghép field number với wire type, số nén bằng varint 7 bit. Dùng gói protowire của Go (không cần protoc) để tự mã hóa một sản phẩm, in ra 20 byte hex và giải thích từng byte là gì, rồi giải mã lại chứng minh. Cùng dữ liệu, JSON tốn 58 byte còn Protobuf chỉ 20.

Lập trình 22/09/2026 6 phút

Protobuf wire format mổ đến từng byte: vì sao nó nhỏ hơn JSON 3,5 lần và message rỗng tốn 0 byte

Protobuf nhỏ hơn JSON không phải nhờ phép màu — mà nhờ ba quyết định thiết kế gọn gàng. Bài này dùng proto.Marshal rồi hexdump từng byte trong go-lab để giải mã: mỗi field là một tag (field_number dịch bit cộng wire_type) rồi tới value, số nguyên mã hoá bằng varint (số nhỏ chỉ 1 byte), và field mang giá trị mặc định không được ghi lên dây chút nào. Kết quả thật: cùng dữ liệu, JSON 46 byte còn Protobuf 13 byte, message rỗng tốn 0 byte.

Lập trình 22/09/2026 7 phút

Protobuf wire format: giải mã từng byte để hiểu vì sao nó gọn và field number là hợp đồng

Bài trước đo được protobuf gọn hơn JSON 63% nhưng chưa nói vì sao. Bài này mổ xẻ từng byte: serialize {id:1001, name:abc, big:7} ra 11 byte rồi giải mã thủ công — 08 là tag field 1, e907 là varint 1001, a001 là tag field 20 tốn 2 byte. Đo thật varint co giãn theo giá trị (id 5 tốn 2 byte, id 10 tỷ tốn 6 byte), và vì sao wire chỉ chứa số field nên đổi tên không phá nhưng đổi field number thì phá.