中級向け

n8n Waitノードの使い方:65秒を境に挙動が変わる

Waitノードは待ち時間が65秒を超えると、実行をいったん終了してあとで再開する作りに切り替わります。境界値を実測し、実装でも確認しました。Webhookで再開する方式で、待機前のデータが消えることも確かめています。

動作確認: — n8n 2.36.8 / Wait ノード v1.1

Wait は、ワークフローの途中で処理を止めるノードです。 APIのレート制限を避けるために数秒空ける、承認が返ってくるまで待つ、 翌朝まで止めておく。そういう使い方をします。

設定項目は少ないのですが、待ち時間の長さによって内部の作りが切り替わります。 その境界を知らないと、実行履歴を見たときに何が起きているのか分かりません。

実際に動かして、境界値まで確かめました。

再開のしかたは4つ

n8nのWaitノード設定画面。Resumeのドロップダウンが開いており、After Time Interval、At Specified Time、On Webhook Call、On Form Submitted の4つが説明文つきで並んでいる
Resume の選択肢。既定は After Time Interval です
表記 何を待つか
After Time Interval(既定) 指定した時間
At Specified Time 指定した日時
On Webhook Call 外部からのリクエスト
On Form Submitted フォームの送信

時間で待つ場合は Wait Amount と Wait Unit を指定します。

Resumeが After Time Interval のときの設定画面。Wait Amount に 5.00、Wait Unit に Seconds が入っている
Wait Amount の表示は 5.00。小数も入れられます

単位は Seconds / Minutes / Hours / Days から選べます。

待ち時間は正確だった

まず基本の確認です。待つ前と後でタイムスタンプを取り、差を測りました。

指定 実測
5秒 5,009ms
70秒 70,025ms

指定どおりに待ちます。 ここは疑う必要がありませんでした。

65秒を境に、内部の作りが変わる

ここが本題です。同じ Wait ノードでも、待ち時間によって実行の扱いがまったく違いました。

指定 実行の status 終了時刻 waitTill
5秒 running → success 5秒後 null
64秒 running 待ち終わるまで null null
70秒 waiting 48ms後に停止 記録される

70秒の方は、48ミリ秒で実行が終わっています。 待っていません。 代わりに waitTill(再開する時刻)が記録され、status が waiting になりました。

境界を n8n の実装で確認したところ、はっきり書かれていました。

const waitValue = Math.max(waitTill.getTime() - new Date().getTime(), 0);
if (waitValue < 65000) {
    // If wait time is shorter than 65 seconds leave execution active because
    // we just check the database every 60 seconds.
    return await new Promise((resolve) => setTimeout(...));
}
// If longer than 65 seconds put execution to wait
return await this.putToWait(context, waitTill);

65秒(65,000ミリ秒)が境目です。理由もコメントに書かれていて、 データベースの確認が60秒間隔だから、それより短い待機はプロセスを起こしたまま setTimeout で待つ、という設計でした。

待機中のデータはどこにあるのか

waiting の状態の実行データを見たところ、待機中のノードと入力データがそのまま 保存されていました。

"nodeExecutionStack": [{
  "node": { "name": "待つ", "type": "n8n-nodes-base.wait", ... },
  "data": { "main": [[ { "json": { "startedAt": "2026-09-25T06:48:55.398Z" } } ]] }
}]

プロセスが終わってもデータは失われません。再開後に確認したところ、 待機前のノードの実行記録もすべて残っていました。

Webhook で再開する

承認フローでよく使う形です。Resume を On Webhook Call にすると、 再開用のURLが実行時に発行されます。

待機前のノードで $execution.resumeUrl を読むと、実際の値が取れました。

http://localhost:5678/webhook-waiting/69?signature=(署名)

実行IDと署名が入ったURLです。このURLを知っている人だけが再開できます。 メールやSlackにこれを載せて「承認はこちら」とするのが基本の形です。

このときの waitTill は、こうなっていました。

"waitTill": "3000-01-01T00:00:00.000Z"

西暦3000年。 期限のない待機は「事実上ずっと待つ」として表現されています。

実際にこのURLへ POST したところ、{"message":"Workflow was started"} が返り、 待機していた実行がそのまま続きました。

待機前のデータが消える

ここが一番はまるところです。

Webhook で再開したとき、Wait ノードの出力が、届いたリクエストの内容に 置き換わっていました。

{
  "headers": { "content-type": "application/json; charset=utf-8", ... },
  "params": {},
  "query": { "signature": "..." },
  "body": { "approved": true, "by": "担当者", "comment": "問題なし" },
  "webhookUrl": "...",
  "executionMode": "test"
}

Webhook ノードの出力とまったく同じ形です。

対処は、待機前のノードを名前で指定して読みにいくことです。

// 直前のアイテムではなく、待機前のノードから直接取る
const startedAt = $('待つ前').first().json.startedAt;

この書き方は今回の検証では試していません。 挙動から考えると通るはずですが、 確認していないことは確認していないと書いておきます。

使うときに気をつけること

  • 65秒未満の待機を大量に並列で動かさない。 プロセスが起きたまま待つので、 数が増えると資源を食います
  • 待機前のデータが必要なら、Webhook再開では前提が崩れる。 ノード名で参照し直すか、 リクエスト側に必要な情報を含めてもらう設計にする
  • On Webhook Call には Limit Wait Time という設定があります。 期限を切らないと、承認が来ないまま実行が残り続けます(未検証)

検証していないこと

  • At Specified Time と On Form Submitted は試していません。 確認したのは After Time Interval と On Webhook Call の2つです
  • Limit Wait Time(待機の上限)は設定していません。 期限切れでどう再開するかは未確認です
  • $('ノード名') で待機前のデータを取り直す方法は、書いただけで試していません
  • 検証はすべて手動実行です。本番実行で waiting がどう扱われるかは見ていません
  • 待機中の実行がどれだけ資源を使うかは測っていません。 「起きたまま待つ」という 実装から述べているだけです
  • 署名(signature)の検証の仕組みは調べていません

まとめると、65秒を境に別物になることと、Webhook再開ではデータが入れ替わることの 2つを知っていれば、Wait でつまずく場面はかなり減ります。

次に読む