n8n guide

Stop n8n from emailing the same Google Sheets row twice

If a workflow reads rows from a Google Sheet on a schedule and emails each one, two runs that overlap can both pick up the same row. Here is how that happens and the pattern we now use to stop it.

How the double send happens

We found this in our own review-request template. An audit on a real n8n 2.43.7 instance showed that if two runs overlapped, the same client could get the email twice.

The cause was simple. The workflow only marked a row as done after the email went out. A second run that read the sheet at the same moment still saw the row as unsent, so it sent it again. A manual test run fired while the hourly schedule is active, or one slow run that is still going when the next one starts, is enough.

The Google Sheets node in n8n can read, append, update and delete rows, but none of those operations lets a run lock a row while it works on it. So the workflow has to do that job itself.

The fix: claim the row, wait, read it again

Keep a status column in the sheet (ours is called review_status). Then build the send step like this:

  1. Pick the rows. Read the sheet and keep only rows that are due and have an empty status.
  2. Claim them. Before sending anything, use Update Row to write sending {{ $execution.id }} into the status column. $execution.id is the ID of the current run, so every run writes a different value.
  3. Wait. Add a Wait node set to a short time interval. We use 15 seconds.
  4. Read the sheet again. Only send a row if it still has the same email and key, is still due, and still carries your own run's ID. If another run overwrote the claim, that row isn't yours.
  5. Stop on any doubt. If a check fails, stop the whole batch before anything is sent and email yourself an alert. A run that is too slow to confirm its claim shouldn't send either.
  6. Send, then mark it. After the email goes out, set the status to sent and read the row back to make sure the write saved.
  7. Cap the retries. Turn on Retry On Fail for the sheet writes and limit it to 3 tries. If a write still fails, stop and alert instead of carrying on. Do the same for failed sends: record each attempt and mark the row as given up after 3, so it doesn't retry forever.

What this doesn't fix

A Google Sheet isn't a database, and this pattern is best effort. It makes the gap between two runs much smaller, but it can't close it completely. The simplest habit that helps: don't start a manual run of a workflow while its schedule is active.

How to test it

Point the workflow at test data and start three runs at the same time. You want exactly one email per row, and the two runs that lose the claim should stop and send you an alert.

That is the test our templates have to pass. Our free review-request template passed all 29 of its automated tests on n8n 2.43.7 on Oct 22, 2026, and again on n8n 2.44.6 on Oct 26, 2026, including the three-runs-at-once case. Those tests use a mock in place of Google Sheets and email; a live Google Sheets test is still pending.

Templates

Templates that already do this

If you'd rather not build it yourself, these use the same claim step.

Free: post-visit review requests

When a visit in your sheet is marked completed and a set delay has passed, it emails the client a link to your Google review page, once per client.

See the free template on n8n.io

Service-Business Ops Pack for n8n

Five workflows: appointment reminders, a form-to-Sheets mini-CRM, review requests, overdue invoice follow-ups and a weekly numbers email. The reminder, review and invoice workflows each passed the three-runs-at-once test. The pack passed all 102 of its automated tests on n8n 2.43.7 on Oct 22, 2026 (mock Sheets and email).

Price
US$39, one-time
License
One per business

Get the Ops Pack on Gumroad

Invoice & Payment Chaser for n8n

Checks your invoices in Google Sheets once a day and sends up to three reminders (by default at 3, 7 and 14 days overdue). It stops once an invoice is marked paid, and it passed the same three-runs-at-once test. All 31 of its automated tests passed on n8n 2.43.7 on Oct 22, 2026 (mock Sheets and email).

Price
US$29, one-time
License
One per business

Get the Invoice Chaser on Gumroad

Questions?

Both paid templates need self-hosted n8n, a Google Sheet and an SMTP mailbox. More on each one is on our products page.

n8n and Google are trademarks of their respective owners. Agentica is not affiliated with or endorsed by them.