<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=2826169&amp;fmt=gif">
Start  trial

    Start trial

      img-anim-badge-person-using-computer-as-hacker-with-0s-and-1s-01PostgreSQL 19 introduces a long-awaited improvement to logical replication by enabling online WAL level changes without requiring a system restart. Previously, switching to logical decoding meant planned downtime and careful coordination, leading many teams to permanently run with higher WAL overhead than necessary.

      With this new capability, PostgreSQL can dynamically adjust the effective WAL level based on demand, allowing logical replication to be enabled and disabled seamlessly—delivering greater flexibility while optimising performance in production environments.

      PostgreSQL 19 introduces online WAL level changes for logical decoding, eliminating the need for server restarts and improving replication efficiency

      Background

      Previously, enabling logical decoding by changing wal_level required a system restart, which was often operationally expensive. If a server was running with wal_level = minimal or replica and logical replication needed to be enabled later, administrators had to schedule downtime just to change the parameter.

      The workflow typically involved editing postgresql.conf, setting wal_level = logical, restarting the server, waiting for recovery to complete, and only then creating logical replication slots and proceeding with setup. On high-traffic production systems, even this small restart window could require careful planning and coordination.

      To avoid such disruptions, many users proactively configured wal_level = logical even when logical replication was not actively in use. However, this meant continuously incurring the overhead of logical-level WAL logging, even in environments without logical replication slots or after all slots had been dropped or invalidated. This overhead can be significant because the logical WAL level records substantially more information in WAL, particularly for tables using REPLICA IDENTITY FULL or workloads with heavy UPDATE and DELETE activity.

      Upcoming PostgreSQL 19 removes this system restart requirement by dynamically adjusting the effective WAL level based on the presence of logical replication slots.

      How it works

      ill-office-worker-132-variation-02The adjustment works with wal_level = replica. With this configuration, the system automatically elevates the effective WAL level to logical when a logical replication slot is created. And it is demoted back to replica when the last logical replication slot is either invalidated or dropped. Note that this demotion may not be immediate, as deactivation of logical decoding is performed asynchronously by the checkpointer process.

      To indicate the actual WAL level of the system, PostgreSQL introduces a new read-only GUC parameter: effective_wal_level. Unlike wal_level, which reflects the user's configured setting, effective_wal_level shows the WAL level currently active inside the system.

      The promotion to effective_wal_level = logical is triggered not only by explicit logical replication slot creation, but also implicitly when a CREATE SUBSCRIPTION command executed on a subscriber creates a logical replication slot on the publisher server.

      The overall flow is as follows:

      img-dgm-wal-level-change-for-logical-decoding-01

      Note that the existing behavior for wal_level = logical remains unchanged. When wal_level is explicitly configured as logical, logical-level WAL logging is always enabled.

      Behavior on standby

      On standby servers, effective_wal_level always mirrors the value from the most upstream server in the replication chain. This ensures consistency across primary and standby nodes.

      When the upstream server demotes its effective_wal_level from logical back to replica, for example after the last logical replication slot is dropped, the same demotion propagates downstream. As a consequence, all logical replication slots present on the standby at that time are invalidated. These slots are marked with invalidation_reason = 'wal_level_insufficient', making it clear that the standby can no longer support logical decoding until the upstream promotes its WAL level again.

      Prior to PostgreSQL 19

      Creating a logical replication slot required wal_level to be set to logical. If the server was configured with wal_level as replica, attempts to create a logical slot would fail:

      postgres=# show wal_level;
       wal_level 
      -----------
       replica
      (1 row)
       
      postgres=#  SELECT pg_create_logical_replication_slot ('slot1', 'pgoutput', false, false);
      ERROR:  logical decoding requires "wal_level" >= "logical"

      New behavior in PostgreSQL 19

      On a server configured with wal_level as replica, creating a logical replication slot no longer fails. Instead, the creation of the first logical replication slot automatically promotes effective_wal_level to logical:

      postgres=# show wal_level;
       wal_level 
      -----------
       replica
       
      postgres=# show effective_wal_level;
       effective_wal_level
      ---------------------
       replica
       
      postgres=# SELECT pg_create_logical_replication_slot('slot1', 'pgoutput', false, false);
       pg_create_logical_replication_slot
      ------------------------------------
       (slot1,0/017FAD30)
      (1 row)
       
      postgres=# show wal_level;
       wal_level
      -----------
       replica
       
      postgres=# show effective_wal_level;
       effective_wal_level
      ---------------------
       logical
       
      -- Let's check the current backend PID:
      postgres=# SELECT pg_backend_pid();
       pg_backend_pid
      ----------------
                47319
      (1 row)

      The log output confirms the transition to the logical decoding enabled state. The PID 47319 matches the current backend, confirming that the backend creating the logical replication slot enabled logical decoding.

      [47319] LOG:  logical decoding is enabled upon creating a new logical replication slot
      [47319] STATEMENT:  SELECT pg_create_logical_replication_slot('slot1', 'pgoutput', false, false);

      Dropping the last logical slot demotes effective_wal_level back to replica:

      postgres=# SELECT pg_drop_replication_slot('slot1');
       pg_drop_replication_slot
      --------------------------
       
      (1 row)
       
      postgres=# show wal_level;
       wal_level 
      -----------
       replica
       
      postgres=# show effective_wal_level;
       effective_wal_level 
      ---------------------
       replica

      Log output reflects the demotion:

      [47312] LOG:  logical decoding is disabled because there are no valid logical replication slots

      Now let's verify which process emitted this log messages:

      postgres=# SELECT pid, backend_type FROM pg_stat_activity WHERE pid = 47312;
        pid  | backend_type
      -------+--------------
       47312 | checkpointer

      This confirms that the demotion of the effective WAL level is performed asynchronously by the checkpointer process.

      Conclusion

      PostgreSQL 19 allows online WAL level change, with the effective level reflected by effective_wal_level. Logical Replication no longer requires a server restart or a permanent wal_level = logical. Instead, the system promotes effective_wal_level to logical when a slot is created and reverts to replica when the last slot is dropped.

      In practice, this means logical replication can now be enabled and disabled seamlessly, with minimal disruption and no wasted resources — a significant step forward in making logical replication management more efficient and user friendly.

      Credit

      This feature was contributed by Masahiko Sawada (commit 67c20979), with design inputs, end-to-end review, and testing support from the team at Fujitsu. The joint effort delivered a long-awaited usability improvement, making logical replication significantly more practical for production environments.

      Topics: PostgreSQL, Logical replication, High Availability, WAL level management, Database optimization, PostgreSQL 19 online WAL level change, dynamic wal_level adjustment in PostgreSQL, Logical decoding, PostgreSQL logical decoding without downtime, enable logical replication without restart

      Receive our blog

      Search by topic

      see all >
      Shveta Malik
      Software Principal Developer
      Shveta Malik specializes in PostgreSQL logical replication. She actively contributes to the PostgreSQL open-source community, focusing on the design, development, and review of advanced replication features that enhance reliability and high-availability architectures.
      Shveta has authored and co-authored several key contributions, including work on replication slot synchronization for failover scenarios. Prior to this, she spent over a decade working on query optimization, execution planning, and performance tuning across large-scale database systems.
      Fujitsu Enterprise Postgres
      is an enhanced distribution of PostgreSQL, 100% compatible and with extended features.
      Compare the list of features.
      roundel-owl-and-book-01PostgreSQL Insider 
      has a series of technical articles for PostgreSQL enthusiasts of all stripes, with tips and how-to's.
      Explore PostgreSQL Insider >
      Subscribe to be notified of future blog posts
      If you would like to be notified of my next blog posts and other PostgreSQL-related articles, fill the form here.

      Read our latest blogs

      Read our most recent articles regarding all aspects of PostgreSQL and Fujitsu Enterprise Postgres.

      Receive our blog

      Fill the form to receive notifications of future posts

      Search by topic

      see all >