---
title: "冪等性とは？読み方・意味からAPI・IaCでの担保方法まで実装者向けに解説"
url: "https://www.issoh.co.jp/tech/details/13382/"
published: 2026-07-10
updated: 2026-09-16
categories: ["アーキテクチャ"]
publisher: "株式会社一創"
---

# 冪等性とは？読み方・意味からAPI・IaCでの担保方法まで実装者向けに解説

冪等性（べきとうせい）とは、同じ操作を1回だけ実行しても複数回繰り返しても、システムの結果が変わらない性質です。ネットワーク越しの通信では「送ったが応答が返らない」状況が避けられず、安全にリトライできるかどうかが信頼性を左右します。この記事で扱うのは、冪等性の読み方・英語表記・言葉の由来から、混同されやすい安全性や再現性との違い、HTTPメソッド別の冪等性の可否、Idempotency-Keyや一意キーによる担保の実装パターン、Ansible/Terraformなどインフラ自動化（IaC）での冪等性、そして担保すべき場面と怠った際の失敗パターンまでです。概念の説明だけで終わらせず、リクエスト例・SQL・Playbook・検証コマンドをそのまま写して動かせる形で置きました。HTTPメソッドの設計論そのものは判断ハブ記事へ、本記事は冪等性の概念と担保設計に絞ります。

## まとめ：冪等性は「安全にリトライできる」を支える設計上の土台

結論を先に示します。冪等性とは、**同じリクエストを何度実行しても副作用が1回分にとどまる性質**であり、通信失敗時に安心してリトライするための前提条件です。数式で言えば f(f(x)) = f(x)、つまり2回適用しても1回適用と結果が同じになる操作を「冪等」と呼びます。絶対値をとる操作 abs(abs(x)) = abs(x) が身近な例です。

実装者が押さえる勘所は3つに絞れます。第一に、HTTPメソッドには初めから冪等なもの（GET・PUT・DELETE）と非冪等なもの（POST）があり、RFC 9110がその区別を定義していること。第二に、非冪等な操作（決済・注文作成など）を安全にリトライしたい場合は、Idempotency-Keyや業務上の一意キーで「同じ操作の二重処理」をサーバー側で弾く設計を足すこと。第三に、冪等性は万能ではなく、カウンタの加算やログ追記のように「繰り返しに意味がある操作」まで無理に冪等化すると設計が歪むこと。まず「その操作は二重実行されたら困るか」を問い、困る操作にだけ担保コストをかける——これが優先順位です。

作業の順番も先に示します。①対象操作を洗い出して二重実行の被害額で並べる、②HTTPメソッドの選定で済む範囲は仕様どおりに寄せる、③残った非冪等な操作にキーとデータベース制約を入れる、④インフラは宣言的IaCへ移して再実行で検証する——この4手です。以降の章はこの順番に対応します。

## 冪等性の読み方と意味を押さえ、安全性・再現性との違いを切り分ける

まず言葉の意味を正確に固めます。冪等性は用語の誤読や、似た概念との取り違えが起きやすいため、境界を先に引いておくと後の設計判断がぶれません。

### 冪等性の読み方はべきとうせい・英語表記idempotencyの由来

冪等性は「べきとうせい」と読みます。「冪」は累乗（べき乗）の冪で、常用漢字外のため「べき等性」と交ぜ書きされることもあります。英語では idempotency（形容詞は idempotent）と表記し、ラテン語の idem（同じ）と potent（累乗・べき）を組み合わせた語です。もともとは数学・計算機科学の用語で、「何回適用しても最初の1回と同じ状態にとどまる」という累乗的な繰り返し不変性を表します。

言い換えれば「操作を重ねても状態が積み上がらない」性質です。検索では「冪等性 言い換え」「冪等性 意味」で調べられることが多いものの、単純な同義語で置き換えると精度が落ちます。「繰り返しに強い」「二重実行しても安全」といった説明を添えると、実務の文脈でも誤解なく伝わるはずです。設計レビューの場では「この操作は冪等か」ではなく「2回叩いたら何が増えるか」と聞くほうが早く結論が出ます。

### 1回でもn回でも結果が同じという定義を具体例で見分ける判定手順

形式的には、操作 f について f(f(x)) = f(x) が成り立つとき、f は冪等です。ポイントは「呼び出し回数によらず最終状態が同じ」であって、「毎回同じレスポンスが返る」ことまでは要求しない点にあります。たとえば「ユーザーIDが42のレコードを削除する」操作は、1回目で削除され、2回目以降は既に無いので状態は変わりません。レスポンスが1回目200・2回目404でも、サーバー側の最終状態が同一なら冪等です。

非冪等な操作の代表は「新しい注文を1件作成する」です。これは呼ぶたびに注文が増え、状態が積み上がります。判定は次の3問で足ります。①その操作は状態を「あるべき姿」に合わせるのか、それとも差分を足し込むのか。②2回目の実行でレコード件数や残高が変わるか。③外部への副作用（メール送信・決済確定・在庫引き当て）が2回起きるか。①で差分型、②③でいずれかがYesなら非冪等なので、後述のキーと制約が必要になります。

### 冪等性・安全性・再現性を切り分けて設計判断に落とす境界の引き方

冪等性は「安全性（safety）」「再現性（reproducibility）」としばしば混同されます。HTTPの文脈での安全性は「サーバーの状態を変えない読み取り専用の性質」で、GETやHEADが該当します。安全なメソッドは必ず冪等ですが、逆は成り立ちません。PUTやDELETEは状態を変える（＝安全ではない）が、何度実行しても最終状態は同じなので冪等です。「冪等性 再現性 違い」で調べられる再現性は、主にテストやデータ分析で「同じ入力・同じ環境なら同じ出力が得られる」ことを指し、副作用の回数不変を問う冪等性とは着眼点が異なります。

| 性質                | 問うこと            | 該当例            | 設計での使いどころ     |
| ----------------- | --------------- | -------------- | ------------- |
| 安全性（safe）         | サーバー状態を変えないか    | GET・HEAD（読み取り） | キャッシュ・事前取得の可否 |
| 冪等性（idempotent）   | 何回実行しても最終状態が同じか | PUT・DELETE・GET | 自動リトライの可否     |
| 再現性（reproducible） | 同じ入力で同じ出力が得られるか | ビルド・テスト・データ処理  | 検証環境の一致・デバッグ  |

設計で効くのは、安全性と冪等性を分けて考えることです。「読み取りだけか」「書き込むが繰り返しても増えないか」を別々に判定すると、メソッド選定とリトライ可否の判断が正確になります。分散環境では「同じ結果に落ち着くまでに時間差がある」ことも絡むため、[結果整合性と強整合性の違いを整理した解説](https://www.issoh.co.jp/tech/details/16287/)と合わせて読むと、リトライ後に古い値が見える理由まで説明が付きます。

## HTTPメソッドの冪等性をRFC 9110で確認しリトライ可否を決める

概念を固めたら、API設計での使い方に落とします。冪等性はREST APIのリトライ戦略と直結し、決済や在庫更新のような「二重処理が事故になる」領域でこそ効いてくる性質です。リトライを前提にした[非同期処理の仕組みと設計](https://www.issoh.co.jp/tech/details/13590/)では、この冪等性の担保が二重実行を防ぐ前提になります。

### GET・PUT・DELETE・POSTのメソッド別冪等性を表で確認する

HTTPの意味論を定めるRFC 9110（2022年公開のHTTP Semantics）は、[セクション9.2.2 Idempotent Methods](https://www.rfc-editor.org/rfc/rfc9110.html)で「PUT・DELETE、および安全なメソッドは冪等である」と定義しています。POSTは冪等ではなく、PATCHも仕様上は冪等性を保証しません。PUTは「このURIをこの内容にする」という絶対指定なので繰り返しても最終状態が一致し、DELETEは「このリソースを無い状態にする」ため同じく冪等です。POSTは「サブリソースを新規作成する」意味を持つため、呼ぶたびにリソースが増えます。

| メソッド     | 安全  | 冪等   | 自動リトライの判断   |
| -------- | --- | ---- | ----------- |
| GET・HEAD | はい  | はい   | そのまま再送してよい  |
| PUT      | いいえ | はい   | 同じ本文なら再送可   |
| DELETE   | いいえ | はい   | 404を成功扱いにする |
| POST     | いいえ | いいえ  | キー無しでの再送は不可 |
| PATCH    | いいえ | 保証なし | 差分表現の設計次第   |

この区別は「リトライしてよいメソッドか」の判断材料になります。ネットワークタイムアウトでGET・PUT・DELETEを再送するのは基本的に安全ですが、POSTの再送は二重作成を招く点に注意が必要です。メソッドの安全性・冪等性を踏まえたリソース指向のAPI設計全体は、[APIデザインパターンの基本とリソース指向設計を扱った解説](https://www.issoh.co.jp/tech/details/6261/)で判断ハブとして整理しています。URI設計やエラー応答まで含めたレビュー観点は[REST API設計のベストプラクティス](https://www.issoh.co.jp/tech/details/17225/)に切り出しました。再送そのものを誘発する上限超過の返し方は[レートリミットと429レスポンスの設計](https://www.issoh.co.jp/tech/details/16179/)で扱っています。

### RFC 9110がリトライ自動化に課す制約とプロキシ側の禁止事項

同じセクション9.2.2には、実装が守るべき条件も書かれています。クライアントは、非冪等なメソッドのリクエストを自動リトライすべきではなく（SHOULD NOT）、リトライしてよいのは「メソッドに関わらずリクエストの意味論が実際に冪等だと分かっている場合」か「元のリクエストが適用されなかったと検出できる場合」の2つだけです。プロキシは非冪等なリクエストを自動リトライしてはならず（MUST NOT）、自動リトライが失敗したときにさらに自動リトライを重ねることも避けるべきとされています。

実装上の含意は明快です。「意味論が実際に冪等だと分かっている」状態を自分で作れば、POSTでも再送してよくなります。それが次章の冪等性キーです。逆に、キーを用意せずクライアントのHTTPライブラリに再送設定だけ入れると、仕様が禁じている領域を踏むことになります。待機時間や試行回数の決め方そのものは[指数バックオフとリトライ予算の設計](https://www.issoh.co.jp/tech/details/16185/)にまとめました。

## 冪等性キーを実装して非冪等なPOSTを安全にリトライさせる手順

決済や注文のように本質的に非冪等な操作でも、安全にリトライしたい要求は強くあります。定石は、クライアントがリクエストごとに一意な冪等性キー（UUID等）を生成し、HTTPヘッダに載せて送る方式です。キーに使う[UUIDのバージョン選択と衝突確率](https://www.issoh.co.jp/tech/details/17545/)は、識別子そのものを扱った記事で整理しています。サーバーはそのキーと処理結果を記録しておき、同じキーの再送を受けたら新規処理をせず、初回と同じレスポンスを返します。

### Idempotency-Keyヘッダを付けてPOSTを再送する実装例

クライアント側でやることは、リクエスト単位で一意な値を作り、ヘッダに載せて、再送時も同じ値を使い回すことに尽きます。生成のたびに新しい値を振ってしまうと、サーバーは別の操作として受け付けてしまうため、キーは「リトライを含む1つの試行群」に紐づけて保持するのが決めごとです。生のHTTPで見ると次の形になります。

```
POST /v1/payments HTTP/1.1
Host: api.example.com
Content-Type: application/json
Idempotency-Key: 0f7c8b1e-4a2d-4c9b-9f31-2b6e5d8a7c40

{"order_no": "A-1001", "amount": 12000, "currency": "jpy"}
```

コマンドラインで動作を確かめるなら、同じキーで2回叩いて結果が一致するかを見ます。2回目のレスポンスが1回目と同一で、注文が1件しか増えていなければ担保できています。

```
KEY=0f7c8b1e-4a2d-4c9b-9f31-2b6e5d8a7c40

for i in 1 2; do
  curl -sS -X POST https://api.example.com/v1/payments \
    -H "Idempotency-Key: $KEY" \
    -H "Content-Type: application/json" \
    -d '{"order_no":"A-1001","amount":12000,"currency":"jpy"}' \
    -w '\nhttp_code=%{http_code}\n'
done
```

ヘッダ名 `Idempotency-Key` の標準化はIETFで議論されてきましたが、[draft-ietf-httpapi-idempotency-key-header](https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/) は07版で止まり、Datatracker上のステータスはExpired（失効・アーカイブ済み）です。RFC化されていない以上、よりどころは実装側のドキュメントになります。参照実装として広く読まれているのが[Stripeの冪等リクエスト仕様](https://docs.stripe.com/api/idempotent%5Frequests)で、そこには次の具体が明記されています。

- キーはクライアントが生成し、V4 UUIDなど衝突しない程度のエントロピーを持つ文字列を推奨（最長255文字）
- 初回リクエストのステータスコードと本文を保存し、成功・失敗にかかわらず同一キーの再送には同じ結果を返す（500エラーも再現される）
- キーは24時間以上経過したものから自動的に削除され、削除後に同じキーが来たら新規リクエストとして扱われる
- 同一キーで異なるパラメータが来た場合はエラーを返し、取り違えを検出する
- メールアドレスなど個人を特定できる値をキーに使わない。POSTのみが対象で、GET・DELETEに付けても効果はない

この5点は、自前APIの仕様を書くときの下敷きにそのまま使えます。とりわけ「失敗も含めて結果を再現する」「パラメータ不一致はエラー」の2つは、実装で抜けやすいところです。

### 受け側でキーと結果を保存し再送に同じ応答を返すテーブルの設計手順

サーバー側は、キーを主キーにしたテーブルを1枚用意し、そこへ「処理中」の行を先に挿入してから本処理へ進みます。先に挿入するのが要点で、挿入が主キー衝突で失敗した時点で「同じキーの再送」だと確定する仕組みです。アプリ層で存在確認してから挿入する順序にすると、確認と挿入の隙間に別リクエストが割り込んで二重処理が通ってしまいます。

```
CREATE TABLE idempotency_keys (
  idempotency_key text PRIMARY KEY,
  request_hash    text        NOT NULL,
  state           text        NOT NULL DEFAULT 'in_progress',
  status_code     integer,
  response_body   jsonb,
  created_at      timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idempotency_keys_created_at_idx
  ON idempotency_keys (created_at);

-- 初回だけ1行返り、再送は0行になる（0行なら保存済みの応答を返す）
INSERT INTO idempotency_keys (idempotency_key, request_hash)
VALUES ('0f7c8b1e-4a2d-4c9b-9f31-2b6e5d8a7c40', 'sha256:9c1f2ab4')
ON CONFLICT (idempotency_key) DO NOTHING
RETURNING idempotency_key;
```

`ON CONFLICT DO NOTHING` の挙動は[PostgreSQL公式のINSERT文リファレンス](https://www.postgresql.org/docs/current/sql-insert.html)に定義があり、競合ターゲットに一致する行があれば何もせず、RETURNINGは挿入された行だけを返します。したがって、0行が返ってきたら再送だと判定できるわけです。`request_hash` にリクエスト本文のハッシュを入れておけば、同じキーで違う内容が来たケースをエラーにできます。`created_at` に索引を張るのは、失効した行をまとめて削除するバッチのためです。ここまでの受け側の実装手順は[冪等キーの発行・保存・再生の実装解説](https://www.issoh.co.jp/tech/details/16293/)に、より細かい状態遷移まで含めて分解しました。

実装で決めておく残りは3点です。第一に、キーの生存期間（24時間で失効させ、以降の同一キーは別処理として扱う）。第二に、初回処理が完了する前に同一キーが再送された場合の返し方（409を返して待たせるか、初回完了までブロックするか）。第三に、キーと結びつけて保存する内容（レスポンス本文・ステータス・処理済みフラグ）。行ロックで待たせる方式を選ぶなら、[楽観ロックと悲観ロックの使い分け](https://www.issoh.co.jp/tech/details/5739/)の判断がそのまま効いてきます。

## データベースの一意制約とUPSERTで二重処理を止める実装手順

冪等性キー以外にも、サーバー側で冪等性を担保する定番の実装があります。「冪等性の担保」「冪等性チェック」で問われる実務の中身は、おおむね次の3系統です。

1. 業務的な一意キーにデータベースの一意制約を張り、二重INSERTを制約違反として弾く（注文番号・外部トランザクションIDなど）
2. INSERTかUPDATEかを「存在すれば更新・無ければ挿入」に統一するUPSERT（PostgreSQLの `ON CONFLICT` 等）で、再実行しても行が重複しないようにする
3. 状態遷移を検査し、「すでに確定済みの注文には確定処理を再適用しない」といった前提条件チェックで多重適用を防ぐ

### 一意制約とUPSERT・状態遷移チェックを1本のSQLに寄せる書き方

この3系統は別々に書くよりも、1本のSQLへまとめたほうが競合に強くなります。一意制約で行の重複を封じ、UPSERTで挿入と更新を統一し、WHERE句の状態条件で「確定済みへの再適用」を除外する、という組み立てです。

```
-- ①業務キーに一意制約を張り、二重INSERTを構造で封じる
CREATE UNIQUE INDEX orders_order_no_uniq ON orders (order_no);

-- ②③UPSERTに状態遷移条件を足し、確定済みへの再適用を除外する
INSERT INTO orders (order_no, amount, state, updated_at)
VALUES ('A-1001', 12000, 'confirmed', now())
ON CONFLICT (order_no) DO UPDATE
   SET amount     = EXCLUDED.amount,
       state      = EXCLUDED.state,
       updated_at = now()
 WHERE orders.state IS DISTINCT FROM 'confirmed'
RETURNING order_no, state;
```

このSQLは、初回は挿入し、再送では「確定済みなら何もしない」で終わります。ON CONFLICT の競合ターゲット指定やMERGE文との使い分けは[PostgreSQLのUPSERT実装を扱った解説](https://www.issoh.co.jp/tech/details/16978/)で整理しました。優先すべきはデータベースの一意制約です。アプリ層の「存在確認してから挿入する」ロジックは、同時実行下で確認と挿入の隙間に別リクエストが割り込むと破綻します。制約は競合時に必ず失敗するため、重複防止の最後の砦になります。

重複が生まれる側の事情も押さえておくと設計が早くなります。メッセージ配信で重複が起きる仕組みは[Outboxパターンとat-least-once配信](https://www.issoh.co.jp/tech/details/16177/)、外部サービスからの通知を二重に受ける場合の受け方は[決済Webhookの署名検証と冪等な注文確定](https://www.issoh.co.jp/tech/details/15734/)で扱いました。冪等性は「アプリのコードで頑張る」より「データ構造の制約で保証する」ほうが堅牢です。

## Ansibleの再実行とterraform planの差分で冪等性を検証する

ここからは判断を言い切ります。冪等性はAPIだけの話ではなく、インフラ自動化や分散処理でも設計の芯になります。ただし何にでも冪等性を求めればよいわけではありません。

### Ansible Playbookを2回流してchanged=0になるか確かめる

「ansible 冪等性」「terraform 冪等性」で調べられるように、インフラ構成管理（IaC）は冪等性を前提に設計されています。Ansibleは各モジュールが「あるべき状態」を宣言し、実行時に現状と比較して差分がある部分だけを変更します。すでに目的の状態なら何も変更しない（実行結果が changed=0 になる）ため、同じPlaybookを何度流しても構成が壊れません。IaCそのものの位置づけは[IaC（Infrastructure as Code）の仕組みと導入判断](https://www.issoh.co.jp/column/details/13004/)、ツール選定の前提は[Ansibleの基本概念と特徴](https://www.issoh.co.jp/tech/details/6533/)にまとめています。

この changed=0 になるかどうかを機械的に判定する工程が、Ansibleのテストフレームワークには用意されています。idempotenceステップの中身と、落ちたときに直す場所は[Ansible Moleculeとは？v26系のansible-native設定とmolecule testの実行手順](https://www.issoh.co.jp/tech/details/17630/)で説明しています。

問題になるのは、宣言的に書けないコマンドを埋め込む箇所です。Ansibleの `ansible.builtin.command` モジュールには `creates` というパラメータがあり、[公式のモジュールドキュメント](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command%5Fmodule.html)に「一致するファイルが既に存在する場合、このステップは実行されない」と定義されています。手続き的な処理はこのガードで囲むと、繰り返し実行に耐えます。

```
- name: 冪等なパッケージ導入と設定配置
  hosts: web
  become: true
  tasks:
    - name: nginxを宣言的に入れる
      ansible.builtin.package:
        name: nginx
        state: present

    - name: 設定を目標状態へ合わせる
      ansible.builtin.copy:
        src: files/nginx.conf
        dest: /etc/nginx/nginx.conf
        mode: "0644"

    - name: 手続き的コマンドはcreatesで再実行を抑える
      ansible.builtin.command:
        cmd: ./bin/init-db.sh
        creates: /var/lib/app/.db_initialized
```

検証は単純です。1回目で構成を作り、2回目を流して changed が0になるかを見ます。Terraform側は `-detailed-exitcode` を付けると差分の有無が終了コードで返るため、CIの判定にそのまま使えるはずです。[Terraform CLIのplanリファレンス](https://developer.hashicorp.com/terraform/cli/commands/plan)には「0＝差分なしで成功、1＝エラー、2＝差分ありで成功」と定義されています。

```
# 2回目でchanged=0なら冪等（--checkは変更せず差分だけ見る）
ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.yml --check --diff

# 終了コードで差分を判定（0=差分なし 1=エラー 2=差分あり）
terraform init -input=false
terraform apply -auto-approve
terraform plan -detailed-exitcode -input=false
echo "exit=$?"
```

2回目の `terraform plan` が0で終われば、構成は宣言どおりに収束しています。2が返るなら、コード側に「毎回変わる値」（タイムスタンプ、ランダムID、外部で書き換えられた属性）が混ざっている合図です。差分の読み方そのものは[terraform planの差分の読み方と安全手順](https://www.issoh.co.jp/tech/details/16531/)で分解しました。

### シェルスクリプトが非冪等になる箇所を宣言的な指定へ置き換える

シェルスクリプトで「ディレクトリを作成する」「設定に行を追記する」を素朴に書くと非冪等になりがちです。2回実行すれば既存エラーや重複追記が起きます。IaCの価値は、この手続き的な操作を「宣言的な状態指定」に置き換え、繰り返し実行しても安全にした点です。置き換えの型は決まっていて、ディレクトリ作成は state: directory、行の追記は lineinfile や template による全体上書き、サービス起動は state: started へ寄せます。

冪等な基盤なら、障害復旧やスケール時の再適用を恐れずに回せるのが強みです。運用の信頼性そのものを底上げする土台になります。信頼性を体系的に扱う考え方は[SRE（サイト信頼性エンジニアリング）の概要](https://www.issoh.co.jp/column/details/3080/)とあわせて捉えると、冪等性が運用設計のどこに効くかが見えてきます。

## 冪等性を担保すべき場面と過剰になる場面を線引きする実務上の基準

冪等性は「二重実行が事故になる操作」にだけ投資すべきで、すべての操作を冪等化しようとするのは過剰です。決済・在庫引き当て・ポイント付与・メール送信のように、多重実行が金銭や信用の損失に直結する操作は、コストをかけてでも担保します。一方、閲覧ログの追記やアクセスカウンタの加算のように「繰り返しに意味がある・重複しても実害が小さい」操作にまで冪等性キーの仕組みを持ち込むと、キー管理のオーバーヘッドだけが増えて割に合いません。

### 二重課金・キー肥大化・副作用残りという3つの失敗パターンを潰す

典型的な失敗パターンを挙げます。決済APIをPOSTで実装し、タイムアウト時にクライアントが自動リトライするのに、サーバー側に冪等性の担保が無いケースです。ユーザーの通信が不安定なだけで二重課金が発生し、返金対応と信用毀損に発展します。もう一つは、冪等性キーを受け取るのに失効期限を設けず、キー保存テーブルが無限に肥大化するケースです。「担保すべき操作を見極め、担保する操作には失効まで設計する」——この2点を外すと、冪等性は入れても機能しません。

三つ目として、冪等化したつもりで副作用が残るパターンにも触れておきます。データベースの書き込みだけをキーで守り、メール送信や外部API呼び出しをトランザクションの外に置いたままにすると、再送のたびに通知だけが飛ぶ構図です。副作用は「キーで守られた処理の内側」に寄せるか、送信履歴側にも一意制約を張るかのどちらかで封じます。補償処理を伴う長い業務フローなら、[Sagaパターンと補償トランザクションの設計](https://www.issoh.co.jp/tech/details/16175/)の枠組みで各ステップを冪等にするほうが見通しが良くなります。

### 冪等な基盤・APIを外部と組む際の設計移譲と支援の使いどころ

冪等性の担保は、単発のコードではなく「二重処理を許さないデータ設計・リトライ前提の通信設計・繰り返し安全なインフラ」という基盤全体の一貫性で決まります。既存システムに後から冪等性を足す場合、決済や在庫のような重要処理から一意制約とキー管理を整え、IaCで再現可能な形にインフラを移し替える、という順序が現実的です。ここを場当たりで進めると、一部だけ冪等・一部は非冪等という穴の残る構成になりがちです。メッセージ連携やストリーム処理で同じ問題を扱う場合は、[Exactly-onceの成立条件と受信側を冪等にする設計](https://www.issoh.co.jp/tech/details/16434/)も併せて確認してください。

繰り返し実行に強い冪等なインフラを、AnsibleやTerraformを用いたIaCで構築・整備したい場合は、[AWS/GCP/Azureのインフラ構築・IaC整備](https://www.issoh.co.jp/service/system/aws/)で、冪等性を前提とした基盤設計から運用の再現性確保までを一緒に組み立てられます。設計判断を社内に残す前提で伴走し、再適用を恐れず回せる状態まで引き渡すことを重視します。

## 冪等性の読み方・意味・担保・IaC設計についてよくある質問への回答

冪等性を実務へ落とし込む際に、検索でよく問われる論点を5つ取り上げます。

### 冪等性の読み方と英語表記は？

「べきとうせい」と読みます。「冪」は累乗（べき乗）を意味する漢字で、常用漢字外のため「べき等性」と交ぜ書きされることもあります。英語表記は idempotency（形容詞 idempotent）で、ラテン語の idem（同じ）と potent（べき）に由来する語です。数学・計算機科学では「何回適用しても最初の1回と結果が同じ」性質を指す用語として使われてきました。

### 冪等性と再現性・安全性の違いは何ですか？

着眼点が異なります。安全性はHTTPで「サーバー状態を変えない読み取り専用か」を、冪等性は「何回実行しても最終状態が同じか」を、再現性は主にテストやデータ処理で「同じ入力から同じ出力が得られるか」を問います。安全なメソッド（GET等）は必ず冪等ですが、冪等なメソッド（PUT・DELETE）は状態を変えるため安全ではありません。3つを混同せず、別々に判定するのが設計のコツです。

### POSTを冪等にすることはできますか？

POSTメソッド自体は仕様上非冪等ですが、冪等性キー（Idempotency-Key）を使えば実質的に冪等な振る舞いにできます。RFC 9110のセクション9.2.2も、メソッドに関わらず「リクエストの意味論が実際に冪等だと分かっている」場合の自動リトライは許容する立場です。クライアントが一意キーを付けて送り、サーバーが同じキーの再送に対して新規処理をせず初回と同じ結果を返す仕組みを用意すれば、この条件を満たせます。キーの失効期間と同時実行時の排他制御まで設計して初めて機能します。

### 冪等性キーはどのように発行・保持すればよいですか？

クライアントがリクエストごとにV4 UUIDなどの一意な値を生成し、HTTPヘッダに載せて送ります。サーバーはキーを主キーにした行を先に挿入し、ステータス・レスポンス本文・処理済みフラグを保存して、同一キーの再送時はそれをそのまま返す形です。Stripeの公式ドキュメントでは、キーは最長255文字・24時間以上経過した分から削除・同一キーで異なるパラメータならエラー、という運用が示されています。自前APIでも失効期間と排他制御を含めて仕様に書き下すのが実務です。

### Ansibleで「冪等性がない」とはどういう状態ですか？

同じPlaybookを2回目に実行したときに、1回目と違う変更が起きたりエラーになったりする状態を指します。Ansibleのモジュールは「あるべき状態」を宣言し、現状と一致していれば変更しない（changed=0）設計が基本です。ところがcommandやshellモジュールで手続き的なコマンド（追記・作成など）を直接実行すると、繰り返しで重複や失敗が生じ冪等性が崩れます。冪等性を保つには、状態を宣言できる専用モジュールを使うか、公式ドキュメントにある creates・removes のような条件を付けて実行そのものを抑えます。

## 関連記事

- [APIデザインパターンの基本とリソース指向設計の重要性](https://www.issoh.co.jp/tech/details/6261/)：HTTPメソッドの安全性・冪等性を踏まえたリソース指向のAPI設計全体を判断ハブとして詳説
- [冪等キーとは？Idempotency-Keyの発行・保存・再生の実装と二重課金の止め方](https://www.issoh.co.jp/tech/details/16293/)：本記事の担保パターンを受け側の実装手順まで分解
- [PostgreSQLのUPSERT実装｜ON CONFLICTの競合ターゲット指定とMERGE文の使い分け](https://www.issoh.co.jp/tech/details/16978/)：一意制約とUPSERTでの担保をSQLレベルで詳説
- [SRE（サイト信頼性エンジニアリング）とは何か？その概要と重要性](https://www.issoh.co.jp/column/details/3080/)：冪等性が支えるリトライ安全性・運用の信頼性設計を体系的に整理

---

出典: [冪等性とは？読み方・意味からAPI・IaCでの担保方法まで実装者向けに解説](<https://www.issoh.co.jp/tech/details/13382/>)（株式会社一創）
