Skip to content
Published on

モダン Erlang と BEAM 2026 — OTP 27 / OTP 28 プレビュー / Cowboy 3 / Bandit / Khepri / Gleam / Nerves / AtomVM 徹底ガイド

Authors

プロローグ — なぜ 30 年もののバーチャルマシンが 2026 年でも魅力的なのか

1986 年。エリクソンの通信スイッチチームが新言語を作る。名前は Erlang。目的はただ一つ — 死なないシステム。9 個の 9、つまり 99.9999999% の可用性を持つ電話交換機。

それから 40 年。2026 年の Erlang はもう通信会社の言語ではない。WhatsApp は 20 億人のメッセージを BEAM の上でさばき、Discord は数億人の音声・テキストを Elixir でルーティングし、Klarna は決済トランザクションを Erlang で処理している。RabbitMQ は事実上あらゆるマイクロサービスのバックボーンに敷かれ、Akamai の DNS は Erlang で動く。

BEAM は止まっていない。 2024 年 5 月に OTP 27 が出て、OTP 28 がプレビューから安定版へ向かう。Cowboy 3 が HTTP/2 と WebSocket を再仕上げし、Bandit が純 Elixir で Cowboy の代替を示した。RabbitMQ チームは Mnesia 後継となる Khepri を Raft の上に作った。Gleam は静的型を引っ提げて BEAM エコシステムに合流、Nerves は組み込み、AtomVM は ESP32 マイコンまで侵入した。

この記事は 2026 年の BEAM エコシステムの 全体地図 である。OTP 27/28 の新機能、HTTP スタック、分散データ、組み込み、新しい言語、そして誰が実際に使っているか。

「Erlang は私たちに、より少ない人数でより多くのことをさせてくれた。」 — Jan Koum、WhatsApp 共同創業者。50 人のエンジニアで 9 億ユーザーを運用していた頃。


第 1 章 · 2026 年の Erlang/BEAM 地図 — なぜ今も魅力的か

まず BEAM とは何か、なぜ他のバーチャルマシンと本質的に違うのかを整理する。

BEAM の 4 つの中核資産

  1. 軽量プロセス(グリーンプロセス) — OS スレッドではない。BEAM 内部の仮想プロセス。1 個あたり約 300 バイト。単一ノードで数百万個が起動できる。
  2. プリエンプティブスケジューラ — Go の協調型スケジューラとは違う。BEAM はリダクションカウントで強制的にコンテキストスイッチをする。1 つのプロセスが無限ループを回しても、ほかのプロセスが餓死しない。
  3. share-nothing のメッセージパッシング — プロセス間でメモリを共有しない。通信はすべてメッセージ。ロックがない。デッドロックのカテゴリ自体が消える。
  4. OTP (Open Telecom Platform) — supervisor、gen_server、gen_statem のような振る舞い(behavior)。30 年検証された分散・耐障害ライブラリの標準集。

BEAM が輝く領域と輝かない領域

輝く                                       輝かない
────────────────────────                  ────────────────────
大量の同時接続(数百万)                   数値計算 (CPU バウンド)
リアルタイムメッセージング・チャット       単一スレッドのスループット
分散システム・クラスタリング              機械学習の学習(training)
長寿命の接続 (LiveView)                   デスクトップ GUI アプリ
障害耐性が必須のシステム                   システムプログラミング
プロトコルゲートウェイ (MQTT, AMQP)        ゲームエンジン

要点: CPU ではなく、同時実行性(concurrency)がボトルネックになる場所。そして 死んではいけない場所

2026 年の BEAM エコシステム一枚絵

              ┌────────────────────────────────────────┐
              │             BEAM VM                    │
              │      (JIT, ETS, supervisor, OTP)       │
              └───────┬────────────────┬───────────────┘
                      │                │
        ┌─────────────┼───┐    ┌───────┼──────────┐
        │             │   │    │       │          │
     Erlang        Elixir gleam    Lustre     Phoenix
       │              │     │       (web)   (LiveView)
       │              │     │
       ▼              ▼     ▼
  ┌────────┐     ┌─────────┐  ┌─────────┐
  │Cowboy 3│     │ Bandit  │  │ AtomVM  │
  │  HTTP  │     │(Plug用) │  │ (ESP32) │
  └────────┘     └─────────┘  └─────────┘

  ストレージ:  Mnesia / Khepri (Raft) / ETS / DETS
  分散:        distributed Erlang / partisan
  組み込み:    Nerves (Linux) / AtomVM (MCU)
  財団:        Erlang Ecosystem Foundation (EEF)

以下、この地図の各部分を順に見ていく。


第 2 章 · Erlang/OTP 27 (2024 年 5 月) — 文字列補間と persistent_term の再発見

2024 年 5 月、Erlang/OTP 27 が正式リリースされた。2026 年現在、本番の大半は 27 へ移動中か既に移動済み。27 がもたらした、もっとも目立つ 3 つの変化。

2-1. トリプルクオート文字列 + 文字列補間

Erlang は 30 年間、文字列補間を持たなかった。2026 年でようやく追加された。しかも 2 形式で。

%% トリプルクオート (OTP 27)
Greeting = """
   Hello, World!
   Multi-line, no escaping needed.
   """,

%% シジル形式 (~b は binary)
Name = <<"Alice">>,
Greeting2 = ~b"Hello, #{Name}!".
%% => <<"Hello, Alice!">>

~b シジルで補間ありのバイナリ文字列、~B で補間なしのバイナリ。Elixir の ~s~S に近い設計。

現実: Erlang ユーザーは 30 年間 io_lib:format("Hello, ~p!", [Name]) を書いてきた。これからは ~b"Hello, #{Name}!" で済む。コードがはるかに読みやすくなる。

2-2. set_node_lookup_node / ノード探索の改善

分散 Erlang クラスタのノード探索は EPMD (Erlang Port Mapper Daemon) に依存していた。OTP 27 では、EPMD を迂回してノード名を直接登録できるコールバック API を正式化した。

  • コンテナ環境(Kubernetes)で EPMD が邪魔だった問題を解消。
  • libcluster のようなライブラリは既に近いことをやっていたが、OTP 27 で標準インターフェイスができた形。

2-3. persistent_term の改善 — 高速な読み出し

persistent_term はほぼ変わらないグローバル定数を高速に読むための、ETS のいとこである。書き込みは非常に重い(システム全体の GC を誘発)が、読み出しはほぼゼロコスト。

OTP 27 は内部実装を整理し、メモリ使用量と書き込み時の GC コストを削減した。設定値・鍵・ルーティングテーブルのような「ほぼ永続」データに、ますます使いやすくなった。

%% 1 回書いて、数億回読む
persistent_term:put({config, max_connections}, 100000),

%% ホットパスでほぼ無料
Max = persistent_term:get({config, max_connections}).

2-4. JIT 改善とコンパイラの診断

  • BEAMAsm JIT が ARM64 でも安定化(Apple Silicon、AWS Graviton で直接性能向上)。
  • コンパイラ警告がより正確になり、エラーメッセージが親切になった。
  • maps モジュールに iterator/2filtermap/2 などが追加。

OTP 27 への移行チェックリスト

□ Rebar3 / Mix を OTP 27 互換バージョンに更新
□ Dialyzer を再実行(型システムが微妙に変化)
□ EPMD 代替コールバックを使うなら net_kernel 設定を確認
□ トリプルクオート文字列は IDE 対応を確認 (Erlang LS, ElixirLS)
□ 依存ライブラリの OTP 27 互換性を確認(大半は OK)

第 3 章 · OTP 28 プレビュー — 次に来るもの

2026 年 5 月現在、OTP 28 は release candidate 段階。正式リリースは 2026 年夏目標。主な変化。

3-1. JIT のさらなる最適化

  • BEAMAsm のレジスタ割り当てアルゴリズムを再整備、ホットループで 10〜15% の追加性能。
  • 関数呼び出しのインライン化ヒューリスティクス改善。

3-2. set / map の標準ライブラリ拡張

%% OTP 28 で追加予定の maps 関数
maps:groups_from_list(fun(X) -> X rem 2 end, [1,2,3,4,5]).
%% => #{0 => [4,2], 1 => [5,3,1]}

%% set モジュールにも同様の便利関数

3-3. ssl スタックの現代化 — TLS 1.3 の完成

  • TLS 1.3 の 0-RTT モードを完全サポート。
  • ポスト量子鍵交換アルゴリズム(Kyber / ML-KEM)を実験的サポート。

3-4. logger と telemetry の統合強化

  • OpenTelemetry 互換のためのインフラ拡張。
  • 構造化ロギングのメタデータ標準化。

3-5. 分散モニタリングの改善

  • monitor/2link/1 の分散環境エラーメッセージ改善。
  • ノード間 monitor メッセージ喪失時の復旧動作を明確化。

まとめ: OTP 28 は革命ではない。磨き(polish) である。30 年ものの言語が毎年どう改善され続けるか、その良い例。


第 4 章 · Cowboy 3 — BEAM の標準 HTTP サーバ

Cowboy は Loïc Hoguin が作った小さく速い Erlang HTTP サーバ。Plug、Phoenix、RabbitMQ Management UI、ほぼすべての Erlang/Elixir ウェブスタックの既定 HTTP サーバ。

2024 年末に Cowboy 3 がリリースされた。中核の変化。

4-1. HTTP/2 の完成度

  • Cowboy 2 も HTTP/2 をサポートしていたが、一部 corner case で RFC 9113 と食い違いがあった。
  • Cowboy 3 は仕様をもう一度丸ごと洗い、fuzzing テストを追加。
  • 特に GOAWAY 処理、フロー制御ウィンドウのレースコンディションを修正。

4-2. WebSocket の安定化

  • WebSocket 圧縮 (permessage-deflate) オプションの整理。
  • 部分メッセージ(framing)処理におけるメモリリークの可能性を修正。

4-3. HTTP/3 — 実験的サポート

  • QUIC トランスポート経由の HTTP/3 が experimental に入った。
  • 本番推奨ではないが、ベータ導入を始めているチームがある。

4-4. シンプルな Cowboy ハンドラ例

%% rebar.config に cowboy 依存を追加した上で

-module(hello_handler).
-export([init/2]).

init(Req0, State) ->
    Req = cowboy_req:reply(200,
        #{<<"content-type">> => <<"text/plain">>},
        <<"Hello from Cowboy 3!">>,
        Req0),
    {ok, Req, State}.

%% ルータに登録
start() ->
    Dispatch = cowboy_router:compile([
        {'_', [{"/", hello_handler, []}]}
    ]),
    {ok, _} = cowboy:start_clear(my_http_listener,
        [{port, 8080}],
        #{env => #{dispatch => Dispatch}}).

Cowboy を使う代表的なシステム

  • Phoenix (Elixir Web フレームワーク) — デフォルトアダプタの一つ。
  • RabbitMQ Management Plugin
  • Akamai の一部エッジサービス
  • WhatsApp 内製ツール

第 5 章 · Bandit — 純 Elixir で書き直された HTTP サーバ

Cowboy は Erlang で書かれている。Plug/Phoenix は Elixir で書かれている。両者をつなぐアダプタ (Plug.Cowboy) は常に存在したが、「Elixir スタック全体を Elixir で書きたい」という声があった。

Bandit (2022 年開始、Mat Trudel 主導)がその答え。

5-1. Bandit が狙ったもの

Cowboy:   Erlang  -> Elixir アダプタ (Plug.Cowboy) -> Plug/Phoenix
Bandit:   Elixir  ->                                -> Plug/Phoenix
  • 純 Elixir で HTTP/1.1、HTTP/2、WebSocket を実装。
  • Plug インターフェイスと直接統合(アダプタ層が不要)。
  • 一部のマイクロベンチで Cowboy 比 10〜30% 速い。

5-2. Phoenix との統合

Phoenix 1.7 以降、Bandit を Plug.Cowboy のドロップイン代替として使える。

# config/config.exs
config :my_app, MyAppWeb.Endpoint,
  adapter: Bandit.PhoenixAdapter,
  http: [port: 4000]

これ 1 行で済む。Phoenix LiveView、channels、controllers すべてそのまま動く。

5-3. Bandit vs Cowboy — 2026 年比較

                      Cowboy 3            Bandit
ホスト言語            Erlang              Elixir
HTTP/1.1              本番運用済み         本番運用済み
HTTP/2                RFC 9113            RFC 9113
HTTP/3                実験的              まだなし
WebSocket             あり                あり
Plug 統合             アダプタ経由         ネイティブ
運用実績              10 年以上            3〜4 年
本番推奨              保守的なら ✓       新規 Phoenix なら ✓

5-4. どちらを選ぶか

  • 既存 Erlang システム → Cowboy 3。
  • 新規 Phoenix プロジェクト → Bandit が徐々にデフォルト化。
  • HTTP/3 が必要 → Cowboy 3 (現状)。
  • 純 Elixir コードベースが欲しい → Bandit。

第 6 章 · Khepri — RabbitMQ チームが作った Mnesia 後継

Mnesia は 1990 年代の Erlang の分散 DBMS。メモリ・ディスクハイブリッド、トランザクション、ETS 互換のインターフェイス。しかし netsplit (ネットワーク分断) 時の挙動が古くから弱点 として知られていた — 分断が起きると両側が生き残り、データが分かれ、再合流には手動介入が必要だった。

RabbitMQ チーム(Pivotal → VMware → Broadcom)がこの問題に正面から取り組んで作ったのが Khepri である。

6-1. Khepri の核心アイデア

「Mnesia を置き換える、ただし Raft 合意 をその下に敷く。」

  • ツリー形式のキー値ストア(Zookeeper / etcd に近いデータモデル)。
  • すべての書き込みは Raft 合意を通る → 過半数が生きていなければ書き込めない。
  • netsplit 時、両側が「真実は自分だ」と主張する事態がなくなる(少数派は書き込めない)。
  • Erlang/OTP で書かれており、外部依存なし。

6-2. Khepri のデータモデル

%% パスベースのツリー構造
ok = khepri:put([app, config, max_users], 1000),
{ok, 1000} = khepri:get([app, config, max_users]),

%% ワイルドカードクエリ
{ok, Map} = khepri:get_many([app, config, ?KHEPRI_WILDCARD_STAR]).

Zookeeper の znode、etcd のキーツリーに非常に近い設計。

6-3. RabbitMQ での採用

  • RabbitMQ 4.0 (2024 年 9 月) から Khepri をメタデータストアとして選択可能。
  • 4.x の後半でデフォルト化予定。
  • 置換対象は RabbitMQ 内部の Mnesia(キュー定義、ユーザー、vhost のようなメタデータ)。
  • メッセージ本体は別のキューエンジン(quorum queue など)が扱うため、Khepri は「コントロールプレーン」に集中。

6-4. 自分のシステムで Khepri を使う

%% rebar.config に khepri を追加
{deps, [
    {khepri, "0.14.0"}
]}.

%% 起動
{ok, _} = khepri:start(),

%% トランザクション
khepri:transaction(fun() ->
    khepri_tx:put([users, alice], #{role => admin}),
    khepri_tx:put([users, bob], #{role => user})
end).

結論: Khepri は Mnesia を「静かに」置き換えつつある。新規の分散 BEAM システムでメタデータストアを選ぶとき、Khepri はますます合理的な選択になっている。


第 7 章 · Mnesia / partisan — 分散データと分散通信

7-1. Mnesia — まだ生きている

Khepri が登場したからといって Mnesia が消えたわけではない。2026 年でも:

  • トランザクションが要る場所、テーブル形式のデータ、ETS とそっくりなインターフェイスが要る場所で、いまだに使われる。
  • ejabberd (XMPP サーバ)、一部のゲームサーバ、通信機器の中で Mnesia が今も動いている。
  • 弱点は変わらない: netsplit 対応が弱く、大規模データセットでは運用負担がある。

指針:

  • データが小さく、ノード数が少ない → Mnesia でも問題なし。
  • netsplit 一貫性が重要 → Khepri か外部 DB。
  • ただのキャッシュなら → ETS だけで足りる。

7-2. partisan — 分散 Erlang そのものへの挑戦

既定の分散 Erlang (net_kernel) はフルメッシュトポロジを前提とする。すべてのノードがすべてのノードと直接接続。ノード数が 100 を超え始めるとメッセージ爆発と head-of-line blocking の問題が出てくる。

partisan (Christopher Meiklejohn ほか)がこれを再設計した。

distributed Erlang:  N ノード -> N*(N-1)/2 接続(フルメッシュ)
partisan:            複数のトポロジオプション
                     - フルメッシュ
                     - hyparview (P2P オーバレイ)
                     - クライアント・サーバ
                     - PG2 ベースの静的グループ

中核アイデア:

  1. マルチチャンネル — ノードペアの間に複数の TCP 接続。小さいメッセージが大きいメッセージで詰まらない。
  2. モノリシック vs P2P — トポロジを選べる。
  3. 後方互換gen_server インターフェイスをそのまま使え、内部だけ差し替え。

2026 年現在の partisan は:

  • 学術研究から始まり、一部の本番(特に IoT バックエンドやゲームサーバ)で採用。
  • 主流はまだ distributed Erlang だが、大規模クラスタ では partisan を検討するチームが増えている。

第 8 章 · Nerves — 組み込み Erlang/Elixir

Nerves は Frank Hunleth 主導の組み込みフレームワーク。中核アイデア:

「Linux の上で BEAM だけを動かす。ユーザランド全部が Elixir/Erlang。」

8-1. Nerves が狙ったもの

  • Raspberry Pi、BeagleBone、産業用シングルボードコンピュータ。
  • 従来の組み込み Linux ディストリ(buildroot、yocto)の複雑さを下げ、再現可能なファームウェアビルド
  • A/B パーティションを使った安全な OTA アップデート。
  • BEAM の supervisor モデルをファームウェア全体に適用。

8-2. 典型的な Nerves プロジェクト構成

# 新規 Nerves プロジェクト作成 (Raspberry Pi 4 ターゲット)
mix nerves.new my_iot_device --target rpi4

cd my_iot_device

# ファームウェアビルド
MIX_TARGET=rpi4 mix deps.get
MIX_TARGET=rpi4 mix firmware

# SD カードに焼く
MIX_TARGET=rpi4 mix firmware.burn

ファームウェアの中にはブートローダ、Linux カーネル、BEAM、そして Elixir アプリケーションが入っている。ユーザランドにはほぼ他に何もない。

8-3. 実例

  • FarmBot — オープンソースの農業ロボット。
  • GRiSP — 産業用組み込みボード。Erlang をベアメタル(または RTOS の上)で直接駆動。
  • 物流・倉庫自動化機器 — 一部の会社が Nerves ベースの PLC 代替を出荷。
  • オーディオ機器、デジタルサイネージ

8-4. NervesHub — OTA フリート管理

Nerves チームが作った NervesHub は、ファームウェア更新の中央管理システム。デバイス艦隊全体に段階的ロールアウトができる。

ポイント: Nerves は「組み込みも BEAM の supervisor の中で動かせば死なない」という仮説を実証するプロジェクト。


第 9 章 · gleam — 静的型付け BEAM 言語

gleam (Louis Pilfold 作、2016 年開始)は BEAM の上で動く 静的型付け 関数型言語である。2024 年にシード調達と 1.0 リリースを経て、本格的に注目を集めた。

9-1. gleam が提示するもの

import gleam/io
import gleam/list

pub fn main() {
  let numbers = [1, 2, 3, 4, 5]
  let doubled = list.map(numbers, fn(n) { n * 2 })
  io.debug(doubled)
}
  • 型推論 — 変数宣言にほとんど型を書かなくても、コンパイル時にすべての型が決まる。
  • 式ベース — Erlang/Elixir 寄りの関数型スタイル。
  • BEAM と JavaScript の二つのターゲットへコンパイル。(そう、gleam は JS も吐く。)
  • Erlang FFI — 既存の Erlang/OTP ライブラリをそのまま呼び出せる。

9-2. なぜ静的型を BEAM に持ち込んだか

  • Elixir、Erlang は動的型付け。dialyzer (success typing) はあるが限界がある。
  • gleam は最初から強力な静的型(Hindley-Milner 系)で設計。
  • 結果: コンパイルが通ればたいていのミスは捕まる — Rust や Haskell に近い。

9-3. 簡単な OTP スタイルのアクター (gleam_otp)

import gleam/erlang/process
import gleam/otp/actor

pub fn main() {
  let assert Ok(subject) = actor.start(0, handle_message)
  process.send(subject, Increment)
  process.send(subject, Increment)
  // 二度インクリメント
}

pub type Message {
  Increment
  GetCount(reply_to: process.Subject(Int))
}

fn handle_message(message: Message, count: Int) -> actor.Next(Message, Int) {
  case message {
    Increment -> actor.continue(count + 1)
    GetCount(reply_to) -> {
      process.send(reply_to, count)
      actor.continue(count)
    }
  }
}

型のある OTP。プロセスが受け取れるメッセージの種類がコンパイル時に検証される。

9-4. gleam 1.0 以降の動き

  • エコシステムの急成長 — hex.pm の gleam パッケージ数が急増。
  • 2024 年シード調達 — Pilfold が gleam の開発に専念可能に。
  • JavaScript ターゲット — gleam コードの一部をフロントエンドに使える。
  • コミュニティの雰囲気 — Elixir コミュニティに友好的に受け入れられている。

9-5. gleam を選ぶべきとき

  • 静的型付けの安心感が欲しいとき。
  • BEAM の同時実行性・耐障害性を求めつつ 型安全性 も求めるとき。
  • 新規プロジェクトとして開始できるとき(既存 Elixir コードベースの移行は別問題)。

第 10 章 · Lustre — gleam のウェブフレームワーク

Lustre は Hayleigh Thompson が作った gleam のフロントエンドフレームワーク。Elm に強くインスパイアされた The Elm Architecture (TEA) パターン。

10-1. Lustre のモデル

        ┌─────────┐     Msg     ┌─────────┐
        │  View   │ ───────────>│ Update  │
        │ (HTML)  │             │ (モデル  │
        └─────────┘ <────────│  │  変更)  │
            ▲       Model       └─────────┘
            └──── ユーザー操作 ────┐
                            (ブラウザ)

10-2. シンプルなカウンタ (Lustre)

import lustre
import lustre/element/html.{button, div, text}
import lustre/event

pub fn main() {
  let app = lustre.simple(init, update, view)
  let assert Ok(_) = lustre.start(app, "#app", Nil)
}

fn init(_) {
  0
}

pub type Msg {
  Incr
  Decr
}

fn update(model: Int, msg: Msg) -> Int {
  case msg {
    Incr -> model + 1
    Decr -> model - 1
  }
}

fn view(model: Int) {
  div([], [
    button([event.on_click(Decr)], [text("-")]),
    text(int.to_string(model)),
    button([event.on_click(Incr)], [text("+")]),
  ])
}

10-3. Lustre の二つのモード

  1. クライアントサイド — gleam を JavaScript にコンパイルしてブラウザで実行。
  2. サーバコンポーネント — Phoenix LiveView スタイルで、サーバが状態を持ち、ブラウザは薄いクライアント。

サーバコンポーネントモードは LiveView に近いが、gleam の型安全性が持ち込まれる点で差別化される。

10-4. 2026 年の位置付け

  • Lustre はまだ主流ではない。
  • 小さなプロジェクト、サイドプロジェクト、gleam のフルスタックを試したいチームが採用中。
  • LiveView の代替としての可能性を探る段階。

第 11 章 · AtomVM — ESP32 で Erlang を走らせる

AtomVM (Davide Bettio ほか)は BEAM のバイトコードをマイコンで実行する VM である。

11-1. AtomVM が狙う場所

  • ESP32 (Wi-Fi/Bluetooth 内蔵 MCU、非常に安価)
  • STM32
  • Raspberry Pi Pico (RP2040)

これらのボードは Linux を載せるには小さすぎる(普通は数百 KB〜数 MB の RAM)。Nerves は来られないが、AtomVM は来られる。

11-2. どう動くか

  • 標準 BEAM バイトコード (.beam ファイル)をそのまま読み込み、マイコンで解釈・実行。
  • 標準ライブラリの 一部のみ 対応(メモリ制約)。
  • supervisor、gen_server のような OTP パターンは使える。

11-3. ESP32 での "Hello, Erlang"

-module(blink).
-export([start/0]).

start() ->
    Pin = 2,
    gpio:set_pin_mode(Pin, output),
    loop(Pin, high).

loop(Pin, State) ->
    gpio:digital_write(Pin, State),
    timer:sleep(500),
    NextState = case State of
        high -> low;
        low -> high
    end,
    loop(Pin, NextState).
# コンパイル後 ESP32 に焼く(概略)
erlc blink.erl
atomvm_packbeam blink.avm blink.beam
esptool.py write_flash 0x250000 blink.avm

LED 点滅のような入門例から始めて、BLE ベースの IoT デバイス、小さなメッセージゲートウェイまで作れる。

11-4. AtomVM と Nerves の比較

            AtomVM                       Nerves
ターゲット   MCU (ESP32, STM32)          SBC (Pi, BeagleBone)
RAM          数百 KB                     数 GB も可能
OS           なし (ベアメタル/FreeRTOS)  Linux
BEAM         AtomVM (subset)             正式な OTP
ユースケース センサノード、BLE デバイス  エッジゲートウェイ

最小ノードは AtomVM、それを集約するハブは Nerves、クラウドバックエンドは正式な OTP — そういう構図が成立する。

11-5. 2026 年現在

  • AtomVM 0.6 系列が安定化段階。
  • Erlang/Elixir 両方に対応(どちらも .beam にコンパイルされるので)。
  • コミュニティは活発だが小さい。IoT/エッジに興味のある BEAM ユーザーが集まる場所。

第 12 章 · RabbitMQ — Erlang の代表選手

RabbitMQ は別記事で取り上げているので、ここでは簡潔に。重要なのは この会社が Erlang を主流に押し上げた最大の貢献者 であること。

12-1. RabbitMQ が Erlang を選んだ理由

  • AMQP メッセージブローカは本質的に数万〜数十万の同時接続を捌く必要がある。
  • 死んではいけない — supervisor ツリー。
  • 分散クラスタリングが最初から必要だった。
  • Erlang はまさにそのために作られた言語だった。

12-2. 2026 年の RabbitMQ

  • バージョン 4.x。
  • Quorum Queue がデフォルト。Raft 合意ベースのキュー(旧クラシックミラーキューの置換)。
  • Khepri がメタデータストアへ移行中。
  • MQTT 5.0Streams(Kafka 風の追加)対応。

12-3. Erlang エコシステムへの影響

  • Erlang を単なる「通信会社の言語」から 主流のインフラコンポーネント に引き上げた最大の立役者。
  • 多くの企業は RabbitMQ 経由で「あれ? Erlang のシステムって意外と死なないな」を初体験。

第 13 章 · 本番事例 — WhatsApp / Klarna / Discord / Riot / Cisco / Akamai

BEAM を真剣に使っている会社の短いケーススタディ。

13-1. WhatsApp — Erlang スケール伝説

  • 2009 年創業。Jan Koum が ejabberd (XMPP サーバ、Erlang) 出身で、最初から Erlang。
  • 1 台のサーバで 200 万同時接続を初めて公に見せたシステム。
  • 2014 年 Facebook 買収時に、9 億ユーザーを 50 名のエンジニアで運用。
  • 買収後もコアは依然として Erlang/FreeBSD ベース。
  • 少ない人数で巨大な同時実行性」が BEAM のキャッチフレーズになった。

13-2. Klarna — 金融スケールの Erlang

  • スウェーデンの BNPL (buy now, pay later) フィンテック。
  • 2005 年から Erlang を採用。決済トランザクション処理、リスク評価の一部。
  • モノリシックな Erlang システムから徐々にマイクロサービス化。それでも Erlang はコアに残る。
  • Erlang のホットコードスワップを無停止デプロイで積極活用。

13-3. Discord — Erlang/Elixir ハイブリッド

  • ボイス・テキストゲートウェイは Elixir (BEAM)。
  • 一つのチャネルに数百万ユーザーが同時にメッセージを受け取る状況を、BEAM のプロセスモデルで処理。
  • 一部コアのデータプレーンは Rust で書き直し(Erlang/Elixir で苦手な部分は正直に他言語へ)。
  • ただし セッション・ルーティング・リアルタイム通信は Elixir 担当

13-4. Riot Games — Erlang 製チャット

  • League of Legends のゲーム内チャットが Erlang (ejabberd 派生)ベース。
  • 数千万人規模の同時チャットを安定に処理。

13-5. Cisco — XMPP / 通信インフラ

  • 一部通信機器、IP 電話、コラボレーションツールのバックエンドに Erlang。
  • Cisco Webex の一部コンポーネントも Erlang を使っているとされる。

13-6. Akamai — DNS の一部

  • CDN 大手 Akamai が DNS インフラの一部に Erlang ベースのサービスを運用。
  • 秒間数十万クエリで BEAM の同時実行性が活きる。

ケーススタディの共通点

  • 死んではいけないシステム
  • 数万〜数百万の同時接続
  • メッセージング・リアルタイムプロトコル
  • 分散クラスタリング

CPU バウンドではなく、同時実行性バウンド が本質の会社たち。


第 14 章 · 韓国・日本 — 東アジアの BEAM

西洋圏では BEAM がよく知られているが、東アジアでの採用はどう見えるか。

14-1. 韓国 — カカオ、通信会社、一部スタートアップ

  • Kakao の一部メッセージング・通知インフラが時期によって Erlang/Elixir を採用。大規模な通知ファンアウトに BEAM モデルが適合。
  • Danggn (Carrot) — チャット・プッシュの一部で Elixir Phoenix を活用した事例(社内テックトークなどで言及)。
  • 通信会社 — KT、SK テレコムの一部通信インフラで Erlang ベースのミドルウェアを使用。ejabberd ベースのメッセージングシステムも。
  • スタートアップ・ゲーム会社 — 一部のモバイルゲームバックエンド(マッチメイキング、チャットサーバ)で Elixir 採用。

現実: 韓国で BEAM は主流ではない。しかしメッセージング・リアルタイムが本質の会社では、静かに使われている。

14-2. 日本 — ピクシブ、NTT、通信インフラ

  • ピクシブ — 一部メッセージング・通知システムで時期により Elixir/Erlang を採用。カンファレンス発表事例あり。
  • NTT — 通信インフラのバックボーンの一部に Erlang ベースのミドルウェア。通信機器メーカー NEC、富士通も同様に一部領域で。
  • DMM — 一部マイクロサービスで Elixir を試行。
  • Drecom などゲーム会社 — 一部のリアルタイムバックエンド。

14-3. 東アジアで BEAM 採用が遅く見える理由

  • リファレンス人材プールが小さい — Java、Go、Rust と比べて採用市場が狭い。
  • 教育で関数型言語に触れる機会が少ない
  • 韓国・日本の企業文化が保守的 — 実績のあるスタックを好む。(逆説的に BEAM は非常に実績があるが、東アジア市場の認知はそうではない。)
  • ただし メッセージング・リアルタイム・IoT の会社では、導入事例が地道に増えている。

第 15 章 · 誰が BEAM を選ぶべきか — 意思決定ガイド

最後に 2026 年時点で「このプロジェクトに BEAM は合うか?」を判断する実用ガイド。

15-1. BEAM が強い領域

  • リアルタイムメッセージング・チャット — Discord、WhatsApp、Slack バックエンドの一部。
  • メッセージブローカ — RabbitMQ が証明。
  • 長寿命の接続 — 大量同時の WebSocket、MQTT、SSE。
  • 分散システム — クラスタリングが最初から内蔵。
  • 耐障害性が必須のシステム — supervisor ツリー、"let it crash" 哲学。
  • プロトコルゲートウェイ — XMPP、AMQP、MQTT、通信シグナリング。
  • IoT バックエンド — 数万デバイスの同時接続。

15-2. BEAM が弱い領域

  • 数値計算・機械学習の学習 — CPU バウンドは NIF を経由する必要がある。
  • 単一スレッドのスループット — Go、Rust、C++ のほうが速い。
  • システムプログラミング — カーネル、ドライバ、ゲームエンジン。
  • デスクトップ GUI アプリ
  • 市場投入の速さ・採用のしやすさ — 人材が見つかりにくい。

15-3. 言語選択 — Erlang vs Elixir vs gleam

              Erlang              Elixir              gleam
型             動的                動的 (dialyzer)     静的
文法           Prolog 風           Ruby 風             Rust / Elm 風
エコシステム   古い、安定           最も活発            急成長
ツール         rebar3              mix (優れる)        gleam (簡潔)
主な用途       既存システム・OTP   新規 Web・Phoenix   新規型安全
学習曲線       文法ゆえに急        やわらかい           関数型経験者は速い

推奨:

  • 新規 BEAM プロジェクト、多くの場合 → Elixir。
  • 型安全性が重要 → gleam。
  • 既存 Erlang システムの維持・拡張 → Erlang。
  • 混ぜてもよい — 同じ BEAM 上で相互呼び出し可能。

15-4. HTTP サーバ選択

  • 新規 Phoenix → Bandit
  • 既存 Erlang/Cowboy スタック → Cowboy 3 を維持。
  • HTTP/3 が必要 → Cowboy 3

15-5. 分散データ選択

  • 小さなメタデータ、強い一貫性が必要 → Khepri
  • トランザクションの多いテーブルデータ、小規模クラスタ → Mnesia
  • キャッシュ・読み出し中心 → ETS (単一ノード) または外部 KV (Redis、FoundationDB)。
  • 本格的な OLTP/OLAP → 外部 DB (PostgreSQL、ClickHouse など)。

15-6. 組み込み選択

  • SBC (Pi、BeagleBone) → Nerves
  • MCU (ESP32、STM32) → AtomVM

第 16 章 · 結び — BEAM は消えない

40 年にわたり、BEAM は通信会社の秘密兵器から始まり、インターネットのメッセージングインフラの背骨となった。2026 年の BEAM は:

  • OTP 27 / 28 で今も磨かれ、
  • Cowboy 3 / Bandit で HTTP スタックが現代化され、
  • Khepri で分散データの弱点を埋めつつあり、
  • gleam で型安全のオプションを得て、
  • Nerves / AtomVM で組み込み領域まで拡大した。

BEAM の約束は変わらない — 「死なないシステム」。 30 年前に電話交換機が必要としたものは、2026 年の LLM 推論ゲートウェイ、メッセージキュー、IoT バックエンド、リアルタイム協業ツールにも同じく必要だ。

もしあなたのシステムが 「多数の接続を同時に維持し、絶対に死んではいけない」 種類のものなら、BEAM を真剣に検討する価値がある。メッセージングでも、決済でも、IoT でも、チャットでも。

BEAM は 30 年後にも、たぶん 50 年後にも、誰かのバックエンドで静かに動いているはずだ。


参考 / References