Перейти к содержимому
Aback Tools Logo

MessagePack против JSON: размер, скорость и накладные расходы

MessagePack и JSON в сравнении: откуда берётся экономия размера 20-50 %, скорость сериализации по рантаймам, различия систем типов и когда компромисс оправдан.

DH
12 мин чтения2,750 слов

JSON - это лингва франка веб-API: читаемый, универсальный и поддерживаемый везде. MessagePack - это бинарный формат сериализации, созданный, чтобы передавать те же данные на 20-50 % меньшим числом байт и с более быстрым парсингом на обоих концах. Понимание того, откуда именно берётся эта экономия, чем вы платите и когда компромисс оправдан, отличает преждевременную оптимизацию от измеримого улучшения инфраструктуры.

20-50%Меньше минифицированного JSONТипичная экономия payload
2-4×Быстрее сериализацияпротив парсинга текстового JSON
< 1sВремя сравнения размераДля любого payload JSON

Что такое MessagePack?

MessagePack - бинарный формат сериализации, созданный Садаюки Фурухаси в 2008 году и опубликованный как открытая спецификация. Он кодирует те же типы данных, что и JSON - null, boolean, integer, float, string, array, map - но использует компактные бинарные представления вместо человекочитаемого текста. Булево `true`, занимающее 4 байта как текст JSON, занимает ровно 1 байт в MessagePack. Небольшое целое число вроде 42 занимает 3 байта в JSON и 1 байт в MessagePack.

Формат не требует схемы: как и JSON, он не нуждается в предопределённой схеме для кодирования или декодирования данных. Поэтому в большинстве контекстов API он служит прямой заменой JSON - вы меняете сериализатор, не меняя модель данных. MessagePack широко поддерживается: официальные и общественные библиотеки есть для Python, JavaScript, Go, Ruby, Java, C++, Rust и более чем 50 других языков.

Как работает кодирование MessagePack

  • Байт тега типа - каждое значение начинается с 1-байтового тега, который кодирует тип, а для небольших значений и само значение (fixint, fixstr, fixarray, fixmap).
  • Целые числа - небольшие целые (0-127) занимают ровно 1 байт. Большие целые используют 2, 4 или 8 байт в зависимости от величины и всегда меньше своего десятичного текстового представления.
  • Строки - кодируются как последовательность байт UTF-8 с префиксом длины. Короткие строки (≤31 символа) используют 1-байтовый заголовок, длинные - 2 или 4 байта.
  • Булевы значения и null - каждое занимает ровно 1 байт. В JSON `true` занимает 4 байта, `false` - 5 байт, `null` - 4 байта.
  • Массивы и map - с префиксом длины; небольшие массивы (≤15 элементов) добавляют 1 байт накладных расходов против скобок `[` `]` и запятых в JSON.

Note

MessagePack - не алгоритм сжатия: он не применяет ни LZ77, ни кодирование Хаффмана, ни какую-либо энтропийную компрессию. Экономия размера возникает целиком из-за использования компактных бинарных кодировок типов вместо текстовых символов. Сжатие gzip или Brotli поверх MessagePack даёт дополнительную экономию, но текстовый JSON часто существенно сокращает разрыв, потому что повторяющиеся имена ключей JSON сжимаются крайне эффективно.

Сравнение размера: насколько MessagePack меньше?

Сокращение размера при переходе на MessagePack полностью зависит от состава данных в вашем payload. Наибольший выигрыш получают payloads с множеством числовых полей, булевых значений и null. Payloads с преобладанием строк - длинные тексты, UUID, даты в формате ISO - выигрывают меньше, поскольку содержимое строки хранится как необработанные байты UTF-8 в обоих форматах.

Экономия возникает из-за информации о типах и структурных накладных расходов, а не из-за сжатия самих значений. Строка из 200 символов стоит примерно одинаково в обоих форматах.

- Обоснование спецификации MessagePack

Сравнение размера по типам данных

ЗначениеБайты JSON (минифицированный)Байты MessagePackЭкономия
true4175%
false5180%
null4175%
42 (целое)2150%
1000 (целое)4250%
"hello"7614%
"2026-06-11"12118%

Бенчмарки реальных payload

Типичный ответ REST API со смешанными типами данных - идентификаторы, имена, метки времени, флаги состояния и счётчики - становится на 20-35 % меньше. Payload из чисто числовых данных (показания датчиков, аналитические события) может дать сокращение 40-50 %. Payload из преимущественно длинных строк (тексты статей, сообщения логов) может дать всего 5-15 %. Инструмент Сравнение размера JSON и MessagePack на Aback Tools измеряет точную экономию в байтах для любого конкретного payload JSON - вставьте свой production-payload и узнайте фактический процент меньше чем за секунду.

Tip

Прежде чем решить внедрять MessagePack, измерьте экономию на своих реальных production-payloads, а не на синтетических бенчмарках. Payloads с длинными повторяющимися именами ключей - обычное дело в многословных API - прекрасно сжимаются gzip. Иногда сжатый gzip JSON меньше, чем несжатый MessagePack. Всегда сравнивайте gzip+JSON с gzip+MessagePack для честной оценки.

Сравнение размера JSON и MessagePack

Вставьте любой payload JSON и увидите его размер в байтах MessagePack, точный процент экономии, разбивку по типам и hex-превью - локально в браузере, без загрузки.

Open tool

Скорость сериализации: насколько MessagePack быстрее?

Сериализация и десериализация MessagePack в бенчмарках обычно в 2-4 раза быстрее стандартной обработки текстового JSON. Преимущество в скорости обеспечивается пропуском токенизации UTF-8: парсеры JSON вынуждены просматривать каждый байт в поисках структурных символов (скобок, кавычек, запятых, двоеточий), тогда как парсеры MessagePack читают тег типа и сразу переходят к следующей границе значения. Никакого сканирования кавычек, обработки escape-последовательностей и преобразования числовых строк в целые.

Производительность в разрезе языков

Разрыв в скорости сильно зависит от рантайма. В Python `msgpack` в 3-5 раз быстрее стандартного модуля `json` на типичных payloads. Однако `orjson` (библиотека JSON для Python на Rust) почти так же быстр, как `msgpack`, во многих сценариях - разрыв сокращается до 1,2-1,5 раза. В Node.js `@msgpack/msgpack` превосходит встроенный `JSON.parse` примерно в 2 раза. В Go разрыв ещё меньше, потому что стандартный `encoding/json` в Go уже достаточно быстр.

Где скорость важнее всего

Преимущество в скорости сериализации наиболее значимо во внутреннем обмене между микросервисами с высокой пропускной способностью, где сервисы обмениваются тысячами сообщений в секунду и сериализация даёт измеримые затраты CPU. Для обычного веб-API с несколькими сотнями запросов в секунду разница между временем сериализации JSON и MessagePack пренебрежимо мала по сравнению со временем запроса к базе данных или сетевой задержкой. Профилируйте реальное узкое место, прежде чем оптимизировать сериализацию.

Note

Во многих production-системах доминирующая статья затрат - не время сериализации, а время передачи payload. Переход с несжатого JSON на MessagePack сокращает время передачи пропорционально сокращению размера. Включение HTTP/2 и сжатия gzip в существующем JSON API часто даёт такую же или большую прибавку к пропускной способности без единой строки кода.

Различия систем типов MessagePack и JSON

MessagePack и JSON разделяют один и тот же базовый набор типов - null, boolean, number, string, array и object/map - но MessagePack богаче на числовом и бинарном уровнях. Эти различия важны при миграции существующего JSON API или проектировании нового протокола, поскольку некоторые типы MessagePack не имеют прямого эквивалента в JSON.

Типы, которые MessagePack добавляет к JSON

  • Беззнаковое 64-битное целое - в JSON вообще нет целочисленного типа (числа - это double IEEE 754, теряющие точность за пределами 2^53). MessagePack кодирует значения uint64 точно.
  • Бинарный массив байт - в MessagePack есть нативный тип bin для необработанных последовательностей байт. В JSON аналога нет - бинарные данные приходится кодировать в base64 как строку, добавляя около 33 % накладных расходов.
  • Типы расширений - зарезервированный механизм для типов, специфичных для приложения: меток времени (ext type 1), десятичных чисел и пользовательских тегированных данных. Позволяет обогащать семантику без схемы.
  • Float32 - MessagePack может кодировать 32-битные float (4 байта). JSON всегда использует 64-битное текстовое представление с двойной точностью, которое и больше, и теряет информацию о типе f32.

Проблема кругового преобразования типов

Критическая ловушка при миграции с JSON на MessagePack: в JSON только один числовой тип (double IEEE 754), а MessagePack различает int8, int16, int32, int64, uint8-uint64, float32 и float64. Если приложение сериализует число JSON и десериализует его как MessagePack, тип может измениться. Значение вроде 42, сериализованное из JavaScript (как double), может десериализоваться в строго типизированном языке как uint8. Всегда проверяйте поведение кругового преобразования между вашей библиотекой сериализации и потребляющим сервисом.

СвойствоJSONMessagePack
Человекочитаемость✓ Да✗ Только бинарный
Целочисленные типы✗ Нет (double)✓ int8-int64, uint8-uint64
Бинарные данные✗ Нужен base64✓ Нативный тип bin
64-битные целые✗ Потеря точности✓ Полные uint64/int64
Требуется схема✗ Без схемы✗ Без схемы
Нативность в браузере✓ JSON.parse/stringify✗ Нужна библиотека
Поддержка стриминга✓ Да✓ Да (с библиотеками)
Типы расширений✗ Нет✓ Да (тип ext)

Метки времени MessagePack

Тип расширения 1 в MessagePack - стандартизированный формат метки времени, кодирующий время Unix в виде бинарного значения размером 4, 8 или 12 байт с наносекундной точностью. Это меньше и точнее, чем строка ISO 8601 вроде `"2026-06-11T14:30:00Z"` (20 байт как JSON), и исключает неоднозначность часовых поясов. Большинство библиотек MessagePack автоматически кодируют и декодируют этот тип расширения, делая работу с метками времени прозрачной для уровня приложения.

Когда использовать MessagePack, а когда JSON

Выбор между MessagePack и JSON не о том, какой формат "лучше", а о том, какие ограничения важны в конкретном контексте. JSON выигрывает в универсальности, инструментах и отлаживаемости. MessagePack выигрывает в размере payload и скорости парсинга. Большинству API стоит начинать с JSON и переходить на MessagePack только после того, как профилирование подтвердит, что сериализация или размер payload действительно являются узким местом.

Используйте MessagePack, когда

  • Внутренний обмен между микросервисами - сервисы, контролируемые вами с обеих сторон, где человекочитаемость не нужна, а пропускная способность измеримо важна.
  • Высокочастотные брокеры сообщений - топики Kafka, NATS, RabbitMQ с тысячами событий в секунду, где размер payload напрямую влияет на пропускную способность и стоимость хранения.
  • Мобильные API с ограниченной полосой - сокращение payload на 30 % в высоконагруженном мобильном API заметно уменьшает расход трафика и задержки в сотовых сетях.
  • Протоколы реального времени и IoT - где бинарные кадры, задержка меньше миллисекунды и эффективность полосы являются требованиями к дизайну с самого начала.
  • Передача бинарных данных - payloads с необработанными байтами (изображения, фрагменты аудио, криптографический материал) избегают 33 % накладных расходов base64 при кодировании в JSON.

Оставайтесь на JSON, когда

  • Публичные API - внешние потребители ожидают JSON; добавление MessagePack требует библиотек на стороне клиента и middleware согласования контента.
  • Инструменты для разработчиков - DevTools браузера, curl, Postman и обозреватели API работают с JSON изначально; отладка MessagePack требует дополнительных шагов декодирования.
  • Эндпоинты с малым трафиком - затраты на разработку поддержки MessagePack намного превышают выгоду при небольшом объёме payload.
  • Уже используется сжатие gzip - HTTP gzip или Brotli агрессивно сжимает повторяющиеся имена ключей JSON, часто достигая сокращения, близкого к сырому MessagePack.

Warning

Согласование контента - рекомендуемый путь миграции для существующих JSON API: сервер принимает и Accept: application/json, и Accept: application/msgpack, а отвечает в формате, запрошенном клиентом. Это позволяет внедрять изменения постепенно, не ломая существующих клиентов. Не переводите существующее публичное API исключительно на MessagePack - затраты на отладку и инструменты для внешних потребителей редко стоят экономии размера.

Интеграция и инструменты

MessagePack имеет зрелые библиотеки для всех основных языков, но не поддерживается изначально в браузерах или стандартных HTTP-фреймворках так, как JSON. Добавление MessagePack в существующий стек означает новую зависимость, обновление обработки content-type и доработку любых инструментов отладки или логирования, работающих с необработанными телами запросов и ответов.

Библиотеки по языкам

  • Python - `msgpack` (PyPI). Быстрое расширение на C с чистым Python-фолбэком. Прямая замена `json` в большинстве случаев.
  • JavaScript / Node.js - `@msgpack/msgpack` (npm). Нативный для TypeScript, поддерживает стриминг. Также `msgpackr` для более высокой производительности.
  • Go - `github.com/vmihailenco/msgpack` или `github.com/ugorji/go/codec`. Обе реализуют полную спецификацию с поддержкой типов расширений.
  • Java / JVM - `msgpack-java` (официальная). Интегрируется с Jackson через `jackson-dataformat-msgpack` как прямая замена JSON.
  • Rust - `rmp` и `rmp-serde`. Сериализация на базе Serde превращает добавление MessagePack рядом с существующим JSON в изменение одной строки.

Проверка payload перед кодированием

Прежде чем переводить production-API на MessagePack, проверьте структуру JSON, который вы кодируете. Payload JSON со структурными ошибками - лишние запятые, ключи без кавычек, неожиданные null - молча создаст некорректный вывод MessagePack, вызывающий загадочные ошибки декодирования на стороне потребителя. Прогоните payload через JSON Formatter Viewer, чтобы проверить структуру, и через JSON Schema Validator, чтобы убедиться в соответствии ожидаемой форме перед кодированием.

Компрессоры JSON

Изучите варианты сокращения payload JSON - сравнение с MessagePack, укорочение ключей и минификация - всё локально в браузере, без загрузки.

Open tool

Компромиссы и оговорки

MessagePack - не бесплатное улучшение по сравнению с JSON. Бинарный формат влечёт реальные затраты на отлаживаемость, совместимость инструментов и адаптацию разработчиков. Это не гипотетические опасения - именно поэтому большинство команд, оценив MessagePack, в итоге оставляют JSON для всего, кроме конкретных внутренних каналов с большим объёмом, где компромисс явно окупается.

Отлаживаемость - самая дорогая практическая цена

С JSON вы можете прочитать необработанное тело запроса в терминале, DevTools браузера или любом текстовом логе. С MessagePack вы видите бинарный вывод вроде `\x81\xa4name\xa5Alice`. Каждая отладочная сессия требует шага декодирования. Команды, использующие MessagePack в production, обычно добавляют отдельную утилиту декодирования во внутренние инструменты и логируют декодированные payloads в стек наблюдаемости рядом с бинарными кадрами. Трение в разработке реально - не недооценивайте его.

Эволюция схемы и версионирование

MessagePack, как и JSON, не требует схемы, поэтому добавление или удаление полей не ломает формат. Однако отсутствие схемы означает, что встроенного механизма обратной совместимости нет, кроме проверок полей на уровне приложения. Для развивающихся API типы расширений MessagePack могут нести метаданные версии схемы, но это требует явного проектирования. Для строго типизированных развивающихся протоколов эволюция схемы Protobuf на основе номеров полей надёжнее - см. сравнение JSON Schema vs Protobuf для полного анализа компромиссов.

Уравнитель gzip

Сжатие HTTP gzip часто кардинально сокращает разрыв между JSON и MessagePack. JSON API с повторяющимися ключами в элементах массива сжимаются чрезвычайно хорошо, потому что gzip использует эту повторяемость. Типичный ответ API, который на 40 % меньше как сырой MessagePack, после сжатия gzip обоих форматов может быть меньше всего на 5-10 %. Всегда сравнивайте сжатый MessagePack со сжатым JSON, прежде чем принимать решение о миграции.

Warning

Никогда не переводите API целиком на MessagePack без профилирования. Измерьте размер payload и время сериализации на своих реальных production-payloads с помощью инструмента [Сравнение размера JSON и MessagePack](/tools/compress/json-compressors/json-vs-messagepack). Затем измерьте те же payloads после сжатия gzip. Продолжайте только если сравнение показывает значимое улучшение, оправдывающее затраты на отладку.

Key takeaways

  • MessagePack на 20-50 % меньше минифицированного JSON на типичных payloads - точная экономия зависит от того, сколько целых чисел, булевых значений и null содержит payload.
  • Скорость сериализации в 2-4 раза выше, чем у текстового JSON в бенчмарках, но высокопроизводительные библиотеки JSON вроде orjson (Python) и simdjson (C++) существенно сокращают этот разрыв.
  • MessagePack добавляет нативные типы, которых нет в JSON: беззнаковые 64-битные целые, необработанные бинарные данные, float32 и типы расширений для меток времени и пользовательских данных.
  • Самый серьёзный практический компромисс - отлаживаемость: вывод MessagePack бинарный и не читается напрямую в DevTools, curl или логах без шага декодирования.
  • Сжатый gzip JSON часто сокращает разрыв в размере с несжатым MessagePack - всегда сравнивайте оба варианта под gzip перед миграцией.
  • Инструмент Сравнение размера JSON и MessagePack на Aback Tools измеряет точную экономию в байтах и разбивку по типам для любого payload JSON менее чем за секунду.
  • Лучшие сценарии применения - внутренние высоконагруженные микросервисы, брокеры сообщений, мобильные API с ограниченной полосой и payloads с необработанными бинарными данными.

Частые вопросы

MessagePack обычно на 20-50 % меньше минифицированного JSON. Точная экономия зависит от структуры вашего payload. Payloads с большим числом целых чисел, булевых значений и null сжимаются наиболее сильно - небольшие целые (0-127) занимают 1 байт в MessagePack против 1-3 байт в тексте JSON. Payloads с преобладанием длинных строк выигрывают меньше, потому что строки хранятся как необработанные байты UTF-8 в обоих форматах. Используйте инструмент «Сравнение размера JSON и MessagePack» на Aback Tools, чтобы измерить точную экономию для вашего конкретного payload.

Сериализация и десериализация MessagePack в бенчмарках обычно в 2-4 раза быстрее обработки текстового JSON, потому что бинарный парсинг пропускает посимвольную токенизацию UTF-8, обязательную для JSON. Реальный выигрыш в скорости в продакшене сильно зависит от рантайма и библиотеки - высокопроизводительные парсеры JSON (simdjson в C++, orjson в Python) заметно сокращают разрыв. Наибольший эффект заметен в микросервисных API с высокой пропускной способностью, обрабатывающих тысячи запросов в секунду.

MessagePack поддерживает все типы, совместимые с JSON: null, boolean, целые (со знаком и без знака до 64 бит), float (32 и 64 бита), строку UTF-8, бинарный массив байт, массив и map. Кроме того, есть механизм типов расширений для пользовательских типов: меток времени, десятичных чисел и данных, специфичных для приложения. В отличие от JSON, MessagePack различает строки и необработанные бинарные данные на уровне системы типов - то, что JSON не может выразить без кодирования в base64.

Да. Пакет npm @msgpack/msgpack предоставляет совместимые с браузером кодировщик и декодировщик MessagePack с полной поддержкой TypeScript. Однако MessagePack - бинарный формат: его нельзя использовать с localStorage браузера (там хранятся только строки), отправлять как тело в виде простого текста или логировать в читаемом виде без hex-просмотрщика. Для связи браузера с сервером установите заголовок Content-Type в application/msgpack и убедитесь, что обе стороны используют одну версию библиотеки для согласованного кодирования.

На очень маленьких payloads (менее 20 байт) MessagePack может занимать столько же или чуть больше минифицированного JSON. Это происходит потому, что теги типов MessagePack добавляют по 1 байту на значение, и на крошечных payloads эти накладные расходы перевешивают компактность бинарной кодировки. Для payload с одним полем вроде {"ok":true} JSON занимает 10 байт, а MessagePack около 8-9 байт - разница незначительна. Преимущество в размере заметно растёт с усложнением и увеличением payload.

Нет. MessagePack - бинарный формат: закодированный вывод нечитаем без специального декодера или hex-просмотрщика. Это один из главных компромиссов по сравнению с JSON. Во время разработки отладка MessagePack-payloads требует инструмента, который декодирует бинарные данные обратно в читаемое представление. Инструмент «Сравнение размера JSON и MessagePack» на Aback Tools показывает первые 64 байта вывода MessagePack в hex, что полезно для проверки корректности кодирования без полного декодирования.

Да, но требует явной настройки на клиенте и сервере. Клиент должен отправлять заголовки Accept: application/msgpack и Content-Type: application/msgpack, а сервер - обрабатывать и JSON, и MessagePack для обратной совместимости. Большинство REST-фреймворков (Express, FastAPI, Spring) поддерживают собственный middleware согласования контента. Экосистемы GraphQL и OpenAPI обычно подразумевают JSON: поддержка MessagePack требует своих сериализаторов и редко оправдывает затраты на разработку, если размер payload не является измеренным узким местом.

Все три - бинарные форматы сериализации, более компактные, чем JSON. Protobuf (от Google) использует описание схемы, чтобы полностью убрать имена полей, и достигает сжатия в 5-10 раз относительно JSON - самая высокая плотность из трёх, но требует поддержки .proto-файлов. MessagePack не требует схемы, как и JSON, что делает его прямой заменой без накладных расходов на схему. CBOR (RFC 7049) - стандарт IETF с большим числом типов данных и лучшей расширяемостью, чем MessagePack. Для миграции API с JSON с минимальными усилиями MessagePack - самая простая отправная точка.

ShareXLinkedIn