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で公開しています。
実装の詳細やビルド手順についても、リポジトリのREADMEで解説しています。
おわりに
ESP32-S3とAzure Functionsを使った、gRPC(Protobuf)とJSONの通信比較検証を行いました。
通信時間自体はHTTPS接続のオーバーヘッドに支配されるため差は出ませんでしたが、シリアライズ速度が2.7倍高速、データサイズが1/3に圧縮 されるという明確なメリットが確認できました。
「速度」だけにとらわれず、CPU負荷の削減、データ量の削減、型安全な開発 といった観点から、デバイスの寿命や開発の堅牢性を高めるための選択肢として、gRPCは非常に有力な手法と言えます。
次のIoTプロジェクトで、バッテリー駆動や従量課金回線を使う場合は、ぜひgRPCを選択肢に入れてみてはいかがでしょうか?
See you …