AutomationFlowsWeb Scraping › Back Up Self-hosted Workflows to Google Drive Daily with Change Detection

Back Up Self-hosted Workflows to Google Drive Daily with Change Detection

ByChandan Singh @coolchandan62 on n8n.io

This workflow creates a daily, automated backup of all workflows in a self-hosted n8n instance and stores them in Google Drive. Instead of exporting every workflow on every run, it uses content hashing to detect meaningful changes and only updates backups when a workflow has…

Cron / scheduled trigger★★★★☆ complexity23 nodesHTTP RequestGoogle DriveData TableCrypto
Web Scraping Trigger: Cron / scheduled Nodes: 23 Complexity: ★★★★☆ Added:
Back Up Self-hosted Workflows to Google Drive Daily with Change Detection — n8n workflow card showing HTTP Request, Google Drive, Data Table integration

This workflow corresponds to n8n.io template #12242 — we link there as the canonical source.

This workflow follows the Datatable → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "XnmlJHHJglVn19SO",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Daily n8n workflow backup to Google Drive",
  "tags": [
    {
      "id": "pH0FjEImo9WfHqWC",
      "name": "Template",
      "createdAt": "2025-12-19T17:46:15.670Z",
      "updatedAt": "2025-12-19T17:46:15.670Z"
    }
  ],
  "nodes": [
    {
      "id": "c707b367-f88e-448b-b047-ab17e2b3fadd",
      "name": "Daily Backup Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1120,
        112
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 1
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "86434789-a4cb-491b-902d-482e61e8fa7e",
      "name": "Set Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -944,
        112
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"n8nHost\": \"\",\n  \"apiKey\": \"\",\n  \"backupFolder\": \"//\",\n  \"hashAlgorithm\": \"\",\n  \"dataTableTitle\": \"\",\n  \"backupScope\" : \"\",  \n  \"requiredTag\" : \"\" \n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "427ef1c2-e969-4eda-9e35-329dd6a8ec0f",
      "name": "Get All n8n Workflows",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -576,
        128
      ],
      "parameters": {
        "url": "={{ $node['Set Configuration'].json.n8nHost }}api/v1/workflows",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "X-N8N-API-KEY",
              "value": "={{ $node['Set Configuration'].json.apiKey }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "9dc37605-d398-4e4f-91cd-144c74aa67d0",
      "name": "Prepare Workflow",
      "type": "n8n-nodes-base.code",
      "position": [
        912,
        -48
      ],
      "parameters": {
        "jsCode": "const wf = { ...$input.first().json };\n\n// remove volatile fields\ndelete wf.createdAt;\ndelete wf.updatedAt;\n\n// stable stringify (important for consistent hash)\nconst content = JSON.stringify(wf);\n\nreturn [\n  {\n    json: {\n      workflowId: wf.id,\n      workflowName: wf.name,\n      workflowJson: wf,\n      content\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "52e21e29-bec0-4d0c-bcae-e3afa03f72cd",
      "name": "Workflow Exists?",
      "type": "n8n-nodes-base.if",
      "position": [
        1600,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "af50990b-1784-4e4e-8ead-3b125abbbc17",
              "operator": {
                "type": "object",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $node['Lookup Workflow in Data Table'].json }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b54e1b3d-9483-44ae-8928-1dcaad66bb24",
      "name": "Hash Changed?",
      "type": "n8n-nodes-base.if",
      "position": [
        1808,
        80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d8f5e189-26a9-4cc8-bcd3-544ebf260390",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $node['Lookup Workflow in Data Table'].json.hashCode }}",
              "rightValue": "={{ $node['Generate Workflow Hash'].json.hashCode }}"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3,
      "alwaysOutputData": false
    },
    {
      "id": "e9c2f658-29a1-4f32-85c2-b18b0225039e",
      "name": "Upload New Workflow Backup",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2320,
        112
      ],
      "parameters": {
        "name": "={{ $node['Generate Workflow Hash'].json.workflowId }}_{{ $node['Generate Workflow Hash'].json.workflowName.replaceAll(\" \",\"_\") }}.json",
        "content": "={{ $node['Generate Workflow Hash'].json.workflowJson.toJsonString() }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1CCs1nAzFe5wDDytXJKGNyEEXqmOmb9kZ",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1CCs1nAzFe5wDDytXJKGNyEEXqmOmb9kZ",
          "cachedResultName": "n8n_workflow_backups"
        },
        "operation": "createFromText"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "7865983d-b69a-4a57-98a5-c5d5c81df19a",
      "name": "Upsert Workflow Records",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2544,
        112
      ],
      "parameters": {
        "columns": {
          "value": {
            "hashCode": "={{ $node['Generate Workflow Hash'].json.hashCode }}",
            "workflowId": "={{ $node['Generate Workflow Hash'].json.workflowId }}",
            "DriveFileId": "={{ $node['Upload New Workflow Backup'].json.id }}",
            "workflowName": "={{ $node['Generate Workflow Hash'].json.workflowName }}"
          },
          "schema": [
            {
              "id": "workflowId",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "workflowId",
              "defaultMatch": false
            },
            {
              "id": "workflowName",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "workflowName",
              "defaultMatch": false
            },
            {
              "id": "hashCode",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "hashCode",
              "defaultMatch": false
            },
            {
              "id": "DriveFileId",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "DriveFileId",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "workflowId",
              "keyValue": "={{ $node['Generate Workflow Hash'].json.workflowId }}"
            }
          ]
        },
        "options": {
          "dryRun": false
        },
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "Q8qb9PoqtQOKYgRn",
          "cachedResultUrl": "/projects/Jz2ZhOCR6j1Rldr1/datatables/Q8qb9PoqtQOKYgRn",
          "cachedResultName": "N8N_Workflow_Backup"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ebe9f41d-187d-445f-ac1c-8dcf49404e12",
      "name": "Split Workflows",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -400,
        128
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "a15f6274-1e4b-4924-b6c0-b5437485cfb6",
      "name": "Process Each Workflow",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -240,
        128
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "fc2b2938-9fd3-4f01-a382-422136254539",
      "name": "Generate Workflow Hash",
      "type": "n8n-nodes-base.crypto",
      "position": [
        1200,
        96
      ],
      "parameters": {
        "type": "={{ $node['Set Configuration'].json.hashAlgorithm }}",
        "value": "={{ $node['Prepare Workflow'].json.content }}",
        "dataPropertyName": "hashCode"
      },
      "typeVersion": 1
    },
    {
      "id": "b8d6fee4-7d4a-468f-bff5-145e7bff0a7a",
      "name": "Lookup Workflow in Data Table",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1408,
        96
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "workflowId",
              "keyValue": "={{ $node['Prepare Workflow'].json.workflowId }}"
            }
          ]
        },
        "operation": "get",
        "returnAll": true,
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "Q8qb9PoqtQOKYgRn",
          "cachedResultUrl": "/projects/Jz2ZhOCR6j1Rldr1/datatables/Q8qb9PoqtQOKYgRn",
          "cachedResultName": "N8N_Workflow_Backup"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "120b28b2-84a1-4427-8ce6-66f493f64ccb",
      "name": "Delete Existing Workflow Backup",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2096,
        112
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{$node[\"Lookup Workflow in Data Table\"].json.DriveFileId }}"
        },
        "options": {
          "deletePermanently": false
        },
        "operation": "deleteFile"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "34af4e1f-8346-4ba5-9724-e00362be3eec",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2096,
        -464
      ],
      "parameters": {
        "width": 880,
        "height": 1312,
        "content": "## Workflow Overview - Daily n8n Workflow Backup to Google Drive (with Change Detection)\n\nThis workflow creates a **daily, automated backup** of all workflows in a self-hosted n8n instance and stores them in Google Drive. Instead of exporting every workflow on every run, it uses **content hashing** to detect meaningful changes and only updates backups when a workflow has actually been modified.\n\nTo keep Google Drive clean and predictable, the workflow intentionally **deletes the existing backup file before uploading the updated version**. This avoids duplicate files and ensures there is always *one authoritative backup per workflow*.\n\nA **Data Table** is used as an index to track workflow IDs, hash values, and timestamps. This allows the workflow to quickly determine whether a workflow already exists, whether its content has changed, or whether it should be skipped entirely.\n\n### How it works\n- Runs daily using a Cron Trigger.\n- Fetches all workflows from the n8n API.\n- Processes workflows one-by-one for reliability.\n- Generates a SHA-256 hash for each workflow.\n- Compares hashes against a stored Data Table.\n- Deletes existing Google Drive backups when changes are detected.\n- Uploads updated workflows and skips unchanged ones.\n- Store new or updated workflows details in Data Table.\n- Filters workflows based on the configured backup scope (all | active | tagged ). Backs up all workflows, only active workflows, or only workflows matching a specific tag.\n- Applies the scope filter before hashing and comparison, ensuring only relevant workflows are processed.\n\n### Setup steps\n- **Set the Cron schedule**\nOpen the Cron Trigger node and choose the time you want the backup to run (for example, once daily during off-peak hours).\n\n- **Create a Data Table**\nCreate a new n8n Data Table with the title defined in dataTableTitle. This table stores workflowId, workflowName, hashCode,  and DriveFiveId.\n\n- **Configure the Set node**\nIn the Set Backup Configuration node, provide the following values:\n{\n  \"n8nHost\": \"https://your-n8n-domain\",\n  \"apiKey\": \"your-n8n-api-key\",\n  \"backupFolder\": \"/n8n/workflow-backups\",\n  \"hashAlgorithm\": \"sha256\",\n  \"dataTableTitle\": \"n8n_workflow_backup_index\",\n  \"backupScope\" : \"\",  \n  \"requiredTag\" : \"\"\n}\n\n- In the Set Backup Configuration node, choose how workflows should be selected for backup:\n**all** \u2013 backs up every workflow (default)\n**active** \u2013 backs up only enabled workflows\n**tagged** \u2013 backs up only workflows containing a specific tag\nIf using the tagged option, provide the required tag name to match.\n{\n  \"backupScope\": \"tagged\",\n  \"requiredTag\": \"production\"\n}\n\n\n- **Connect Google Drive credentials**\nAuthorize your Google Drive account and ensure the backup folder exists.\n\n- **Activate the workflow**\nOnce enabled, backups run automatically with no further action required."
      },
      "typeVersion": 1
    },
    {
      "id": "32b72911-65e7-4e1d-b1d3-f8f6b4e08084",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1168,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 464,
        "content": "## Trigger , Configuration & Validation\nThis section defines when the workflow runs and where all configuration lives.\nThe Cron Trigger controls the daily execution time.\nThe Set Backup Configuration node centralizes all reusable values."
      },
      "typeVersion": 1
    },
    {
      "id": "29ccad62-afd8-4446-917c-1d08313a9c11",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -624,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 1696,
        "height": 464,
        "content": "## Workflow Discovery & Looping\nThis section connects to the n8n API and retrieves all existing workflows.\nWorkflows are split into individual items and processed one at a time, ensuring stability even for large or complex n8n instances. \nAt this stage, no backups are created or deleted."
      },
      "typeVersion": 1
    },
    {
      "id": "ec5f92ec-bbdb-4c3b-8587-693a0cfed690",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 464,
        "content": "## Hashing & Change Detection\nEach workflow\u2019s JSON is normalized and converted into a SHA-256 hash.\nThis hash acts as a fingerprint for the workflow.\nIf any node, connection, or parameter changes, the hash changes.\nThe workflow then checks the Data Table to determine whether the workflow already exists and whether its hash has changed."
      },
      "typeVersion": 1
    },
    {
      "id": "640b325c-d669-42c1-9b24-e84c7add800e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2016,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 464,
        "content": "## Google Drive Backup & Data Table Updates\n- **New workflow** \u2192 upload backup and insert Data Table record.\n- **Changed workflow** \u2192 delete existing Google Drive backup, upload the new version, and update the Data Table.\n- **Unchanged workflow** \u2192 skip entirely\nThis ensures a clean Google Drive folder with accurate backups."
      },
      "typeVersion": 1
    },
    {
      "id": "546decbe-3392-4b38-af79-34c30f15bf09",
      "name": "Backup scope all?",
      "type": "n8n-nodes-base.if",
      "position": [
        0,
        144
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "8c439629-ec1e-479a-a592-935c0dbb15ce",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Set Configuration').item.json.backupScope }}",
              "rightValue": "all"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "962efe3c-8dd6-4076-b962-15c23dc9552f",
      "name": "Backup scope active?",
      "type": "n8n-nodes-base.if",
      "position": [
        240,
        176
      ],
      "parameters": {
        "options": {
          "ignoreCase": false
        },
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "60b6a1f4-1e7d-4aee-9a06-f2d42f2d2c57",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $node['Set Configuration'].json.backupScope }}",
              "rightValue": "active"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3,
      "alwaysOutputData": false
    },
    {
      "id": "d188a826-70cf-4488-befd-081d615d3c2c",
      "name": "If workflow active?",
      "type": "n8n-nodes-base.if",
      "position": [
        752,
        48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cecb44e2-ca48-4f02-9be1-4f208f8f3aa9",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.active }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "ff864dfe-6008-4ced-99e2-6197789131e8",
      "name": "Backup scope tagged?",
      "type": "n8n-nodes-base.if",
      "position": [
        576,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "de098349-c7d3-45ae-a6a5-7e5418c74ab4",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $node['Set Configuration'].json.backupScope }}",
              "rightValue": "tagged"
            },
            {
              "id": "5f126eba-c66c-4af3-9dd4-a90bc5539419",
              "operator": {
                "type": "array",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.tags }}",
              "rightValue": ""
            },
            {
              "id": "bdc81217-2e10-4bdb-8f80-27fcecf2ad0f",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $node['Set Configuration'].json.requiredTag }}",
              "rightValue": ""
            },
            {
              "id": "4ac7cd74-4a1e-456b-8a12-b897e773f878",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.tags[0].name }}",
              "rightValue": "={{ $node['Set Configuration'].json.requiredTag }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8361b04b-9e28-4073-9657-a2087a49be38",
      "name": "Config Validation",
      "type": "n8n-nodes-base.code",
      "position": [
        -784,
        112
      ],
      "parameters": {
        "jsCode": "const errors = [];\nconst items = $input.all();\nconst n8nHost = items[0].json.n8nHost;\nconst apiKey = items[0].json.apiKey;\nconst folderPath = items[0].json.backupFolder;\nconst dtName = items[0].json.dataTableTitle;\nconst backupScope = items[0].json.backupScope;\nconst requiredTag = items[0].json.requiredTag;\n\n\nif (n8nHost == '') {\n  errors.push('A valid n8n hostname must be configured.');\n}\nif (apiKey == '') {\n  errors.push('A valid n8n ApiKey must be configured.');\n}\nif (folderPath == '') {\n  errors.push('Google drive directory path must be configured.');\n}\nif (dtName == '') {\n  errors.push('N8n data table name must be configured.');\n}\nif (backupScope == '') {\n  errors.push('The backup scope must be configured.');\n}\nif (backupScope == 'tagged' && requiredTag == '') {\n  errors.push('Please specify the tag name if you have configured the backup scope as \u201ctagged\u201d.');\n}\n\nif (errors.length) {\n  throw new Error(`Validation failed: ${errors.map((e, i) => `${i+1}. ${e}`).join(' | ')}`);\n}\n\nreturn items;"
      },
      "typeVersion": 2
    }
  ],
  "active": true,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "Rj0geDykTdOiLQQL",
    "timeSavedMode": "fixed",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "36e532ba-e890-4d48-bd86-7a7d25c78d64",
  "connections": {
    "Hash Changed?": {
      "main": [
        [
          {
            "node": "Delete Existing Workflow Backup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Process Each Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Workflows": {
      "main": [
        [
          {
            "node": "Process Each Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Workflow": {
      "main": [
        [
          {
            "node": "Generate Workflow Hash",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Exists?": {
      "main": [
        [
          {
            "node": "Hash Changed?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Upload New Workflow Backup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Backup scope all?": {
      "main": [
        [
          {
            "node": "Prepare Workflow",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Backup scope active?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config Validation": {
      "main": [
        [
          {
            "node": "Get All n8n Workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration": {
      "main": [
        [
          {
            "node": "Config Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If workflow active?": {
      "main": [
        [
          {
            "node": "Prepare Workflow",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Process Each Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Backup scope active?": {
      "main": [
        [
          {
            "node": "If workflow active?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Backup scope tagged?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Backup scope tagged?": {
      "main": [
        [
          {
            "node": "Prepare Workflow",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Process Each Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Backup Trigger": {
      "main": [
        [
          {
            "node": "Set Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All n8n Workflows": {
      "main": [
        [
          {
            "node": "Split Workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Each Workflow": {
      "main": [
        [],
        [
          {
            "node": "Backup scope all?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Workflow Hash": {
      "main": [
        [
          {
            "node": "Lookup Workflow in Data Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upsert Workflow Records": {
      "main": [
        [
          {
            "node": "Process Each Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload New Workflow Backup": {
      "main": [
        [
          {
            "node": "Upsert Workflow Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Workflow in Data Table": {
      "main": [
        [
          {
            "node": "Workflow Exists?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Existing Workflow Backup": {
      "main": [
        [
          {
            "node": "Upload New Workflow Backup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow creates a daily, automated backup of all workflows in a self-hosted n8n instance and stores them in Google Drive. Instead of exporting every workflow on every run, it uses content hashing to detect meaningful changes and only updates backups when a workflow has…

Source: https://n8n.io/workflows/12242/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

This workflow snoozes any Todoist tasks, by moving them into a Snoozed todoist list and unsnoozes them 3 days before due date. Helps keep inbox clear only of tasks you need to worry about soon. Add yo

Todoist, Crypto, Item Lists +1
Web Scraping

This workflow automatically creates daily backups of all n8n workflows and stores them in Google Drive, using the n8n API to export workflows and a scheduled retention policy to keep storage organized

Google Drive, HTTP Request
Web Scraping

Tags: Marketing, Image Processing, Automation

Google Drive, HTTP Request
Web Scraping

Title: ⚙️ Deep Dive: Automating Weekly US Trademark Reports with n8n, RapidAPI & Google Drive (No-Code Workflow)

HTTP Request, Google Drive
Web Scraping

This automation organizes your n8n workflows files into categorizes (Active, Template, Done, Archived) and uploads them directly to a categorized Google Drive folders. It is designed to help users man

Google Drive, HTTP Request, Time Saved