Before getting into this one, an errata against the previous post. I said backup tools “can register as an archive_library and bypass archive_command entirely” on PostgreSQL 15+. That is what the feature was designed to enable. It is not what the ecosystem has actually shipped. More on that in a moment.
archive_library, added in PostgreSQL 15, lets you configure a loadable C module to handle WAL archiving instead of a shell command. The archiver process invokes the module’s callbacks directly, in-process, once per segment. No fork. No shell. No cp. PostgreSQL submits completed WAL files to the module and will not recycle them until the module confirms success, the same contract as archive_command but without the overhead or the failure modes that come with shell scripting.
Set either archive_command or archive_library, not both — PostgreSQL will raise an error if you try to set both. Context is sighup, so you can flip between them without a restart once the module is present. The module itself, being a C shared object, has to be on the server’s library path.
Why this exists: archive_command forks a shell process per 16MB WAL segment. On a busy primary generating hundreds of segments a minute, that is meaningful overhead, and the fork-a-process-to-check-exit-status contract makes certain failure modes (partial writes, lost stderr, hanging commands) awkward to handle correctly. An in-process module gets to use the full C API, handle its own concurrency, return structured errors, and not pay for fork on every segment.
PostgreSQL ships a reference implementation in contrib/basic_archive:
1 archive_library = 'basic_archive'
2 basic_archive.archive_directory = '/mnt/archive'
The docs describe it as “a working example, which demonstrates some useful techniques.” The subtext is: do not run this in production. It is to archive modules what the cp example in the archive_command docs is to backup strategy — a starting point, not a destination.
Which brings me back to the errata. As of PostgreSQL 18 in early 2026, pgBackRest, Barman, and WAL-G all still integrate via archive_command. The documented configuration for every one of them is still archive_command = 'pgbackrest --stanza=foo archive-push %p' or the equivalent. The archive_library infrastructure was introduced in 2022 with the explicit expectation that the backup tool community would adopt it “soonish”; four years on, none of the major tools have. The mechanism is sound. The migration is not happening quickly.
Recommendation: Leave archive_library empty. Use archive_command with your backup tool of choice, per last post. If you are hand-rolling archiving to a local directory and want to learn the module API, basic_archive is a fine place to start — but treat that as a learning exercise, not a production configuration.