All field notes

Field note · found 10 November 2026

n8n Google Sheets append missing rows

Two n8n executions that append to the same Google Sheet within the same second can lose a row, and both Sheets nodes report success when it happens.

Test record: run by Fractional HQ on 10 November 2026 on a test n8n hosted on Railway. n8n version not recorded. One template lost 1 of 6 rows and another lost one row in nine bursts. After the fix, six bursts ran with no loss. Not tested: the n8n source, newer versions, how close together two writes must be.

Symptom

We found this on 10 November 2026 while building a batch of four templates on a test n8n running on Railway. One template lost 1 of 6 answer rows. Another lost one row in nine bursts, a burst being a set of runs fired close together. The "Use Append" option was switched on in the second case, and both nodes reported success.

How to reproduce it

What we ran was bursts of executions of the same workflow, each ending in a Google Sheets node that appends a row to the same tab, and then we counted the rows. We have those two counts and no loss rate, so we cannot tell you how often it happens, only that it did.

The "append or update" operation behaves worse when the key is new, because it reads the last row of the sheet and then writes to the row after it. Our reading is that two executions reading at the same moment then aim at the same row.

Cause, as far as we know

We do not have the cause confirmed. Our working guess is that the node's append uses Google's default insert mode, which writes into the empty rows after the table and does not insert new ones. We did not check that against the n8n source, so please treat it as an inference.

The fix that held

We replaced the Sheets node with an HTTP Request node that calls the Sheets API append endpoint directly:

POST https://sheets.googleapis.com/v4/spreadsheets/{id}/values/{Tab}!A:A:append?valueInputOption=RAW&insertDataOption=INSERT_ROWS

It uses the predefined credential type googleSheetsOAuth2Api. With that in place, the template that had lost a row ran six bursts with no loss. For rows that already exist we kept the Sheets node with the update operation, matched on a key.

Two checks went along with it. First, we treat a 200 response whose updates.updatedRows is 0 or missing as a failed save, because an append sent with no values still returns success and adds an empty row. Second, in any workflow that races to claim a row, a claim that cannot be found afterwards counts as a lost race.

Something that looks like this but is not

When several test runs shared one Google account, a 429 from the Sheets API turned up in runs that were not trying to force one. The quota is per user per minute, so the answer we took from it is to pace each test driver to roughly twenty Sheets calls a minute, or to run the suites one at a time. Such a 429 tells you about the shared quota and nothing about row loss.

What we did not establish

We did not read the n8n source to confirm the insert mode. We did not record the n8n version for these runs, and we did not test whether newer versions behave differently. We also did not measure how close together two writes have to be before a row goes missing: the only figure we have is "the same second", and we did not narrow it further.

Written by Fractional HQ from its own runs. If your n8n behaves differently, email hello@fractionalhq.uk and we will correct the note.