The usual rule for backups is 3-2-1: three copies of your data, on two kinds of storage, with one copy off-site. If your backups sit on the same PC (or the same disk) as the database, a dead disk, a stolen laptop, ransomware or a fire takes both. On Windows, the cheapest off-site copy is a folder that a sync client you already use uploads for you.
The simple setup
Point your backup folder at a synced location:
- OneDrive:
C:\Users\<you>\OneDrive\PostgresBackups - Dropbox:
C:\Users\<you>\Dropbox\PostgresBackups - Google Drive for desktop: a folder inside your Google Drive drive letter (often
G:\My Drive\PostgresBackups)
Each new backup is uploaded shortly after it's written, and deletions by your retention rules sync too.
Pitfalls, and how to avoid them
Half-written files get uploaded
Sync clients start uploading as soon as a file appears. A 2 GB dump being written for five minutes may be uploaded several times, or uploaded mid-write. Two fixes:
- Write locally, then move. Dump into a local folder and
Move-Itemthe finished file into the synced folder. A move within the same drive is instant and atomic, so the sync client only sees complete files. - Or rely on the client noticing changes and re-uploading. It works, but wastes bandwidth.
In the script from the main guide, that's two extra lines after a successful dump:
$synced = 'C:\Users\me\OneDrive\PostgresBackups'
Move-Item $File (Join-Path $synced (Split-Path $File -Leaf))Files On-Demand
OneDrive's Files On-Demand can free up local space by keeping only an online placeholder. That's fine for old backups, but your cleanup script must not fail on placeholder files. Remove-Item works on them; reading them triggers a download.
The SYSTEM account and your OneDrive
A scheduled task running as SYSTEM can write into your OneDrive folder (it's just a folder on disk), but the OneDrive client only syncs while you're signed in. Files written overnight are uploaded the next time you sign in. If that's too late, run the task as your own user, or copy to a network share or object storage instead.
Deleting syncs too
If ransomware encrypts your local backups, the sync client happily uploads the encrypted versions. OneDrive, Dropbox and Google Drive keep version history and a recycle bin for a while, so learn where those live. For important data, also keep an occasional copy somewhere sync can't touch (an external drive you unplug, or a bucket with object lock).
Your backups contain your data
A pg_dump file holds the database contents in a readable format, including any personal data, password hashes and API keys stored in tables. Uploading it to a personal cloud account may be against your company's or your client's policy. If in doubt, encrypt before syncing. With 7-Zip:
& 'C:\Program Files\7-Zip\7z.exe' a -t7z -mhe=on -p"$env:BACKUP_ZIP_PASSWORD" "$synced\shop-20261014.7z" $File-mhe=on also hides the file names inside the archive. Keep the password somewhere other than next to the backups, and test that you can open an archive.
Other off-site options
- A network share or NAS:
Copy-Item $File '\\nas\backups\postgres\'after each run. - Object storage (S3, Azure Blob, Backblaze B2): their CLIs (
aws s3 cp,az storage blob upload,b2 file upload) work in the script. Turn on versioning or object lock to protect against deletion. - A second PC: a sync tool like Syncthing between two machines you control.
How PostgresBackup fits
PostgresBackup writes each backup to the folder you choose for the job, so pointing a job at a OneDrive or Dropbox folder works. It writes each backup completely before recording it, and removes half-written files when a backup fails or is canceled. Retention deletes old files after each successful backup, and the sync client mirrors that. The background service runs whether or not you're signed in, so with OneDrive the upload follows when you next sign in. If you already moved older backups somewhere else by hand, Change backup location in Backup History keeps them restorable.