WAL-G: PostgreSQL, MySQL and SQL Server backups to object storage
Archival and Restoration for databases in the Cloud
At a glance
- What is it?
- WAL-G is a Go binary that ships Postgres WAL segments and base backups to S3, GCS, Azure and other cloud storage. It is fast, it is a command line tool, and it assumes you already know how to drive your database's own backup interfaces.
- Who is it for?
- Adopt WAL-G if you run PostgreSQL, MySQL/MariaDB or SQL Server on your own infrastructure and already have object storage you trust, and you are comfortable writing archive_command and restore_command yourself. Do not adopt it if you need a control plane with scheduling, retention policies and a web UI, or if you want the tool to manage your database for you; WAL-G is a binary you call.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap WAL-G fills between pg_dump and a managed backup service
PostgreSQL writes a continuous stream of write-ahead log segments. Those segments are the difference between losing a day of writes and losing a few seconds. Capturing them reliably, and getting them back into a running server during an incident, is the part most teams get wrong.
WAL-G is a single Go binary that does exactly that job. The README describes it as "an archival restoration tool for PostgreSQL, MySQL/MariaDB, and MS SQL Server (beta for MongoDB and Redis)", and it is positioned as the successor to WAL-E. The audience is infrastructure engineers running their own database instances, usually on VMs or Kubernetes, who have object storage available and do not want to pay a managed service per gigabyte.
The important framing: WAL-G is not a scheduler and not a control plane. It is a command line program that your database invokes. Postgres calls it through archive_command to ship each WAL segment, and you call it from cron or systemd for periodic base backups. Everything about retention, alerting and verification is yours to build.
How WAL-G moves data: archive_command, base backups and storage backends
The data flow has two paths and they are worth separating.
The continuous path is WAL shipping. Postgres finishes a 16 MB WAL segment, runs the command in archive_command, and that command is wal-g wal-push with the segment path. WAL-G compresses the segment, optionally encrypts it, and uploads it to the configured storage backend. Nothing about this is Postgres-specific magic; if the command exits non-zero, Postgres keeps the segment and retries.
The discrete path is the base backup. wal-g backup-push takes a full copy of the data directory, splits it into files, and uploads them. The README notes one design difference from WAL-E: WAL-G takes non-exclusive base backups for Postgres, meaning pg_start_backup does not block other concurrent backups the way the older tool's exclusive mode did.
Compression happens on the client, before upload. The README lists lz4, lzma, zstd, brotli and none, with lz4 as the default. The trade-off is stated plainly in the documentation: lz4 is the fastest method but its compression ratio is poor, lzma compresses about six times better than lz4 but is far slower, and brotli and zstd land around three times better than lz4. WALG_ZSTD_LEVEL accepts fastest, default, better or best, with default used when unset.
Encryption is also client-side and optional. The README documents libsodium keys (WALG_LIBSODIUM_KEY, WALG_LIBSODIUM_KEY_PATH, WALG_LIBSODIUM_KEY_TRANSFORM), OpenPGP via WALG_PGP_KEY or WALG_PGP_KEY_PATH, and envelope PGP keys stored in Yandex Cloud KMS through WALG_ENVELOPE_PGP_KEY. The README states that only Yandex Cloud KMS is currently supported for the envelope option. GPG via WALG_GPG_KEY_ID is marked deprecated in the README, so new deployments should not start there.
The storage layer is where the project's breadth shows. The go.mod file pulls in SDKs for AWS S3, Google Cloud Storage, Azure Blob, Alibaba OSS, OpenStack Swift and others. The README defers the full list to a separate STORAGES.md rather than enumerating it inline.
Installing WAL-G and taking a first Postgres backup
The README points to precompiled Linux AMD64 binaries under the Releases tab. Binary names follow the pattern wal-g-DBNAME-OSNAME, where DBNAME is the database (pg, mysql) and OSNAME is the build target. For Postgres on Ubuntu 24.04 the README gives this exact sequence:
tar -zxvf wal-g-pg-24.04-amd64.tar.gz
mv wal-g-pg-24.04-amd64 /usr/local/bin/wal-gAfter that, wal-g should be on your PATH. For systems other than the published Linux AMD64 builds, the README directs you to the Development section of the repository rather than offering a package. There is no apt or yum repository documented here, and no Homebrew formula.
Configuration comes from environment variables or a config file. The --config /path flag sets the file location, or you can set WALG_CONFIG_PATH so you do not pass the flag on every invocation. The README states that any format the viper package supports works, including JSON, YAML and envfile.
A minimal YAML config for an S3 bucket, with zstd compression instead of the lz4 default, looks like this:
WALG_COMPRESSION_METHOD: zstd
WALG_ZSTD_LEVEL: default
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYThe access key and secret in that snippet are the placeholder values that appear in the repository's own docker-compose.yml for its SeaweedFS test service. Replace them. Note that the exact key names for the storage prefix and region are documented in STORAGES.md, which is not reproduced here, so confirm the S3 keys against that file before you commit a config.
The README mentions bash and zsh autocompletion via wal-g help completion, which is worth enabling if you are going to type these subcommands often.
For the first real use, the sequence is: run wal-g backup-push against your data directory to take a base backup, then wire archive_command so Postgres calls wal-g wal-push for each segment. The README does not reproduce a full archive_command example in the text available here, so take the exact form from the Postgres documentation page in the docs directory. Restoring is wal-g backup-fetch followed by a standard Postgres recovery, using wal-g wal-fetch in restore_command to pull segments back.
Where WAL-G stops and your own operational discipline has to start
The honest limitation is that WAL-G is a low-level primitive, and the failure modes are operational rather than technical.
There is no scheduler. The README does not document a built-in cron, a retention policy engine, or a backup catalog. If you want to keep 30 days of base backups and delete the rest, you write that. If you want an alert when the last successful backup is more than 24 hours old, you write that too. Tools that bundle these features exist and are the main reason teams choose them over WAL-G.
Restore is not a single command. backup-fetch brings the files down; Postgres still has to replay WAL, and you have to configure recovery correctly for your server version. The README does not document rollback of a partially applied restore, and it does not document a point-in-time recovery interface beyond what Postgres itself provides. If your team has never done a manual Postgres recovery, this is the wrong first tool.
Key management is the other sharp edge. Losing WALG_LIBSODIUM_KEY or WALG_PGP_KEY_PATH means losing the archive. The README notes that libsodium keys are fixed at 32 bytes and recommends a random key, suggesting openssl rand -hex 32 with WALG_LIBSODIUM_KEY_TRANSFORM set to hex. It also notes that the none transform exists for backwards compatibility and converts user input to 32 bytes by truncation or zero-padding. That is a compatibility path, not something to choose deliberately.
Finally, MongoDB and Redis are labelled beta in the README, while PostgreSQL, MySQL/MariaDB and MS SQL Server are the primary targets. If your estate is mostly MongoDB, the maturity difference matters.
WAL-G compared with pgBackRest: different centres of gravity
The comparison that comes up most is against pgBackRest, and the repository itself acknowledges it. The Makefile builds pgBackRest from source into the Postgres test image, with PGBACKREST_VERSION set to 2.36 for PG 10 and 2.59.0 otherwise, because the project uses it as a comparison point in its own test infrastructure.
The difference in approach is architectural. pgBackRest is a Postgres-specific backup system with its own repository format, its own configuration file, and a long list of built-in features: retention policies, differential and incremental backups, parallel restore, and a verify command. It is a system you configure and it manages the repository for you.
WAL-G is a portable binary that speaks to many databases and many storage backends. Its repository format is simpler, closer to a directory of compressed files, and it does not impose a policy layer. The README's own framing of the WAL-E succession focuses on speed and compression choices rather than on management features.
Practically: if you run PostgreSQL only, want retention and verification handled for you, and value a mature configuration surface, pgBackRest is the safer default. If you run Postgres plus MySQL plus SQL Server, or you want one binary and one mental model across all of them, WAL-G's multi-engine coverage is the reason to pick it. The Makefile's PGBACKREST_VERSION pinning also tells you something about how the project thinks: it treats pgBackRest as a reference implementation worth testing against.
Build requirements, licence and the cost of staying current
The repository's last push was on 2026-09-23, and the most recent release listed is v3.0.9 from 2026-08-20. Before that, v3.0.8 came out on 2026-01-21 and v3.0.7 on 2025-04-13. That cadence is worth reading carefully: patch releases arrive when they arrive, and the gap between v3.0.7 and v3.0.8 was roughly nine months. Plan upgrades as deliberate events, not as a continuous stream.
go.mod declares go 1.27.0, and the Makefile derives GO_VERSION from that file rather than hardcoding it, so building from source requires a Go toolchain at least that new. The build also pulls in C dependencies: the repository contains link_brotli.sh, link_libsodium.sh and CMakeLists-brotli.txt, and the go.mod requires github.com/google/brotli/go/cbrotli and github.com/cyberdelia/lzo. The Makefile's disable_grpc_modules comment explains that gRPC DirectPath is dropped from the Google Cloud Storage dependency because WAL-G uses the HTTP GCS client, which trims the dependency tree but is a build-time decision you inherit.
The LICENSE.md is present at the repository root, but the metadata for this repository reports the licence as NOASSERTION, meaning no standard SPDX identifier was detected. Read LICENSE.md yourself before you redistribute the binary or embed it in a product. Nothing here is legal advice, and the practical consequence is that you cannot assume Apache-2.0 or MIT from the GitHub sidebar.
Upgrade cost is mostly about the storage SDKs. The go.mod pins specific versions of the AWS, Azure, GCS and Alibaba SDKs, so a rebuild picks up whatever the maintainers have bumped. If you vendor the binary, you own that. If you track releases, you inherit their testing, which the Makefile shows is substantial: the docker-compose.yml spins up SeaweedFS as an S3 endpoint, an OpenStack Swift container on port 8010, and a Graphite instance for statsd metrics, and the Makefile defines separate test targets per database.
Deciding whether WAL-G belongs in your stack
WAL-G is the right tool when you want a small, portable binary that speaks to several database engines and several object stores, and when your team is comfortable owning the surrounding automation. The compression and encryption options are documented with their trade-offs stated, the storage backend list is broad, and the project's own test harness exercises multiple real storage services rather than mocking them.
It is the wrong tool when you want backup as a managed feature. No scheduler, no retention engine, no verification command, and no rollback documentation for a failed restore. Those are not oversights to work around; they are the shape of the project.
The thing to verify before you commit is the restore path, not the backup path. Backups that upload successfully tell you almost nothing. Run backup-fetch against a scratch Postgres instance, point restore_command at wal-g wal-fetch, and confirm the server reaches consistency. Do that once with your real encryption keys and your real storage bucket, and you will know more about your setup than any amount of reading.
Editorial conclusion
Adopt WAL-G if you run PostgreSQL, MySQL/MariaDB or SQL Server on your own infrastructure and already have object storage you trust, and you are comfortable writing archive_command and restore_command yourself. Do not adopt it if you need a control plane with scheduling, retention policies and a web UI, or if you want the tool to manage your database for you; WAL-G is a binary you call. Before rolling it out, verify three things: that your chosen storage backend is listed in STORAGES.md, that WALG_COMPRESSION_METHOD and your encryption key settings are recorded somewhere you can reach during a restore, and that a backup-fetch plus recovery actually completes on a scratch instance, because an untested archive is not a backup.
Frequently asked questions
What is WAL-G?
WAL-G is an archival and restoration tool for PostgreSQL, MySQL/MariaDB and MS SQL Server, with beta support for MongoDB and Redis. It is the successor to WAL-E and ships database backups and WAL segments to cloud object storage.
How does WAL-G work with PostgreSQL?
Postgres calls WAL-G through archive_command for each WAL segment, and WAL-G compresses and uploads it to the configured storage backend. Base backups are taken separately with backup-push, and both are pulled back with backup-fetch and wal-fetch during recovery.
How does WAL-G compare with barman?
The README does not compare WAL-G with barman. The project it does position itself against is WAL-E, which it succeeds, and the repository's Makefile builds pgBackRest into its Postgres test image as a comparison point.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wal-g-wal-g)