AutomationFlowsData & Sheets › Daily Postgres Table Backup to Github in CSV Format

Daily Postgres Table Backup to Github in CSV Format

ByJay Emp0 @jay-emp0 on n8n.io

This workflow automatically backs up all public Postgres tables into a GitHub repository as CSV files every 24 hours. It ensures your database snapshots are always up to date updating existing files if data changes, or creating new backups for new tables.

Cron / scheduled trigger★★★★☆ complexity17 nodesPostgresGitHubItem Lists
Data & Sheets Trigger: Cron / scheduled Nodes: 17 Complexity: ★★★★☆ Added:

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

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": "oBJaQvcNxODDoAl1",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "backup postgres as csv to github",
  "tags": [],
  "nodes": [
    {
      "id": "20477146-5542-4701-a92f-4300c95a0c5d",
      "name": "Daily Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1712,
        -96
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 24
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3f5ec59d-374f-421c-a333-155c06443e5d",
      "name": "List tables",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -544,
        64
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.table_name }}"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "options": {},
        "operation": "select",
        "returnAll": true
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "8d8af1f2-5b28-449d-a354-a624f9e2a53c",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -912,
        -96
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "680847b4-e704-4728-8ee2-44642d931d58",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        -752,
        64
      ],
      "parameters": {
        "jsCode": "return $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "0ec30d45-c281-4d65-a966-29f615eade3a",
      "name": "Convert to File1",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        -336,
        64
      ],
      "parameters": {
        "options": {
          "fileName": "={{ $('List tables1').item.json.table_name }}"
        },
        "binaryPropertyName": "=data"
      },
      "typeVersion": 1.1
    },
    {
      "id": "09466877-0cdb-4011-809f-87c696ab3717",
      "name": "List tables1",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -1104,
        -96
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tables",
          "cachedResultName": "tables"
        },
        "where": {
          "values": [
            {
              "value": "public",
              "column": "table_schema"
            }
          ]
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "information_schema",
          "cachedResultName": "information_schema"
        },
        "options": {},
        "operation": "select"
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "014fa66c-4acc-4698-97cc-142efaae9376",
      "name": "List files from repository [GITHUB]",
      "type": "n8n-nodes-base.github",
      "position": [
        -1536,
        -96
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "user"
        },
        "filePath": "=",
        "resource": "file",
        "operation": "list",
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-repo",
          "cachedResultUrl": "https://github.com/user/github-repo",
          "cachedResultName": "github-repo"
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "5942926d-b940-4ba4-a0c1-7209c04c0a3c",
      "name": "Combine file names [GITHUB]",
      "type": "n8n-nodes-base.itemLists",
      "position": [
        -1344,
        -96
      ],
      "parameters": {
        "options": {},
        "operation": "aggregateItems",
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "name"
            }
          ]
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "00aa6a0e-b5c1-4093-8ee0-94b35bcdd934",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1584,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 390,
        "height": 547,
        "content": "## Get list of current tables\nReturn a list of existing files in GitHub repository. \nSome of them are tables, \nSome are readme files"
      },
      "typeVersion": 1
    },
    {
      "id": "863c59ef-6ce2-4c22-8c0e-00b9abcfdbd9",
      "name": "Split to single items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -80,
        -112
      ],
      "parameters": {
        "options": {},
        "batchSize": 1
      },
      "typeVersion": 2
    },
    {
      "id": "ccee7881-77c8-419e-ad99-ac3bb113ae6b",
      "name": "Check if file exists in repository",
      "type": "n8n-nodes-base.if",
      "position": [
        160,
        -128
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $node['Combine file names [GITHUB]'].json.name }}",
              "value2": "={{ $binary.data.fileName }}",
              "operation": "contains"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f6d53dcc-1e40-43f5-b793-4d06a55ccbed",
      "name": "Update file [GITHUB]",
      "type": "n8n-nodes-base.github",
      "position": [
        384,
        -128
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "user"
        },
        "filePath": "={{ $binary.data.fileName }}",
        "resource": "file",
        "operation": "edit",
        "binaryData": true,
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-repo",
          "cachedResultUrl": "https://github.com/user/github-repo",
          "cachedResultName": "github-repo"
        },
        "commitMessage": "=backup-{{ $now.toMillis() }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ebcd65d3-37ac-4d47-90dc-fede45adb9c0",
      "name": "Upload file [GITHUB]",
      "type": "n8n-nodes-base.github",
      "position": [
        384,
        80
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "user"
        },
        "filePath": "={{ $binary.data.fileName }}",
        "resource": "file",
        "binaryData": true,
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-repo",
          "cachedResultUrl": "https://github.com/user/github-repo",
          "cachedResultName": "github-repo"
        },
        "commitMessage": "=backup-{{ $node['Set commit date'].json.commitDate }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6bcbeffb-b036-45f3-88a8-dd5f1ac0fa39",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1168,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 998,
        "height": 547,
        "content": "## Get postgres table data\nReturn a list of existing tables and data in the postgres.  \nConvert them to csv"
      },
      "typeVersion": 1
    },
    {
      "id": "88cc96e5-fc5b-4d28-8e57-82c193efb19d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 694,
        "height": 547,
        "content": "## Make a list of existing files\nCreate backup if its a new table. \nUpdate backup if there is new data in the table"
      },
      "typeVersion": 1
    },
    {
      "id": "4b4f32d2-2138-4d9a-8d48-6b35b387270a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 374,
        "height": 195,
        "content": "![postgres table](https://articles.emp0.com/wp-content/uploads/2025/08/backup-postgres-to-github-tables.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "02ddc44f-7c23-4022-9978-c43876593274",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 694,
        "height": 259,
        "content": "![github backup](https://articles.emp0.com/wp-content/uploads/2025/08/backup-postgres-to-github-repo.png)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "747a3b1e-5b2a-4f61-875c-250bd44fbf01",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "List tables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List tables": {
      "main": [
        [
          {
            "node": "Convert to File1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List tables1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Schedule": {
      "main": [
        [
          {
            "node": "List files from repository [GITHUB]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Split to single items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update file [GITHUB]": {
      "main": [
        [
          {
            "node": "Split to single items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file [GITHUB]": {
      "main": [
        [
          {
            "node": "Split to single items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split to single items": {
      "main": [
        [
          {
            "node": "Check if file exists in repository",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine file names [GITHUB]": {
      "main": [
        [
          {
            "node": "List tables1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if file exists in repository": {
      "main": [
        [
          {
            "node": "Update file [GITHUB]",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Upload file [GITHUB]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List files from repository [GITHUB]": {
      "main": [
        [
          {
            "node": "Combine file names [GITHUB]",
            "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 automatically backs up all public Postgres tables into a GitHub repository as CSV files every 24 hours. It ensures your database snapshots are always up to date updating existing files if data changes, or creating new backups for new tables.

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

Disparador 1.8. Uses itemLists, postgres, emailSend, httpRequest. Scheduled trigger; 85 nodes.

Item Lists, Postgres, Email Send +1
Data & Sheets

GitHub Analytics Pull (github-pull). Uses github, httpRequest, postgres. Scheduled trigger; 5 nodes.

GitHub, HTTP Request, Postgres
Data & Sheets

공유회_알림톡_크론. Uses postgres, httpRequest, n8n-nodes-solapi. Scheduled trigger; 39 nodes.

Postgres, HTTP Request, N8N Nodes Solapi
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request
Data & Sheets

QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.

Postgres, Postgres Trigger, HTTP Request