IoTデバイスの通信プロトコル:JSONかgRPCか

IoTデバイスからクラウドへのデータ送信において、最もポピュラーな選択肢は JSON です。軽量で人間が読みやすく、多くのプログラミング言語でサポートされているためです。

しかし、「もっとデータを軽くしたい」「マイコンの負荷を減らしたい」「通信コストを削減したい」と考えたとき、有力な候補に挙がるのが gRPC(Google Remote Procedure Call)Protocol Buffers(Protobuf) です。

本記事では、ESP32-S3から Azure Functions へセンサーデータを送信し、JSONとgRPCでどれほどの差が出るのかを実際に計測した結果をまとめました。


gRPCとProtocol Buffersとは?

Protocol Buffers(Protobuf) は、Googleが開発したデータシリアライズフォーマットです。JSONのようにデータ構造を表現しますが、テキスト形式ではなくバイナリ形式でデータを扱うため、サイズが小さく、処理速度が高速という特徴があります。

gRPC は、このProtobufを使用したRPC(Remote Procedure Call)フレームワークで、マイクロサービス間の通信などで広く使われています。IoTデバイスでは、メモリに制約があるため、軽量な Nanopb というProtobuf実装を使用するのが一般的です。

Protobufの基礎知識についてはこちらの記事で詳しく解説しています: 【理論解説】マイコンで使うgRPC入門!Protocol Buffers基礎知識


実測データ比較:JSONとgRPCの速度とサイズ

同じセンサーデータ(デバイスID、温度、湿度)を、JSONとgRPCそれぞれで送信した際の実測値がこちらです。ESP32-S3とAzure Functionsを使った実環境での計測結果です。

実測データ比較

比較項目 JSON形式 gRPC (Protobuf) 改善率
シリアライズ時間 約424 μs 約157 μs 約2.7倍高速
データサイズ 62 bytes 21 bytes 約1/3に凝縮
トータル通信時間 約1.3 sec 約1.3 sec 差なし

データの中身をパッキングする「シリアライズ」の速度や、パケットの「サイズ」については、gRPCが圧倒的な性能を示しました。一方で、トータルの通信時間はどちらもほぼ同じ という、興味深い結果となっています。

この結果から、gRPCは「通信速度の向上」よりも、「CPU負荷の削減」「データ量の削減」「省電力化」といった側面で効果を発揮することがわかります。


実装構成:マイコンとクラウドの連携

今回の検証では、マイコン側には軽量な Nanopb を、クラウド側には Azure Functions(Python) を採用しました。

マイコン側(ESP32-S3)の実装

マイコンの限られたメモリを圧迫しないよう、設計図(.protoファイル)からC言語のコードを自動生成して使用します。

使用ツール:

  • ESP-IDF: ESP32の開発フレームワーク
  • Nanopb: 組み込みデバイス向けの軽量Protobuf実装
  • HTTPS通信: Wi-Fi経由でAzure Functionsへデータ送信

手書きでJSONを組み立てるよりも遥かに効率的で、バグの入りにくい実装が可能になります。また、型安全性が保証されるため、データ構造の変更時もコンパイルエラーで検出できます。

ESP32でのNanopb環境構築とローカル疎通確認についてはこちら: ESP32でgRPC(Protobuf)通信!Nanopbを使って爆速・軽量な自動ビルド環境を構築する(ローカル疎通)

クラウド側(Azure Functions)の実装

サーバー側ではPythonを使用し、届いたバイナリデータをそのままパース(解析)します。

実装のポイント:

  • HTTP Trigger: RESTful APIとしてエンドポイントを公開
  • Protobuf解析: Python用のprotobufライブラリでデコード
  • バイナリデータ処理: Content-Type application/octet-stream でリクエストを受信

テキスト形式のJSONと違い、届いた「生のデータ」を瞬時に構造体へ復元できるのが強みです。

ESP32とAzure Functionsの連携方法についてはこちら: ESP32-S3からAzureへデータを飛ばす!HTTPS POSTとサーバーレス連携の極意


検証で見えた「1.3秒の壁」の正体

なぜデータサイズが1/3になっても、通信時間が短縮されなかったのでしょうか?そこには実用上の重要なポイントが隠れていました。

HTTPS接続が支配する通信時間

実測でネットワークタイムに差が出なかったのは、TLS(HTTPS)の接続準備(ハンドシェイク) に約1.3秒を要しているためです。

通信時間の内訳:

  • TLSハンドシェイク:約1.3秒
  • データ送信:30〜50ミリ秒
  • レスポンス受信:20〜40ミリ秒

IoT通信において、一度の送信にかかる電力の多くは、この「接続を確立する瞬間」に消費されていることがわかります。データサイズの削減効果は、この接続時間に比べると誤差範囲に収まってしまいます。

実装時の注意点:スタックメモリの確保

HTTPS通信は非常に多くのメモリを消費します。検証中にクラッシュが発生したため、ESP32の スタックサイズを8192以上(推奨16KB) へ拡張することで安定稼働を実現しました。

// タスク作成時のスタックサイズ設定例
xTaskCreate(
    https_task,
    "https_task",
    16384,  // スタックサイズ(バイト)
    NULL,
    5,
    NULL
);

特にTLS通信を行う際は、十分なスタックサイズの確保が必須です。

技術的な詳細や実装手順についてはQiita記事で解説しています: ESP32 × Azure Functions!gRPC (Protobuf) vs JSON 通信比較検証(クラウド連携)


gRPCが真価を発揮するシーン

トータルの通信時間が変わらないのであれば、gRPCを使う意味はないのでしょうか?いえ、そんなことはありません。gRPCには「通信速度」以外にも重要なメリットがあります。

CPU負荷の削減と省電力化

シリアライズが2.7倍速いため、CPUがフル稼働する時間を削り、即座にスリープへ戻ることで省電力に貢献します。

バッテリー駆動のIoTデバイスでは、CPUの稼働時間が消費電力に直結します。シリアライズ時間が424μsから157μsへ短縮されることで、その分早くDeep Sleepモードへ移行でき、バッテリー寿命の延長につながります。

データ量削減による通信コスト削減

LTE-Mなどの従量課金回線や、Wi-Fiが不安定な場所では、21バイトという「軽さ」が通信の成功率とコストに直結します。

データ量削減のメリット:

  • 従量課金回線での通信コスト削減
  • 電波状況が悪い場所での送信成功率向上
  • 複数センサーからの同時送信時の帯域節約

型安全な開発と保守性の向上

サーバーとマイコンで同じ定義(.protoファイル)を共有するため、データ型の不一致によるトラブルを未然に防げます。

開発面でのメリット:

  • コンパイル時に型チェックが行われる
  • データ構造の変更が容易
  • ドキュメントとしても機能する
  • 多言語間での互換性が保証される

ソースコード

今回の検証に使用した全コード(ESP-IDF / Azure Functions)はGitHubで公開しています。

📦 GitHubでコードを見る

実装の詳細やビルド手順についても、リポジトリのREADMEで解説しています。


おわりに

ESP32-S3とAzure Functionsを使った、gRPC(Protobuf)とJSONの通信比較検証を行いました。

通信時間自体はHTTPS接続のオーバーヘッドに支配されるため差は出ませんでしたが、シリアライズ速度が2.7倍高速データサイズが1/3に圧縮 されるという明確なメリットが確認できました。

「速度」だけにとらわれず、CPU負荷の削減データ量の削減型安全な開発 といった観点から、デバイスの寿命や開発の堅牢性を高めるための選択肢として、gRPCは非常に有力な手法と言えます。

次のIoTプロジェクトで、バッテリー駆動や従量課金回線を使う場合は、ぜひgRPCを選択肢に入れてみてはいかがでしょうか?

See you …