n8nのWaitノードとWebhookタイムアウトのイメージ画像

n8nのWaitノードで64秒以上待機させると、なぜかWebhookの応答が届かず処理が止まってしまう…そんな経験はありませんか?実は多くの実践者が、この「64秒の壁」に気づかずに詰まっています。

そこで今回は、実際の検証環境で「n8n Wait ノード タイムアウト」問題の原因調査と解決策の検証を行ってみました!設計変更自体はシンプルですので、ぜひ皆さんも記事を読んで試してみてください!

この記事で分かること

  • Waitノードで64秒を超えるとタイムアウトが発生する仕組み
  • 原因を切り分ける2つのケースの見分け方
  • 実際のノード設定・expressionを使った3つの解決方法

Waitノードで64秒以上のタイムアウトが起きる仕組み

n8nのWebhookノードには、応答待機に関する仕様上の上限があります。この上限が、いわゆる「64秒の壁」の正体です。

Wait時間が64秒未満の場合、n8nは実行中のプロセスをメモリ上に保持し、Webhookの接続を開いたまま待機します。しかし64秒前後を超えると、実行データはメモリからデータベースへオフロードされ、初期のWebhook接続そのものが切断されます。

つまり[Webhook]→[Wait]の間で処理自体は正常に継続していても、接続が切断されているため、後続の[Respond to Webhook]が応答を返す先を失ってしまうのです。これが「n8n Respond to Webhook 動かない」現象の典型的な原因です。

この仕様は、長時間の処理でHTTP接続を占有し続けることを防ぐための意図的な設計です。したがって、環境変数やノード設定だけで単純に回避できるものではなく、ワークフロー構成そのものを見直す必要があります。

原因を切り分ける2つのケース

「n8n 64秒」のタイムアウトは、実は2つの異なるケースが原因として存在します。まずはどちらに該当するかを切り分けましょう。

同一実行内でWaitノードが長時間待機しているケース

最も多いのがこのケースです。同じワークフロー実行内で[Webhook]→[Wait]→[Respond to Webhook]という構成にしていて、Waitの待機時間が64秒を超えている状態です。

この場合、外部システムからのリクエストに対して、n8nが処理完了まで応答を保留しようとしてしまいます。実行ログを確認すると、ワークフロー自体は正常終了しているのに、リクエスト元にはタイムアウトエラーが返っていることが多いです。

見分け方は簡単です。n8nの実行履歴(Executions)で該当のRunを開き、Waitノードにマウスを合わせると経過時間が表示されます。この数値が64秒を明確に超えていれば、このケースが確定です。

外部サービス側のWebhookタイムアウト設定が短いケース

もう一つは、n8n側ではなく、リクエストを送っている外部サービス(連携先API、フロントエンド、リバースプロキシなど)のタイムアウト設定が短いケースです。

例えばNginxのproxy_read_timeoutや、外部SaaSのHTTPクライアント側のタイムアウトがデフォルト30〜60秒程度に設定されていると、n8n自体が応答できても、その手前で接続が切られてしまいます。

切り分け方は、n8nの実行履歴で処理自体が正常完了しているかを確認することです。処理は完了しているのに呼び出し元でエラーが出る場合は、このケースに該当します。

解決する3つの方法

「64秒の壁」を回避する現実的な方法は、いずれも「同期処理を非同期処理に切り替える」という発想に集約されます。具体的な設定値まで示します。

最初のWebhookで即座に200 OKを返し非同期で処理を継続する設計手順

最もシンプルで再現性の高い方法です。Webhookノードを開き、「Respond」の項目を以下のように変更します。

  • Respond:「Immediately」に設定
  • Response Code:202(受付済みであることを明示する場合)または200
  • Response Data:任意のJSON(例:{"status":"accepted"})
[Webhook (Respond: Immediately, Response Code: 202)]
 →[Wait (外部処理待ち・64秒超も可)]
 →[HTTP Request (処理結果を外部に送信)]

この設定にすると、n8nはリクエストを受け取った瞬間に応答を返し、接続をすぐに閉じます。そのため後段のWaitがどれだけ長くても、初期接続のタイムアウトは発生しません。処理結果は、HTTP Requestノードで呼び出し元のコールバックURLやSlack、DBなどへ別途送信します。

別のWebhookで処理完了後に再開する設計例

外部サービス側からのコールバック(Webhook通知)を受け取れる場合は、Waitノードの「Resume On Webhook Call」機能を使います。実装手順は以下の通りです。

[Webhook A (受付, Respond: Immediately)]
 →[Set (変数 wait_url に {{$execution.resumeUrl}} を格納)]
 →[HTTP Request (外部サービスへ wait_url を送信)]
 →[Wait (Resume On Webhook Call)]
 →[HTTP Request (最終結果をクライアントへ送信)]

(別トリガー)
[Webhook B (外部サービスの完了通知を受信)]→ Wait ノードのURLに直接POSTすることで自動的に処理が再開されます

ポイントは、Waitノードより前に配置したSetノードで{{$execution.resumeUrl}}というexpressionを使い、実行ごとに動的に発行されるresume用URLを取得することです。このURLを外部サービスに渡しておけば、外部サービスがそのURLへコールバックした瞬間にWaitノードが再開されます。64秒を超える待機でも接続を保持し続けないため安全です。

なお、Waitノードは固定のURLを持たず、実行のたびに異なるURLが発行される点に注意してください。常に同じURLを使いたい場合は、Waitノードではなく別ワークフローの固定パスWebhookを使う構成に変更するとよいでしょう。

外部サービスがポーリングで進捗確認する設計への変更

外部サービスがコールバックを実装できない場合は、ポーリング方式への変更が現実的です。具体的な構成は以下の通りです。

[Webhook (受付, Respond: Immediately)]
 →[Set (jobId = {{$execution.id}} を生成)]
 →[DB挿入 (jobId, status: "processing" を保存)]
 →[Respond to Webhook を使わず即時応答済みのJSONを返却 例:{"jobId":"abc123","status":"processing"}]

(別ワークフロー:状態確認用)
[Webhook (ステータス確認, Path: /status/:jobId)]
 →[DB検索 (jobIdでstatusを取得)]
 →[Respond to Webhook (取得したstatusをJSONで返却)]

最初のWebhookでは処理を受け付けたことと一意のjobIdだけを即座に返し、実際の重い処理はバックグラウンドで継続します。外部サービスは、そのjobIdを使って別エンドポイントに数秒おきに問い合わせ、進捗や結果を取得します。

この設計は実装コストが上がりますが、64秒どころか数分〜数時間の処理にも対応できるため、最も汎用性の高い解決策です。

非同期設計を安定させる運用のコツ

非同期化した後も、安定運用のためにいくつか押さえておきたいポイントがあります。

  • Setノードで取得したresumeUrlやjobIdは、発行時刻と一緒にDBやNoOpノードで記録し、後から追跡できるようにする
  • 環境変数N8N_WEBHOOK_TTLのような設定が紹介される場合がありますが、公式ドキュメントに存在しない非公式な設定であり、動作が不安定という報告があるため恒久対策には使わない
  • Nginxなど手前にリバースプロキシがある場合は、proxy_read_timeoutなどタイムアウト関連の設定値も、n8n側の設計変更と合わせて見直す
  • 大量アクセスが想定される場合はqueue modeを検討し、Webhook受付とWorkflow実行のプロセスを分離することで安定性が向上する

「n8n TTL設定」という関連キーワードで検索すると環境変数の紹介記事も見つかりますが、根本解決にはならないケースが多いです。TTL調整に頼るより、本記事で紹介した非同期設計への切り替えを優先することをおすすめします。

よくある質問

Q1. N8N_WEBHOOK_TTLを設定すれば64秒制限は解消しますか?

一時的に効果があるという報告もありますが、公式ドキュメントに記載のない非公式な設定です。65秒を超えると応答が返らなくなる例も報告されているため、恒久的な解決策としては推奨できません。

Q2. Respond to Webhookノードが動かない・応答が返らないのはなぜですか?

Webhookノードの「Respond」設定が「Using 'Respond to Webhook' Node」になっているか、まず確認してください。加えてWaitの待機時間が64秒を超えていないかも確認が必要です。

Q3. Nginxなどのリバースプロキシのタイムアウト設定も影響しますか?

影響します。n8n自体の64秒の制限とは別に、手前のリバースプロキシのproxy_read_timeoutが短い場合も同様のタイムアウトが発生します。両方を確認してください。

Q4. n8n cloudでも同じ64秒の制限はありますか?

はい、n8n cloudでもセルフホストと同様の応答待機の上限が存在します。ただし環境変数によるTTL調整はセルフホスト環境でのみ可能です。

まとめ:非同期設計で64秒の壁を突破する

今回は、「n8n Wait ノード タイムアウト」問題の原因調査と解決策の検証に挑戦してみました。

環境変数によるTTL調整も一部で紹介されていますが、「Waitノード」を長時間使う設計自体を非同期に見直すほうが、はるかに安定した運用ができるため、これを機に設計を切り替えるのはもったいなくありません!

導入も既存ノードの組み合わせだけで完結しますので、みなさんも今回の記事を参考に、ぜひ非同期設計を活用してみてください!

参考リンク