Hi everyone,
I made a critical mistake and accidentally exhausted my entire monthly execution limit.
5 days ago I built my first Schedule Trigger workflow with a 1-minute interval. I didn’t realize that a failing downstream node creates a silent crash loop — the workflow kept crashing and restarting every minute without me noticing. I couldn’t stop it in time. I got the 80% alert Friday morning and hit 100% by Friday afternoon — the entire 2,500-execution quota consumed in roughly 24 hours.
My workspace is now paused until May 1st, and n8n runs my entire sales lead pipeline. I’m completely blocked.
I have already identified the logic error, disabled the workflow, and the fix is ready to deploy (add IF-guard + reduce trigger to 5 min).
I would greatly appreciate a one-time courtesy reset. I’ve also opened a support ticket but saw this community has helped others in similar situations. Happy to DM my cloud username and any account details needed.
Thanks,
Linus
Hi @libstrom Welcome! kjooleng is right on the reset, but here’s your IF-guard + 5-min trigger ready to import so you can deploy the fix the moment your workspace unpauses — the silent crash loop happened because a failing node still counts as an execution, so the guard needs to catch errors before they bubble up.
Swap $json.ready for whatever field confirms your upstream data is valid, point the HTTP Request at your actual leads endpoint, done.
Thanks @achamm – really appreciate the template and the explanation on why failing nodes still burn executions.
I have already reworked the pipeline to be fully event-driven. Here is what I landed on:
Primary flow (webhook, no cron):
FB Webhook (POST from Meta Lead Ads)
→ Split leads
→ Fetch lead fields (Graph API)
→ Parse + route (postnummer decides Skane pool vs Online pool)
→ Insert to Supabase (fb_leads table)
→ Build Adaptive Card
→ Post to Teams (claim buttons per pool member)
→ Wait 3 min
→ Check if claimed (Supabase lookup)
→ IF unclaimed: auto-assign to pool member with fewest open tasks
→ Post Teams update
All HTTP nodes have neverError: true so nothing crashes the chain. The Wait node replaces the old 1-min cron entirely – fallback lives inside the same execution.
Execution cost: 1 execution per actual lead. 0 when nothing happens.
My concern: If the webhook itself fails (n8n down, Meta timeout, network blip), there is no safety net. The lead is silently lost.
I am thinking about adding your cron pattern as a low-frequency sweep – something like every 30 min, check Supabase for fb_leads older than 5 min with no matching claim, and process any orphans. With an IF-guard so it exits immediately when there is nothing to sweep.
Question for you: On the Starter plan (2,500 exec/month), would you run the sweep cron at all, or trust the webhook and save the budget? A 30-min sweep would cost roughly 1,440 exec/month just on the guard checks alone. Is there a smarter pattern for a safety net that does not eat half the quota?
Update — landed on a different pattern after thinking about this more, sharing in case it helps others on Starter:
I’m putting the sweep in Supabase pg_cron instead of n8n. pg_cron is included on all Supabase plans (including free), runs inside Postgres, and doesn’t count toward n8n executions at all. The pg_cron job has an EXISTS guard so it only calls the n8n webhook when there’s actual work — meaning n8n executions stay at 0 unless something has genuinely gone wrong downstream.
Frequency math for Starter (2,500 exec/month): | Pattern | n8n exec / month | | --------------------------------- | ---------------- | | 30-min sweep in n8n (your idea) | ~1,440 | | 5-min sweep in n8n | ~8,640 (over!) | | 5-min sweep in pg_cron + EXISTS | ~0–50 |
The pg_cron version runs every 5 minutes (matching my speed-to-lead goal) but only invokes n8n when there’s an orphan to process. If the system is healthy, it’s free.
One more thing worth flagging for anyone building this kind of pipeline: Meta itself retries failed Lead Ads webhooks for up to 36 hours with exponential backoff. So the sweep isn’t really protection against “n8n was down” — Meta handles that. The real risk is “n8n returned 200 but a downstream HTTP call (CRM, Teams, etc.) silently failed because neverError: true was set.” That’s what the sweep should catch — rows in the leads table that never got their downstream side-effect.
So the sweep query checks for “lead exists in Supabase but no matching CRM task ID” rather than “lead exists but no claim” — different failure mode.
Hope this helps someone else avoid the same trap. Thanks again @achamm for the IF-guard template — same idea applied at the database layer.