Ian Chou's Blog

MessagePack 什麼時候該用?什麼時候不該用?

一篇給實務工程師的使用場景指南

MessagePack 常常被拿來跟 JSON、Protobuf、gRPC 一起比較,但這其實是個錯誤的起點

因為 MessagePack 不是要取代 JSON,也不是要跟 Protobuf 正面競爭;它真正厲害的地方,在於它填補了一個非常關鍵、但常被忽略的區間:

「我不想要 JSON 的冗餘,但我也不想要 gRPC 的複雜度。」

這篇文章會用場景導向的方式,說明 MessagePack 最適合用在哪裡、什麼情況下它是神兵利器,以及什麼時候你根本不該考慮它。


一、先給結論:MessagePack 的「甜蜜點」

一句話總結 MessagePack 的定位:

MessagePack =「結構化資料 + 二進制內容 + 高頻傳輸」的最佳折衷方案

如果你的資料同時滿足以下任兩點,MessagePack 幾乎一定值得考慮:


二、TypeScript / JavaScript 對 MessagePack 的支援其實非常成熟

很多人對 MessagePack 的第一個誤解是:

「在 TS / 前端用 MessagePack 會不會很痛苦?」

實際上完全不會。

官方維護的 @msgpack/msgpack 是純 TS/JS 實作,支援:

而且透過 TypeScript Generics,開發體驗非常順。

import { encode, decode } from "@msgpack/msgpack";

interface User {
  id: number;
  name: string;
  tags: string[];
}

// Encode
const binary = encode<User>({
  id: 1,
  name: "Alice",
  tags: ["admin"],
});

// Decode(型別推斷)
const user = decode<User>(binary);
user.name; // string

⚠️ 注意:
decode<T>() 不是 runtime validation,而是型別轉型(casting)。
如果你需要 runtime 驗證,MessagePack 應該搭配 schema validator 使用,而不是單獨承擔型別安全。


三、最容易被低估的殺手級應用:混合資料傳輸(文字 + 檔案)

傳統方案的問題

Web 世界中,我們經常要同時傳送:

常見做法只有兩種:

  1. multipart/form-data

    • 結構複雜
    • 巢狀資料難維護
    • 型別難對齊
  2. JSON + Base64

    • 體積膨脹 33%
    • CPU 浪費在 Base64 encode/decode

MessagePack 的解法

MessagePack 原生支援 Binary Type

const payload = {
  user: {
    id: 123,
    name: "Alice",
  },
  avatar: imageUint8Array, // 直接放 binary
};

fetch("/api/profile", {
  method: "POST",
  headers: { "Content-Type": "application/x-msgpack" },
  body: encode(payload),
});

後端 decode 後,avatar 就是 bytes,沒有任何轉換成本

👉 這個場景下,MessagePack 幾乎是目前 Web 世界最優雅的解法。


四、不要誤會:MessagePack 在「大量文字資料」並不佔優

假設你要下載:

1 萬筆歷史訂單(主要是文字)

直覺可能會想:「MessagePack 不是比較小嗎?」

但現實是:

格式 壓縮後體積
JSON + Brotli ~2.0 MB
MessagePack + Brotli ~1.9 MB

為了省那一點點流量:

👉 完全不值得

真正該優化的是「資料結構」,不是格式

{
  "columns": ["id", "name", "price"],
  "rows": [
    [1, "A", 100],
    [2, "B", 200]
  ]
}

這種結構,比換 MessagePack 有效 10 倍


五、MessagePack 在 BFF / 微服務內部通訊是高 CP 值選擇

Client ↔ Server 使用 JSON 是對的,但在:

MessagePack 非常適合。

為什麼?

  1. 沒有人需要讀它
  2. 傳輸頻率高
  3. CPU 與頻寬都是真實成本

與 gRPC 的實際取捨

gRPC MessagePack
Schema 嚴格
開發成本
變更彈性
適合語言 Go / Java Node / Python

👉 如果你覺得 .proto 太重、JSON 太慢,MessagePack 是完美中間解。


六、被忽略但非常重要的用法:Redis / Cache 儲存

很多系統還在這樣存 Redis:

redis.set(key, JSON.stringify(obj));

這其實是:

改成:

redis.setBuffer(key, encode(obj));

你會得到:

👉 在高流量系統中,這個改動「非常值錢」。


七、什麼時候「不該」用 MessagePack?

請直接用別的方案:

❌ 單一超大檔案(影片 / ZIP / Backup)

❌ 公開 API(給第三方開發者)


八、總結:一個實務導向的決策表

使用場景 推薦
前端 API JSON
混合資料上傳 MessagePack 👑
BFF / 微服務內部 MessagePack
Redis / Cache MessagePack(強烈)
大量文字列表 JSON + Gzip
超大檔案 Stream / Multipart

最後一句話

MessagePack 不是「到處都該用」的銀彈,但在對的地方用對它,它會是:

最少侵入、最高回報的效能優化之一

如果你的系統正卡在:

那你現在正站在 MessagePack 的甜蜜點上。