keepcalculator

06 Numbers and Powers

Checkpoints vs WAL: Postgres Confusion Explained

Card No. 06·41262 · Updated · Standard formula, shown below

Average pace 5.00 min/km
Average speed
12.00 km/h
Result
Finish time
50 min
You entered
Distance
10 km
You entered
You enter
Finish time, Distance
You get
Average pace, Average speed
Rounding
2 dp

Checkpoints and WAL (Write-Ahead Log) are two separate mechanisms in PostgreSQL, and the confusion between them is common. The core difference: WAL is the journal of every change, written first for crash safety, while a checkpoint is a marker that flushes all dirty data from shared buffers to disk, allowing the WAL to be truncated. They work together, but they are not the same thing, and understanding their distinct roles is key to tuning a PostgreSQL server.

Formula

The calculator works out your average pace and speed for a run or ride. The formulas are:

Pace (min/km) = Total time (minutes) / Distance (km)

Speed (km/h) = Distance (km) / (Total time (minutes) / 60)

Where:

  • Total time is your finish time in minutes.
  • Distance is the length of your run in kilometers.

Worked Example

Using the default values: finish time = 50 minutes, distance = 10 km.

First, calculate the pace:

Pace = 50 min / 10 km = 5.00 min/km

Next, calculate the speed:

Speed = 10 km / (50 min / 60) = 10 km / 0.8333 h = 12.00 km/h

So the average pace is 5:00 min/km and the average speed is 12.00 km/h.

Background: Why Both Exist

PostgreSQL uses both WAL and checkpoints to solve two related but distinct problems. The WAL (also called the transaction log) is an append-only record of every change made to the database. Its primary purpose is crash recovery: if the server crashes, PostgreSQL can replay the WAL from the last checkpoint to restore the database to a consistent state. A checkpoint, on the other hand, is the process of writing all dirty (modified) pages from shared buffers to the actual data files on disk. This is a background activity that ensures the data files are eventually up to date, and it allows the server to recycle or remove old WAL segments.

The confusion often arises because both are related to disk I/O and durability. But they are on opposite sides of the same coin: WAL is the record of changes, and a checkpoint is the act of applying those changes to the permanent data files.

How WAL Works

When a transaction commits, PostgreSQL writes the changes to the WAL buffer, and then flushes that buffer to disk (unless synchronous_commit is set to off). This ensures that the change is durable even if the server crashes immediately after. The actual data pages in shared buffers are not written at commit time; they are written later, either by a background writer or during a checkpoint. This is why WAL is often described as “write-ahead� – the log entry is written before the actual data page is modified on disk.

WAL segments are typically 16 MB each. They are created, filled, and then recycled or archived. The server keeps a set of WAL segments that are needed for recovery, plus some extra. The max_wal_size setting controls how much WAL is kept before a checkpoint is forced.

How Checkpoints Work

A checkpoint is a point in the WAL stream from which recovery can start. When a checkpoint occurs, PostgreSQL performs several steps:

  1. It records the checkpoint location in the WAL.
  2. It writes all dirty buffers from shared memory to the data files.
  3. It flushes the data files to disk.
  4. It updates the control file with the checkpoint location.

After a checkpoint, the server can discard WAL segments before the checkpoint. The checkpoint process is controlled by two main parameters: checkpoint_timeout (default 5 minutes) and max_wal_size (default 1 GB). A checkpoint is triggered when either the timeout expires or the WAL size reaches the maximum. The goal is to spread the I/O load, so checkpoints are “spread� over a period controlled by checkpoint_completion_target (default 0.5, meaning the checkpoint is spread over half the timeout interval).

How to Choose the Right Settings

Choosing the right settings for WAL and checkpoints depends on your workload and hardware. Here are the key considerations:

  • WAL size: A larger max_wal_size means checkpoints happen less often, which reduces the frequency of large write spikes. However, it also means that after a crash, recovery takes longer because more WAL must be replayed. For systems with high write volume, a larger value (e.g., 4-8 GB) is often beneficial.
  • Checkpoint timeout: A shorter timeout means more frequent checkpoints, which spreads the I/O load but also increases the total I/O overhead. A longer timeout reduces overhead but can lead to large checkpoints that cause noticeable latency spikes.
  • Checkpoint completion target: This controls how quickly the checkpoint is done. A value closer to 1 spreads the writes more evenly, but if the system is idle, the checkpoint may not finish before the next one starts.
  • Disk speed: On slow disks, frequent checkpoints can cause severe performance degradation. On fast SSDs, the impact is less noticeable.

There is no one-size-fits-all answer. The best approach is to monitor your system’s WAL generation rate and checkpoint frequency, then adjust accordingly.

Common Problems and Misconceptions

One common misconception is that increasing max_wal_size improves performance. While it can reduce checkpoint frequency, it also increases crash recovery time. Another issue is that developers often confuse “checkpoint� with “vacuum� – both are background processes, but they serve completely different purposes. Vacuum cleans up dead rows, while checkpoints synchronize data files with WAL.

Another problem is that some users disable WAL or checkpoints to improve performance, which is dangerous. Without WAL, you lose crash safety entirely. Without checkpoints, WAL grows indefinitely, eventually filling the disk. Both are essential.

Comparisons: WAL vs Checkpoint vs fsync

WAL and checkpoints are often discussed alongside fsync. fsync is the system call that forces data to be physically written to disk. PostgreSQL uses fsync when flushing WAL buffers and during checkpoints. If you disable fsync (not recommended), the database may report a transaction as committed even though it is not durable. This is a separate concept from both WAL and checkpoints.

Another related concept is the background writer, which writes dirty buffers continuously to avoid large checkpoints. The background writer and checkpoints work together: the background writer writes some dirty pages, and the checkpoint writes the rest.

Costs and Trade-offs

The main cost of WAL is disk I/O for every commit (if synchronous). The main cost of checkpoints is the burst of I/O when dirty buffers are flushed. The trade-off is between durability and performance. If you set synchronous_commit = off, you reduce WAL flushing frequency, but you risk losing recent transactions in a crash. If you set checkpoint_timeout very high, you reduce checkpoint overhead, but you increase recovery time and the risk of running out of WAL space.

It’s also important to note that WAL is written sequentially, which is fast on both HDDs and SSDs. Checkpoints, however, involve random writes to data files, which can be slow on HDDs. This is why spreading checkpoints is beneficial.

Safety and Best Practices

Never disable WAL or checkpoints. Always ensure that fsync is on (the default). For production systems, use a dedicated disk for WAL if possible, and monitor the WAL directory for growth. If you see frequent checkpoints (more than every few minutes), consider increasing max_wal_size. If you see long recovery times after a crash, consider decreasing it.

Also, remember that pg_basebackup and continuous archiving rely on WAL. If you are using streaming replication, the standby replays WAL continuously. Checkpoints on the primary are independent of the standby’s recovery, but the standby also performs its own checkpoints.

Frequently Asked Questions

Q: Is a checkpoint the same as a WAL flush?
A: No. A WAL flush is writing the WAL buffer to disk at commit time. A checkpoint is writing all dirty data pages to disk. They are separate operations.

Q: Why does PostgreSQL need both WAL and checkpoints?
A: WAL ensures durability and crash recovery, while checkpoints allow the WAL to be truncated and keep data files up to date. Without checkpoints, WAL would grow forever.

Q: What happens if I set checkpoint_timeout to 0?
A: Setting it to 0 disables time-based checkpoints, but checkpoints will still occur when max_wal_size is reached. This is not recommended for production because it can lead to huge checkpoints.

Q: Does increasing max_wal_size improve performance?
A: It can, by reducing checkpoint frequency. However, it also increases recovery time after a crash. The optimal value depends on your workload.

Q: Can I turn off WAL for better performance?
A: No. WAL is essential for crash safety. Turning it off would risk data loss and corruption. You can adjust synchronous_commit to reduce WAL flushing, but that trades durability for speed.

Q: How do I know when a checkpoint is happening?
A: You can see checkpoint activity in the PostgreSQL logs if you set log_checkpoints = on. This logs the start and end of each checkpoint, along with the number of buffers written.

Related

Formula used
in t | Finish time | min | 50 | 0
in d | Distance | km | 10 | 0 | 100000
out pace | Average pace | min/km | t / d | 2
out speed | Average speed | km/h | d / (t / 60) | 2

Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →