ブログ

認証サーバーのメモリ消費を20MB以下に抑える:Rustで自作して見えてきた軽量化のメリット

今回は、Your auth server shouldn’t cost more RAM than your entire app. So I wrote my own in Rust. という記事を読み、小規模プロジェクトにおける認証基盤のオーバーヘッドの問題が、実務でも非常に共感できる内容だったので紹介します。

Keycloak って結構重いんですねぇ。


認証サーバーが「重すぎる」という課題

システムを構築する際、認証機能は避けては通れない要素です。多くの場合、実績のある OSS(オープンソースソフトウェア)である Keycloak を選んだり、Auth0 や Clerk といった SaaS を利用したりするのが一般的かと思います。

しかし、個人開発や小規模なサイドプロジェクト、あるいは予算の限られた受託案件などの場合、これらの選択肢は「リソース消費」や「コスト」の面で壁にぶつかることがあります。

特にセルフホスト型の認証サーバーを運用する場合、メモリ消費量が大きなボトルネックになります。たとえば、月額 6 ドル程度の安価な VPS(メモリ 1GB 程度)でサービスを動かそうとすると、認証サーバーだけでメモリの大半を使い切ってしまうことも珍しくありません。

実際に、主要な認証ソリューションのアイドル時のメモリ消費量を比較してみると、以下のようなイメージになります。

主要な認証サーバーのメモリ消費量(目安)

ソリューション 言語・ランタイム 推定メモリ消費量(アイドル時) 特徴
Keycloak Java (JVM) 約 512MB〜 高機能だが、起動とメモリ消費が重い
Authentik Python/Go 約 700MB〜 サーバーとワーカーが必要で、Redis も併用
Zitadel Go 約 150MB〜 比較的新しく、他よりは軽量
自作(OVTL) Rust 20MB 未満 圧倒的に軽量で、安価な VPS でも余裕で動作

このように、多機能な OSS は便利である反面、小規模なアプリ本体よりも認証サーバーの方がリソースを食ってしまうという「主客転倒」な状況が起こりがちです。

なぜ Rust で自作するのか

元記事の筆者は、この課題を解決するために Rust を選択しました。単に「Rust が流行っているから」という理由ではなく、リソース制約の厳しい環境において、Rust には明確な優位性があるためです。

1. ガベージコレクション(GC)の不在

Java や Python、Go などの言語は、メモリ管理を自動化するためにガベージコレクターを備えています。これは開発効率を高めますが、一方で「いつ、どれだけメモリが解放されるか」の予測が難しく、ランタイムのオーバーヘッドも避けられません。

Rust は所有権モデルによるコンパイル時のメモリ管理を行うため、実行時のオーバーヘッドが極限まで抑えられます。

flowchart TD
    subgraph "一般的なランタイム (Java/Go等)"
        A[アプリ実行] --> B[メモリ確保]
        B --> C{GC発動?}
        C -- Yes --> D[一時停止・メモリ回収]
        C -- No --> A
    end

    subgraph "Rust"
        E[アプリ実行] --> F[スコープ終了時に即解放]
        F --> E
    end

2. セキュリティと安全性の両立

認証サーバーは、ユーザーの最も機密性の高い情報を扱う場所です。Rust の最大の武器は、メモリ安全性をコンパイル時に保証することです。バッファオーバーフローなどの脆弱性が入り込む隙を、設計段階で排除できるのは、セキュリティが求められるコンポーネントにおいて大きな安心材料になります。

3. 高速な起動

Rust でビルドされたバイナリは、JVM のような「ウォームアップ」を必要としません。1 秒未満で起動し、即座にリクエストを捌ける状態になります。これは、オートスケーリングや、リソースの限られた環境での再起動時に非常に有利に働きます。

セキュリティ設計のこだわり

単に「軽い」だけではなく、認証サーバーとしての堅牢性も重要です。元記事で紹介されている自作サーバー「OVTL」では、ゼロ知識暗号化の考え方が取り入れられています。

たとえば、パスワードのハッシュ化などは当然として、ユーザーの認証情報が万が一漏洩したとしても、サーバー側がその内容を知り得ないような設計を目指しています。

「認証の実行にかかるコスト」と「小規模プロジェクトが実際に支払える額」のギャップを埋めるためには、以下のような割り切りと最適化のバランスが必要になります。

  1. 必要最小限の機能に絞る: エンタープライズ向けの複雑すぎる設定項目(ドキュメントが迷宮化する原因)を削ぎ落とす。
  2. サードパーティへの依存を減らす: 外部の DB や Redis が必須な構成ではなく、単体でも動作する軽量さを追求する。

まとめ

今回の内容を振り返ると、以下のような結論になります。

  • Keycloak などの既存ツールは強力だが、小規模プロジェクトには重すぎる場合がある。
  • SaaS(Auth0/Clerk)は手軽だが、コスト増とデータのロックインが懸念される。
  • Rust を使うことで、メモリ消費を数十 MB 単位まで抑えつつ、高い安全性を確保できる。

「自分のアプリより認証サーバーの方が豪華なサーバーを必要としている」と感じたら、それはアーキテクチャを見直すタイミングかもしれません。Rust のようなシステムプログラミング言語を使って、用途に最適化した軽量なコンポーネントを導入してみるのも、一つの賢い選択肢ではないでしょうか。

こちらのようなアプローチは、今後のマイクロサービス開発においても、リソース効率を最大化するためのヒントになるかと思います。

参照記事