도구스개발

프로토콜 버퍼 와이어 포맷 계산기

필드 번호와 타입에서 태그 바이트((필드번호 << 3) | 와이어타입)를 구하고 메시지 하나의 실제 바이트 수를 필드별로 쌓아 보여 줍니다. 필드 번호 16부터 태그가 2바이트가 되는 것과, 중첩 메시지의 길이 접두가 어떻게 붙는지를 숫자로 확인할 수 있습니다.

한 줄에 하나씩 「이름: 번호 타입 값」입니다. 값은 스칼라면 숫자, 문자열·바이트·중첩 메시지면 페이로드 바이트 수입니다. 뒤에 ×3처럼 반복 횟수를 적을 수 있습니다.

쓸 수 있는 타입: int32 · int64 · uint32 · uint64 · sint32 · sint64 · bool · enum · fixed32 · fixed64 · float · double · string · bytes · message

메시지 크기 (필드 5개)

45바이트

태그가 10바이트, 길이 접두가 4바이트, 내용이 31바이트입니다. 이 메시지를 남의 중첩 필드로 담으면 2바이트가 더 붙습니다.

필드별로 뜯어보면

필드번호와이어태그태그 B길이 B내용 B합계
id10 VARINT08123
name22 LEN1211810
score31 I6419189
active40 VARINT20112
tag ×3162 LEN82 0121421

태그는 (필드번호 << 3) | 와이어타입을 varint로 적은 것입니다. 16진으로 보인 값이 실제로 바이트열의 맨 앞에 놓입니다.

태그가 차지하는 몫10바이트
길이 접두가 차지하는 몫4바이트
내용31바이트
합계45바이트
군더더기 비율31.1%
중첩 필드로 담을 때 더 붙는 바이트2바이트 (태그 + 길이 접두)

필드 번호와 태그 크기

태그 바이트필드 번호 범위
1바이트1 ~ 15
2바이트16 ~ 2,047
3바이트2,048 ~ 262,143
4바이트262,144 ~ 33,554,431
5바이트33,554,432 ~ 536,870,911

19000~19999는 프로토버프 내부용으로 예약되어 쓸 수 없고, 최대 필드 번호는 536,870,911(2²⁹−1)입니다.

필드 번호 16부터 태그가 2바이트가 됩니다. 태그가 varint라 127 이하면 1바이트인데, 와이어타입이 아래 3비트를 먹으니 필드 번호가 15까지여야 태그가 127 안에 들어옵니다. 「자주 쓰는 필드에 1~15를 배정하라」는 권고의 근거가 이것이며, 필드가 백만 번 반복되면 1바이트 차이가 1MB 차이가 됩니다.
중첩 메시지는 크기를 두 번 훑습니다. 문자열·바이트열·중첩 메시지는 값 앞에 길이를 varint로 적는데, 중첩 메시지의 길이는 안쪽을 다 만들어 봐야 알 수 있고 길이 접두 자체의 바이트 수도 길이에 따라 달라집니다. 그래서 직렬화기는 안쪽부터 크기를 재고 그 크기로 다시 쓰는 두 번 훑기를 합니다.
varint 자체는 따로 다룹니다. 7비트씩 잘라 담는 방식과 음수를 짧게 만드는 지그재그 부호화는 varint 계산기 쪽을 보세요. 여기서는 그것을 전제로 「태그를 어떻게 만들고 길이 접두와 중첩이 어떻게 붙는가」만 셉니다. 다만 크기 계산에는 varint가 그대로 쓰이므로, int64 음수가 언제나 10바이트인 것과 sint64가 짧은 것은 위 표에 반영되어 있습니다.
필드 이름은 바이트열에 없습니다. 태그에 들어가는 것은 번호와 와이어타입뿐이라 JSON보다 훨씬 작습니다. 대신 .proto 파일 없이는 값의 의미를 알 수 없고, 와이어타입만으로는 int32인지 bool인지도 구별되지 않습니다. 바이트열만 보고 되살리면 「타입은 모르지만 구조는 보이는」 상태가 됩니다.
필드 번호는 절대 바꾸지 마세요. 번호가 곧 식별자이므로 번호를 바꾸면 옛 데이터가 다른 필드로 읽힙니다. 필드를 지울 때도 번호를 reserved로 막아 두어야 나중에 그 번호를 재사용하는 사고를 막을 수 있습니다. 이름은 바꿔도 와이어 포맷에는 영향이 없습니다.
여기서 세는 것은 이상적인 크기입니다. 기본값과 같은 필드는 proto3에서 아예 나가지 않으므로 실제 메시지는 이보다 작을 수 있고, 반복되는 스칼라 필드를 packed로 묶으면 태그가 한 번만 붙어 더 줄어듭니다. 반대로 문자열 길이는 UTF-8 바이트 수라 한글 한 글자가 3바이트라는 점도 함께 봐야 합니다.

사용 방법

  1. 1한 줄에 한 필드씩 「이름: 번호 타입 값」을 넣습니다.
  2. 2스칼라 타입은 값을, 문자열·바이트·중첩 메시지는 페이로드 바이트 수를 넣습니다.
  3. 3반복 필드는 값 뒤에 ×3처럼 횟수를 적습니다.
  4. 4필드별 태그 바이트와 길이 접두, 내용 바이트를 확인합니다.
  5. 5자주 나오는 필드의 번호를 16 이상에서 15 이하로 옮겨 보고 크기가 얼마나 줄어드는지 봅니다.

자주 묻는 질문

(필드번호 << 3) | 와이어타입을 varint로 적습니다. 아래 3비트가 와이어타입이고 그 위가 필드 번호입니다. 필드 1의 varint 타입이면 태그가 0x08, 필드 2의 LEN 타입이면 0x12입니다.

태그가 varint라 127 이하면 1바이트인데, 와이어타입이 아래 3비트를 먹으니 필드 번호가 15까지여야 태그가 127 안에 들어오기 때문입니다. 16부터는 태그가 2바이트가 되며, 필드가 백만 번 반복되면 1바이트 차이가 1MB 차이가 됩니다.

0 VARINT(int·bool·enum), 1 I64(fixed64·double), 2 LEN(string·bytes·중첩 메시지), 5 I32(fixed32·float) 네 가지를 씁니다. 3 SGROUP과 4 EGROUP은 폐기되었습니다. 와이어타입만으로는 int32인지 bool인지 구별되지 않습니다.

길이를 값 앞에 적어야 하는데 그 길이를 안쪽을 다 만들어 봐야 알 수 있기 때문입니다. 게다가 길이 접두 자체의 바이트 수도 길이에 따라 달라집니다. 그래서 직렬화기는 안쪽부터 크기를 재고 그 크기로 다시 쓰는 두 번 훑기를 합니다.

2의 보수로 64비트를 채워 담기 때문입니다. −1은 비트가 전부 1이라 varint로 10바이트가 됩니다. 음수가 자주 나오는 필드라면 지그재그를 거치는 sint32·sint64를 쓰면 −1이 1바이트로 담깁니다.

536,870,911(2²⁹−1)입니다. 태그가 varint 5바이트까지 들어가기 때문입니다. 19,000~19,999는 프로토버프 내부용으로 예약되어 쓸 수 없습니다.

있습니다. proto3에서는 기본값과 같은 필드가 아예 나가지 않고, 반복되는 스칼라 필드를 packed로 묶으면 태그가 한 번만 붙습니다. 반대로 문자열 길이는 UTF-8 바이트 수라 한글 한 글자가 3바이트라는 점도 함께 봐야 합니다.

전송되지 않습니다. 계산은 모두 브라우저 안에서 이루어지고 넣은 값은 이 기기에만 남습니다.

알아두면 좋은 점

  • varint의 7비트 분할과 지그재그 부호화 자체는 varint 계산기에서 다룹니다. 이 도구는 태그·길이 접두·중첩만 봅니다.
  • proto3의 기본값 생략과 packed 반복은 반영하지 않은 이상적인 크기입니다. 실제 메시지는 더 작을 수 있습니다.
  • 중첩 메시지의 안쪽 필드는 페이로드 바이트 수로 한 번에 넣습니다. 안쪽을 따로 계산해 그 값을 넣으세요.
  • 문자열 길이는 UTF-8 바이트 수입니다. 한글 한 글자는 3바이트입니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.