{"id":"2NhqmUqW3KruEkaE","meta":{"instanceId":"workflow-b66f9786","versionId":"1.0.0","createdAt":"2025-09-29T07:07:55.424212","updatedAt":"2025-09-29T07:07:55.424224","owner":"n8n-user","license":"MIT","category":"automation","status":"active","priority":"high","environment":"production"},"name":"Exponential Backoff for Google APIs","nodes":[{"id":"5d6b1730-33c5-401c-b73f-2b7ea8eedfe3","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-580,-80],"parameters":{},"typeVersion":1,"notes":"This manualTrigger node performs automated tasks as part of the workflow."},{"id":"6726b630-597c-46cf-8839-75cd80108f2f","name":"Exponential Backoff","type":"n8n-nodes-base.code","position":[160,120],"parameters":{"mode":"runOnceForEachItem","jsCode":"// Define the retry count (coming from a previous node or set manually)\nconst retryCount = $json[\"retryCount\"] || 0;  // If not present, default to 0\nconst maxRetries = 5;  // Define the maximum number of retries\nconst initialDelay = 1;  // Initial delay in seconds (1 second)\n\n// If the retry count is less than the max retries, calculate the delay\nif (retryCount < maxRetries) {\n    const currentDelayInSeconds = initialDelay * Math.pow(2, retryCount);  // Exponential backoff delay in seconds\n    \n    // Log the delay time for debugging\n    console.log(`Waiting for ${currentDelayInSeconds} seconds before retry...`);\n    \n    return {\n        json: {\n            retryCount: retryCount + 1,  // Increment retry count\n            waitTimeInSeconds: currentDelayInSeconds, // Pass the delay time in seconds\n            status: 'retrying',\n        }\n    };\n} else {\n    // If max retries are exceeded, return a failure response\n    return {\n        json: {\n            error: 'Max retries exceeded',\n            retryCount: retryCount,\n            status: 'failed'\n        }\n    };\n}\n"},"typeVersion":2,"notes":"This code node performs automated tasks as part of the workflow."},{"id":"605b8ff0-aa19-42dd-8dbb-aa12380ac4bc","name":"Stop and Error","type":"n8n-nodes-base.stopAndError","position":[760,120],"parameters":{"errorMessage":"Google Sheets API Limit has been triggered and the workflow has stopped"},"typeVersion":1,"notes":"This stopAndError node performs automated tasks as part of the workflow."},{"id":"97818e8b-e0cc-4a49-8797-43e02535740f","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[-360,-80],"parameters":{"options":{}},"typeVersion":3,"notes":"This splitInBatches node performs automated tasks as part of the workflow."},{"id":"0583eabd-bd97-4330-8a38-b2aed3a90c37","name":"Google Sheets","type":"n8n-nodes-base.googleSheets","onError":"continueErrorOutput","position":[-120,20],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"name","value":"Sheet1"},"documentId":{"__rl":true,"mode":"url","value":"{{ $env.WEBHOOK_URL }}"},"authentication":"{{ $credentials.serviceAccount }}"},"credentials":{"googleApi":{"id":"lm7dPHYumCy6sP6k","name":"AlexK1919 Google Service"}},"typeVersion":4.5,"notes":"This googleSheets node performs automated tasks as part of the workflow."},{"id":"0d8023f8-f7ac-4303-b18e-821690cc9f94","name":"Wait","type":"n8n-nodes-base.wait","position":[360,120],"webhookId":"f1651aa1-6497-4496-9e07-240dcf1852f3","parameters":{"amount":"={{ $json[\"waitTime\"] }}"},"typeVersion":1.1,"notes":"This wait node performs automated tasks as part of the workflow."},{"id":"72e0001e-f99b-4d57-9006-4a4dd5d3d8d5","name":"Check Max Retries","type":"n8n-nodes-base.if","position":[560,120],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"51e191cb-af20-423b-9303-8523caa4ae0d","operator":{"type":"number","operation":"gt"},"leftValue":"={{ $('Exponential Backoff').item.json[\"retryCount\"] }}","rightValue":10}]}},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"2ea14bb0-4313-4595-811d-729ca6d37420","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[100,-80],"parameters":{"color":3,"width":820,"height":460,"content":"# Exponential Backoff for Google APIs \n## Connect these nodes to any Google API node such as the Google Sheets node example in this workflow"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"error-31d8d3e1","name":"Error Handler","type":"n8n-nodes-base.stopAndError","typeVersion":1,"position":[1000,400],"parameters":{"message":"Workflow execution error","options":{}}}],"active":false,"settings":{"executionOrder":"v1","saveManualExecutions":true,"callerPolicy":"workflowsFromSameOwner","errorWorkflow":null,"timezone":"UTC","executionTimeout":3600,"maxExecutions":1000,"retryOnFail":true,"retryCount":3,"retryDelay":1000},"versionId":"729e3a54-6238-4e4c-833e-8e37dba16dbb","connections":{"Google Sheets":{"main":[[]]}},"description":"Automated workflow: Exponential Backoff for Google APIs. This workflow integrates 8 different services: stickyNote, wait, code, stopAndError, manualTrigger. It contains 9 nodes and follows best practices for error handling and security.","notes":"Excellent quality workflow: Exponential Backoff for Google APIs. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}