
WAL-G
A single Go binary that streams compressed, encrypted Postgres backups and WAL to object storage, and restores them in parallel.
- What it is
- Backup & restore,Relational databases
- Type
- Open source
- Made by
- WAL-G contributors (started at Citus Data; supported by Yandex Cloud)
- License
- Apache 2.0 (the optional LZO support is GPL 3.0 or later)
- Facts checked
- 6 October 2026
What it is
WAL-G has no server of its own. Postgres calls it: archive_command runs wal-g wal-push for each finished WAL segment, and on restore restore_command runs wal-g wal-fetch, which also prefetches the next segments. A base backup is wal-g backup-push $PGDATA: it reads the data directory, packs it into tar bundles (1 GB each by default), compresses them (LZ4 by default, or zstd, Brotli or LZMA), optionally encrypts them with libsodium, OpenPGP or Yandex Cloud KMS, and uploads them over 16 parallel streams. A JSON sentinel file marks a finished backup. With WALG_DELTA_MAX_STEPS set, later backups copy only pages whose LSN changed since the previous one. Restoring is wal-g backup-fetch <dir> LATEST, then Postgres replays WAL from the bucket up to the moment you choose.
Backups can go to Amazon S3 and S3-compatible stores such as MinIO, Google Cloud Storage, Azure Blob Storage, Alibaba Cloud OSS, OpenStack Swift, a host over SSH, or a local disk, with optional failover storages if the main one is down. The same binary also backs up MySQL and MariaDB (with xtrabackup and binlogs), SQL Server, Greenplum and Cloudberry, and, in beta, MongoDB and Redis or Valkey. It is free under Apache 2.0; the cost is object storage and requests, and smaller tar bundles mean more requests.
Why teams pick it
- Fast: written in Go with compression, tar and uploads in-process and in parallel; Citus measured restores about 4 times faster than WAL-E
- Delta backups and WAL prefetch keep backup volume and restore time down on large databases
- Speaks to every major object store, plus S3-compatible ones, SSH and local disk, with failover storages
- Reads WAL-E archives, so it replaced WAL-E in place; Patroni-based stacks such as Zalando’s Spilo and Datadog’s Postgres platform use it
- One tool and one bucket layout across Postgres, MySQL, SQL Server, Greenplum and more
Watch out for
- No scheduler, catalogue server or UI: cron, systemd or an orchestrator must run
backup-pushanddelete, and you watch for failures yourself delete retainorders Postgres backups by timeline by default; afterpg_upgraderesets the timeline it can delete new backups unless you pass--use-sentinel-time- Outside Postgres, interfaces are marked unstable: MySQL/MariaDB, MongoDB and Redis docs say so, and etcd and FoundationDB support is work in progress
- Configuration is a long list of environment variables with few safety checks; GPG key encryption is deprecated in favour of libsodium or OpenPGP keys
- LZO support is licensed under GPL 3.0 or later, unlike the rest of the code
Alternatives
What all backup & restore have in common →
pgBackRestOpen sourceA PostgreSQL-only backup tool in C: parallel full, differential and incremental backups, WAL archiving and point-in-time restores, to disk, S3, Azure, GCS or SFTP.
VeleroOpen sourceBacks up a Kubernetes cluster’s objects and persistent volumes to object storage, and restores them into the same cluster or a new one.How it fits with other technologies
What WAL-G uses
What uses WAL-G
Continuous archiving to S3, nightly backups and a restore · bash
# /etc/wal-g.env, sourced by Postgres and by cron
export WALG_S3_PREFIX=s3://acme-pg-backups/orders
export AWS_REGION=eu-central-1
export WALG_COMPRESSION_METHOD=zstd
export WALG_DELTA_MAX_STEPS=6 # up to 6 delta backups between full ones
export WALG_LIBSODIUM_KEY_PATH=/etc/wal-g/backup.key
export WALG_LIBSODIUM_KEY_TRANSFORM=hex # key made with: openssl rand -hex 32
export PGHOST=/var/run/postgresql
# postgresql.conf: ship every finished WAL segment
# archive_mode = on
# archive_command = '. /etc/wal-g.env && wal-g wal-push %p'
# nightly: base backup, then keep 7 full backups, their deltas and WAL
wal-g backup-push "$PGDATA"
wal-g backup-list --pretty
wal-g delete retain FULL 7 --use-sentinel-time --confirm
# restore on a fresh server, then let Postgres replay WAL from S3
wal-g backup-fetch /var/lib/postgresql/18/main LATEST
touch /var/lib/postgresql/18/main/recovery.signal
# restore_command = '. /etc/wal-g.env && wal-g wal-fetch %f %p'
# recovery_target_time = '2026-10-06 09:41:00+00'What it backs up, and how ready each one is#
Status as the WAL-G README and each database’s page describe it.
PostgreSQL
matureFull and delta backups, WAL archiving through archive_command or wal-receive over streaming replication, catch-up backups for lagging replicas, partial restores (experimental) and WAL integrity checks.
MySQL and MariaDB
unstable interfaceWraps a backup command such as xtrabackup that writes one stream, and archives binlogs for point-in-time recovery. Delta backups only with xtrabackup-push.
SQL Server
production-ready since 1.0Emulates Azure Blob storage locally so the standard BACKUP ... TO URL and RESTORE commands write through WAL-G.
Greenplum and Cloudberry
production-readyEncrypted, compressed physical backups of Greenplum 6.19+ and Cloudberry 2.0+.
MongoDB, Redis and Valkey
betaBackups and restores, with interfaces the docs call unstable.
etcd and FoundationDB
work in progressEarly support for encrypted, compressed backups of these key-value stores.
WAL-G or pgBackRest?#
Both are open-source Postgres backup tools that write to object storage. The WAL-E maintainers point to these two as its successors.
| WAL-G | pgBackRest | |
|---|---|---|
| Model | A binary called from archive_command and cron; state lives in the bucket | Its own repository format, run locally or from a separate repository host over TLS or SSH |
| Databases | Postgres plus MySQL, SQL Server, Greenplum and others | Postgres only |
| Incremental backups | Delta backups from page LSNs | Full, differential and incremental, at file or block level |
| Where backups go | S3 and compatible, GCS, Azure, Alibaba OSS, Swift, SSH, local; failover storages | S3, Azure and GCS compatible stores, local or remote hosts; several repositories at once |
| Integrity | wal-verify checks WAL continuity; optional page checksum checks | Checksums every file, rechecked on restore; validates page checksums; resumes interrupted backups |
| Licence | Apache 2.0 (LZO part GPL 3.0+) | MIT |
- The WAL-E README says WAL-G tends to follow a cloud service provider’s priorities, while pgBackRest has more polished features for independent system operators.
See it in a real stack
No architecture uses WAL-G yet. Drop it into the playground and wire it up yourself.Open playground →Worth exploring
Where it came from2017–2026
Continuous archiving is how Postgres gets point-in-time recovery: a base copy of the data directory plus every WAL segment written since. WAL-E, written in Python by Daniel Farina, made object storage the place to keep both, and was used to protect millions of databases. It shelled out to lzop, cat and pipes, though, and memory copies between them became its bottleneck.
At Citus Data, a summer engineering intern, Katie Li, a UC Berkeley undergraduate, rewrote it in Go with Farina, linking tar, LZ4 and the AWS SDK’s multipart uploads directly instead of running external processes. Citus announced WAL-G on 18 August 2017, measuring restores about 4 times faster than WAL-E, and as much as 7 times on some instances, with 1,500 lines of code instead of 6,500.
Development continued in the wal-g organisation on GitHub, with Yandex Cloud supporting the work. Version 1.0 in 2021 could restore WAL-E backups and declared MySQL and SQL Server support production-ready. WAL-E’s README now calls it obsolete and suggests WAL-G or pgBackRest.
Why it’s built this way
- Go instead of Python
- A compiled language with cheap concurrency, and libraries linked in-process instead of external
lzopandcatprocesses joined by pipes, which had been WAL-E’s main bottleneck. - Parallel restore as the main goal
- Disaster recovery time is what users feel. Downloading and unpacking many bundles at once let WAL-G hold close to an instance’s advertised disk throughput during a restore.
- Keep WAL-E’s model and read its archives
- Hooking into
archive_commandandrestore_commandwith object storage underneath meant existing WAL-E users could switch without re-architecting, and keep their old backups.
Timeline
- 2017
Citus Data releases WAL-G 0.1 on 18 August
- 2021
1.0: restores WAL-E backups; MySQL and SQL Server production-ready
- 2022
2.0 released in May
- 2024
3.0 adds failover storages, a WAL archiving daemon and partial restore
- 2026
3.0.9 released in August
- Citus Data blog: Introducing WAL-G by Citus, faster disaster recovery for Postgres (Aug 2017)
- wal-g/wal-g on GitHub: tag v0.1.0 (Aug 2017)
- wal-g/wal-g on GitHub: release v1.0 (May 2021)
- wal-g/wal-g on GitHub: release v2.0.0 (May 2022)
- wal-g/wal-g on GitHub: release v3.0.0 (Mar 2024)
- WAL-E README: obsolescence notice
Sources18 · facts checked 6 October 2026
- WAL-G documentation (configuration, compression, encryption, delete, authors, licence)
- WAL-G docs: PostgreSQL (backup-push, wal-push, delta backups, concurrency)
- WAL-G docs: Storages
- WAL-G docs: MySQL
- WAL-G docs: Failover storages
- WAL-G docs: SQL Server
- WAL-G docs: Greenplum and Cloudberry
- WAL-G docs: MongoDB
- WAL-G docs: Redis and Valkey
- WAL-G LICENSE.md (Apache 2.0 notice, Citus Data 2017)
- WAL-G README on GitHub (supported databases, Yandex Cloud support)
- wal-g/wal-g on GitHub: release v3.0.9 (Aug 2026)
- Citus Data blog: Introducing WAL-G (4x faster restores)
- WAL-E README: obsolescence notice (WAL-G and pgBackRest as alternatives)
- pgBackRest: features
- pgBackRest LICENSE (MIT)
- Zalando Spilo: environment (WAL-G backups with Patroni)
- PGConf NYC 2025: How (and why) Datadog is moving from cloud-managed to self-managed Postgres (slides, PDF)