【比較】ステートフルとステートレスの違い¶
概要¶
「ステートフル(stateful)」と「ステートレス(stateless)」は、サーバや通信が過去のやり取りの文脈(状態)を覚えているかどうかを表す設計上の性質です。ステートフルはサーバ側に会話の状態を保持し、ステートレスは各リクエストが必要な情報を自己完結的に含み、サーバは前回までの文脈に依存しません。
混同が起きやすいのは「ステートレス=状態がどこにもない」と誤読されやすい点です。実際にはステートレスでも状態は存在し、その置き場所がサーバ側ではなくクライアント/リクエスト側になるだけです。REST の提唱者 Roy Fielding の博士論文や HTTP の仕様(RFC 9110)が、この性質を明確に定義しています。
詳細比較¶
| 項目 | ステートフル (Stateful) | ステートレス (Stateless) |
|---|---|---|
| 状態の保持場所 | サーバ側にセッション/会話状態を保持 | サーバ側に保持しない。状態はクライアントまたはリクエスト自体に含める |
| リクエストの自己完結性 | 前のやり取りの文脈に依存し得る | 各リクエストが処理に必要な情報をすべて含む |
| スケーラビリティ | サーバ間で状態共有が必要で水平スケールが難しい | どのサーバでも処理でき水平スケールしやすい |
| 障害復旧 | 状態を持つサーバが落ちると会話が失われやすい | リクエスト単位で再実行・再ルーティングしやすく回復性が高い |
| 可視性(運用監視) | 1リクエスト単体では意味が判断しづらい | 1リクエストを見れば内容を理解できる |
| ネットワーク効率 | 反復データを再送しないため効率的になり得る | 毎回コンテキストを送るため反復データが増えうる(トレードオフ) |
| 代表例 | WebSocket 接続、DB トランザクション、FTP セッション、ステートフルなアプリサーバ | HTTP/REST API、DNS クエリ、純粋関数、ステートレスなマイクロサービス |
Roy Fielding の博士論文(REST、5.1.3 client-stateless-server)は「each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server」と定義し、セッション状態は完全にクライアント側に置くとしています。RFC 9110 も「HTTP is defined as a stateless protocol」と明記し、各リクエストのセマンティクスは単独で解釈できるとしています。
よくある誤解¶
-
「ステートレス=状態がまったく存在しない」は誤り。 ステートレスは「サーバが会話の文脈を保持しない」という意味であり、状態自体は存在します。Fielding の定義どおり、セッション状態はクライアント側(トークン、Cookie、リクエストパラメータ)に置かれます。さらにステートレス API でもデータベースに永続化される業務データ(リソース状態)はあり、これは「会話状態(session state)」とは区別されます。
-
「REST/HTTP はステートレスだから認証セッションは持てない」は誤り。 ステートレスでも認証は成立します。各リクエストにトークン(例: 署名済みトークン)を載せ、サーバはそれを検証するだけにすれば、サーバ側にセッションを保持せずに認証付き API を作れます。「サーバがセッションを覚える」のではなく「リクエストが資格情報を毎回運ぶ」だけです。
-
「ステートレスは常に優れている」は誤り。 ステートレスはスケーラビリティ・回復性・可視性で有利な一方、Fielding 自身が指摘するとおり毎回コンテキストを送るためネットワーク効率が落ちうるトレードオフがあります。低遅延の双方向通信やトランザクション境界が重要な場面ではステートフル(WebSocket、DB トランザクション)が適切です。
実務での選び分け¶
- 水平スケール・自動復旧・ロードバランサ配下で動かしたい → ステートレス設計。状態はトークン/DB/外部ストア(Redis 等)に外出しし、アプリサーバ自体は状態を持たない。
- 低遅延の双方向リアルタイム通信(チャット、通知、ゲーム) → ステートフルな永続接続(WebSocket)が自然。
- 一連の操作を原子的にまとめたい(決済、在庫引当) → DB トランザクションというステートフルな境界を使う。
- マイクロサービス/サーバレス → 各インスタンスが使い捨てになるためステートレスが前提。状態は必ず外部ストアへ。
- 判断の原則 → 「会話状態(session state)」はできるだけクライアント/外部ストアへ追い出し、アプリサーバはステートレスに保つと運用が楽になる。本当に接続を張り続ける必要があるところだけステートフルにする。
ひとことまとめ¶
ステートフルは「サーバが会話の文脈を覚えている」、ステートレスは「各リクエストが自己完結し、サーバは前回の文脈に依存しない」設計であり、ステートレスでも状態は消えず置き場所がクライアント/外部ストアに移るだけです。
出典・参考¶
- Fielding 博士論文 CHAPTER 5: Representational State Transfer (REST) — 5.1.3 client-stateless-server 制約の原典定義(each request must contain all information)
- RFC 9110 — HTTP Semantics — 「HTTP is defined as a stateless protocol」と Cookie 等は別仕様での状態管理