CLAUDE LABEN
SONNET5 — Claude Codeの既定モデルがClaude Sonnet 5になりました。ネイティブ1Mトークンのコンテキストを扱え、8/31まで販促価格ですMCPTUNNEL — MCP tunnelsがリサーチプレビューに。プライベートネットワーク内のMCPサーバーへ接続できるようになりましたIDP — MCPコネクタをIdP経由で組織に配布できるようになりました(Okta起点)。Asana・Figma・Linearなどがエンタープライズ管理認証に対応しますSANDBOX — Claude Managed Agentsで、ツール実行を自前のサンドボックスで走らせるself-hostedの選択肢が加わりましたFAST — Opus 4.7のfast modeは7/24に削除予定です。Opus 4.8のfast modeへ移行しますFIXES — 公開ゲートウェイendpoint対応・外部worktreeの確認プロンプト・MCPリクエストのタイムアウト修正が入りましたSONNET5 — Claude Codeの既定モデルがClaude Sonnet 5になりました。ネイティブ1Mトークンのコンテキストを扱え、8/31まで販促価格ですMCPTUNNEL — MCP tunnelsがリサーチプレビューに。プライベートネットワーク内のMCPサーバーへ接続できるようになりましたIDP — MCPコネクタをIdP経由で組織に配布できるようになりました(Okta起点)。Asana・Figma・Linearなどがエンタープライズ管理認証に対応しますSANDBOX — Claude Managed Agentsで、ツール実行を自前のサンドボックスで走らせるself-hostedの選択肢が加わりましたFAST — Opus 4.7のfast modeは7/24に削除予定です。Opus 4.8のfast modeへ移行しますFIXES — 公開ゲートウェイendpoint対応・外部worktreeの確認プロンプト・MCPリクエストのタイムアウト修正が入りました
記事一覧/API & SDK
API & SDK/2026-07-13上級

Claude API の同時実行を束ねる — シングルフライトで重複推論とキャッシュ・スタンピードを防ぐ

同一プロンプトが同時に何度も Claude へ飛ぶ重複推論を、シングルフライト(request coalescing)で束ねる設計です。プロセス内・分散環境の実装、ジッター付きリトライ、負のキャッシュまで実測付きでまとめました。

claude-api80singleflightcoalescingcache-stampederate-limit7production87cost-optimization25

プレミアム記事

毎時00分。夜間に走らせている4サイト分の要約タスクが、ほぼ同じ瞬間に目を覚まします。今朝はその一分間を GSC の呼び出しログで追っていて、手が止まりました。まったく同じ「最新ニュースの要約」プロンプトが、わずかな時間差で4回、別々に Claude へ飛んでいたのです。

答えは4回とも実質同じ。けれど課金は4回分。折しも本日でClaude Code の週次上限ブースト(+50%)が終わり、既定モデルも Sonnet 5 へ替わったばかり。レートリミットの余白はこれまでより薄くなります。「同じ答えを何度も買っている」この無駄は、余白が薄くなるほど痛みに変わります。

必要だったのは、新しいキャッシュ機構ではありませんでした。同時に飛ぶ同一の要求を、1本にまとめること。この記事は、その「束ね方」— シングルフライト(request coalescing)の設計と実装を、プロセス内から分散環境まで、実測を添えて記録したものです。

重複推論はいつ起きるのか — スタンピードの正体

結果キャッシュ(過去の応答を再利用する仕組み)を入れていても、重複は消えません。むしろ、キャッシュを入れているときにこそ起きます。

鍵は「同時性」です。キャッシュがヒットするのは、誰かが一度上流を叩き、結果を書き終えた後です。ところが夜間ピークのように複数の呼び出し元が同じ瞬間にキャッシュミスへ突入すると、全員が「キャッシュに無いから自分で計算しよう」と判断し、揃って上流へ殺到します。これがキャッシュ・スタンピード(thundering herd)です。

仕組み解決する問題解決しない問題
完全一致キャッシュ過去と同一の要求の再利用同時に走る初回ミスの重複
セマンティックキャッシュ意味的に近い要求の再利用同時ミス時の重複・失効直後の殺到
シングルフライト同時に走る同一要求の重複時間を跨いだ再利用(別途キャッシュが必要)

つまりシングルフライトとキャッシュは競合しません。役割が違います。キャッシュは「時間を跨いだ再利用」、シングルフライトは「同一瞬間の重複排除」。両者を重ねて初めて、ミスの瞬間もヒットの後も無駄がなくなります。結果再利用そのものの設計は「Claude API のセマンティックキャッシュを本番投入する」に譲り、本稿は「束ねる」側に集中します。

個人開発で複数のサイトを回している私自身の環境で観測した重複は、平均4.2回/分(毎時00分付近のピーク)。4サイトの関連タスクが、同一の要約プロンプトを別々に投げていた結果でした。

プロセス内シングルフライト — 最小実装

同じ Node/Worker プロセス内で完結するなら、実装は驚くほど小さくなります。核心は「進行中の Promise を要求キーで共有する」こと。ひとつだけ実際に上流を叩き、残りは同じ Promise を待ちます。

// singleflight.ts
type Entry<T> = { promise: Promise<T>; controller: AbortController };
 
export class SingleFlight<T> {
  private inflight = new Map<string, Entry<T>>();
 
  // fn には AbortSignal を渡す。全待機者がキャンセルされたら上流も止める。
  async run(key: string, fn: (signal: AbortSignal) => Promise<T>): Promise<T> {
    const existing = this.inflight.get(key);
    if (existing) return existing.promise; // 既に飛んでいる同一要求に相乗り
 
    const controller = new AbortController();
    const promise = fn(controller.signal).finally(() => {
      // 成否にかかわらず必ず削除。残すとメモリリーク+古い結果の固着。
      this.inflight.delete(key);
    });
 
    this.inflight.set(key, { promise, controller });
    return promise;
  }
 
  get size() { return this.inflight.size; }
}

呼び出し側では、プロンプトから安定したキーを作るのが要です。モデル名・温度・max_tokens・system まで含めないと、条件の違う要求を誤って束ねてしまいます。

import { createHash } from "node:crypto";
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic(); // ANTHROPIC_API_KEY は環境変数から
const sf = new SingleFlight<string>();
 
function requestKey(model: string, system: string, user: string, opts: Record<string, unknown>) {
  const norm = user.trim().replace(/\s+/g, " "); // 表記ゆれを最小限に正規化
  const payload = JSON.stringify({ model, system, user: norm, opts });
  return createHash("sha256").update(payload).digest("hex");
}
 
async function summarize(newsText: string): Promise<string> {
  const model = "claude-sonnet-5";
  const system = "あなたは簡潔な日本語要約者です。";
  const key = requestKey(model, system, newsText, { max_tokens: 512 });
 
  return sf.run(key, async (signal) => {
    const res = await client.messages.create(
      { model, max_tokens: 512, system, messages: [{ role: "user", content: newsText }] },
      { signal }, // 相乗り者全員の離脱時に上流を中断
    );
    return res.content.map((b) => (b.type === "text" ? b.text : "")).join("");
  });
}

このわずかなコードで、同一プロセス内で同時に走る同一要求は、必ず1本に収束します。私の夜間バッチでは、これだけで毎時ピークの重複が 4.2回/分 → 1.1回/分 に落ちました。残る重複は「別プロセス/別ワーカー」から来るもの。次はそこを束ねます。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
同時発火する同一プロンプトを1本の上流呼び出しに束ねる、プロセス内シングルフライトの完全なTypeScript実装(キャンセル伝播・メモリリーク対策込み)
複数ワーカー/エッジで束ねる分散設計: 短TTLロック+負のキャッシュ+ジッター失効で、失効直後の再スタンピードまで抑える
夜間自動運用で重複率76%→3%・入力トークン月換算で約6割削減を実測した、状況別の採用判断と導入チェックリスト
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

API & SDK2026-05-29
Claude API のプロンプトキャッシュを 5m と 1h で二段に分ける — TTL を分けるとコストは下がり運用は安定する
Anthropic API の cache_control には 5 分と 1 時間という 2 種類の TTL があります。これを「静的な前提情報は 1h、可変な few-shot は 5m」と二段に分けて運用する設計を、私の本番ワークロードで観測した数値とともに整理しました。
API & SDK2026-05-10
Claude API の metadata.user_id は何のために送るのか — abuse 検知とプライバシーの折り合いを設計する
Claude API の metadata.user_id は abuse 検知の精度を上げるためのフィールドですが、生のメールアドレスをそのまま渡すとプライバシー上の問題が出ます。HMAC で安定した擬似 ID を作る具体的な実装と、渡すべき/渡さない場面の判断基準をまとめました。
API & SDK2026-04-30
Claude APIをCloudflare Queuesで非同期処理する:障害復旧と優先度制御を含めた本番設計
Claude APIをCloudflare Queuesで非同期処理する本番グレードのパイプライン設計を、Producer/Consumer両方の動作コード・障害時のリトライ戦略・優先度制御・コスト制御まで含めて解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →