
1 つのサーバーで 60 のコンテナ
1 つのベアメタルボックスで数十から数百の Hoody コンテナを実行。KSM と BTRFS のデデュプでマージナルコストはほぼゼロ。
本物の Stripe webhook を hoody-files の URL に 30 分間向けます。ディレクトリには 14 個の JSON ファイルが入ります。本番に届いたペイロードがバイト単位でそのまま揃っています。1 つの cron エントリが exec スクリプトを動かし、月曜から金曜の 9 時にステージングへ POST し直します。スケジュールは次の土曜日に失効し、自分で消えます。
{ "id": "evt_3OHk8ZJs2k9aXq1vQ", "type": "payment_intent.succeeded", "created": 1714723522, "data": { "object": { "id": "pi_3OHk8ZJs2k9aXq1v0K7rT4mB", "amount": 4900, "currency": "usd", "status": "succeeded" } } }
本物の webhook がキャプチャ · cron エントリ 1 つでリプレイ
全体の流れは URL が 3 つだけです。本番トラフィックがキャプチャ URL に到着します。ファイルは hoody-files に置かれます。cron がフォルダを巡回し、本文をステージングへ POST し直します。ブローカーもキューもリプレイサービスもありません。ディレクトリとスケジュールだけです。
Stripe / Intercom / GitHub の webhook URL を hoody-files のパスに設定します。各イベントは PUT として届き、タイムスタンプを名前にした JSON ファイルとして保存されます。ディレクトリそのものが録画です。
ファイルはディスクに永続化され、各ファイルに独自 URL が付きます。ブラウザでディレクトリを閲覧したり、API でリストしたり、curl でシェルアクセスできます。録画は cat、scp、バージョン管理できる事実です。
スケジュール 0 9 * * 1-5、コマンド bash /scripts/replay.sh /webhooks/2026-05-03 で管理 cron エントリを POST します。スクリプトはディレクトリを一覧し、各ファイルをタイムスタンプ順でステージングに POST し直します。
キャプチャとリプレイは、別の日に走る同じプロトコルです。バイトを記録した仕組みが、そのまま再生する仕組みになります。学ぶべき JSONL パーサーもサイドカーも録画フォーマットもありません。フォルダの中のファイルが、時系列順に並んでいるだけです。
キャプチャは webhook イベントごとの PUT 1 回。リプレイは cron API への POST 1 回。Hoody Files が録画を保持し、Hoody Cron がスケジュールに沿って巡回し、hoody-exec が POST を行う bash スクリプトを実行します。3 つのサービス、間に貼り付けるグルーコードはありません。
# point your real webhook at hoody-files curl -X PUT \ https://files.containers.hoody.com/webhooks/2026-05-03/stripe-08-15-22.json \ --data-binary @- # 30 minutes later, the directory holds 14 files HTTP/1.1 201 Created webhooks/2026-05-03/stripe-08-15-22.json
# one cron entry replays the morning at 9am, mon-fri curl -X POST \ https://cron.containers.hoody.com/api/v1/cron/users/me/entries \ -d '["schedule":"0 9 * * 1-5","command":"bash /scripts/replay.sh /webhooks/2026-05-03","expires_at":"2026-05-10T09:00:00Z"]' HTTP/1.1 201 Created { "id":"f0a8", "schedule":"0 9 * * 1-5", "expires_at":"2026-05-10T09:00:00Z" }
キャプチャ側は金曜の朝に 1 度だけ動きます。リプレイ側は次の土曜まで毎平日動き続け、cron エントリの expires_at フィールドがスケジュールを削除します。webhook 設定に PUT URL を 1 つ書き、cron API に POST を 1 回投げる。それで負荷テストの全体です。
合成トラフィックは、リクエストがどう見えるかを想像したものです。キャプチャ済みトラフィックは、実際に届いたものです。同じフィールド名、同じエッジケース、同じ意外性です。
録画には Stripe が送ったままの JSON が記録されています。null になり得る各フィールド、想定外のイベント種別、忘れていた customer_id の形式まで含まれます。あなたのハンドラは、昨日失敗したのと同じペイロードに再び向き合えます。
cron 式 0 9 * * 1-5 は、本物のユーザーが実際にシステムを使う時間帯にリプレイを着地させます。テスト中のハンドラは、同じキャッシュ、同じ cron の隣人たち、同じ騒がしい DB を相手にした朝のラッシュを目にします。
フォルダはイミュータブルで、cron は expires_at まで毎平日動きます。火曜の実行でハンドラがまだ落ちるなら、修正して水曜の実行に証明させます。入力は毎回同じ、変わるのはハンドラだけです。
数字は Hoody Cron の管理エントリ API と標準 cron 式仕様に基づきます。架空のベンチマークではありません。
標準の 5 フィールド cron 式: 分、時、日、月、曜日。1985 年に使った構文が、2026 年も同じようにリプレイをスケジュールします。
GET /users/[user]/entries は最大 200 件の管理エントリを 1 ページで返します。1 環境あたり 63 個のリプレイスケジュールでも余裕です。
POST /users/me/entries 1 回で、スケジュール、コマンド、expires_at を指定して定期リプレイを作成できます。後で PATCH してミュート、DELETE で廃止、expires_at に任せれば自動廃止です。
Hoody Cron Managed Entries API の仕様: 標準 5 フィールド cron 式と @daily / @hourly マクロ、1 ページあたり最大 200 エントリのページネーション、expires_at はオプションで、期限を過ぎるとエントリを自動的に無効化します。
本番トラフィックを 1 度録画し、スケジュールでリプレイ。
webhook トラフィックをリプレイするための定番ツール群、レコーダー、リプレイサービス、スケジュールモック。それぞれ SaaS、サイドカー、面倒を見るスクリプトのいずれかです。hoody-files + hoody-cron の組み合わせは、そのどれでもありません。
金曜のトラフィックをキャプチャ。来週のリプレイをスケジュール。実験が終わったら cron エントリ自身に失効させましょう。