Copy-on-Write principle in ZFS
Copy-on-Write is an optimization principle of data processing in which changes are not made directly to the existing data set, but are always written to a new copy. As the cornerstone of the ZFS file system's storage strategy, CoW, in combination with transaction groups, ensures that an interrupted write operation can never result in an inconsistent file system. This is why ZFS stands out from classic file systems that overwrite the data completely.
Copy-on-Write principle
For write operations based on the CoW principle, data blocks are not overwritten when changes are made. Instead, new data blocks are written with the changes, and the old data blocks are simply overwritten. To receive the consistency of the data, CoW works with a reference system that is also known as Hash-Tree (or Merkle-Tree)[1]. With the help of this system it is ensured that errors in data integrity can be noticed all time.
The tree structure

In the first image, a simplified view of a hash tree is represented:
- At the endpoints of the trees, that are also called leaves, the data blocks can be found.
- The nodes above, inner nodes or branches, include block pointers. Every of these pointers includes information on the underlying blocks, for example the physical location of the data, the size of blocks as well as the number of the transaction group (Birth-TXG), in which the block has been written to. The most important information, however, is the check sum.
- At the top level, the uberblock is located. This value is unique within a
zpooland is recalculated after every write operation. It includes the check sum from which can be used to verify all data contained inzpool.
Application in transaction groups
ZFS stores the data in so-called transaction groups (txg) in the RAM of the system. After a determined timeline, the default setting is 5 seconds, or when enough data has been collected, all changes collected in the transaction group are committed simultaneously[2].
With this procedure, it is ensured that an inconsistent data set is excluded by an interrupted writing process.
Either the txg is committed: Then a new "uberblock" was created, and the file system is now consistent.
Or the txg has not been committed: In that case, the old "uberblock" is considered current, and the file system is also consistent (just older).
The writing process

In the second image, the condition of the file system can be seen with Copy-on-Write after a writing process. The following steps have contributed to this result:
- A change makes it necessary to replace the data in the block
D4 - A new block
D4'is created that includes the new data - The new block should be included into the Hash-tree. For this, it is necessary to form a new
inode2, which is described withinode2'here. This step is necessary, as the checksum must be recalculated for all parent nodes - As described in step 3,
rootanduberblockare also recreated - The inner nodes are reconnected with the unchanged nodes and the check sums are reformed. The new data blocks are now integrated
With the integration of the new data block, the old data block D4 was replaced and released, just like all parent nodes. As long as there is no snapshot that references the old block, it can be reused for future write operations.
Consequences of CoW-strategy
CoW gives rise to some of ZFS's most important features as a logical consequence. However, this also highlights some of ZFS's weaknesses. These are listed as advantages and disadvantages in the following.
Advantages
- Snapshots – in other words, snapshots of a system's state - can be simply created by CoW. All you need to do is reference and freeze the "uberblock" and its underlying nodes and blocks.
- Clones can be also simply created, as simple references can be used here as well.
- Incremental Duplication is exactly, as every block knows, in which transaction group it has been created. This allows ZFS to jump directly to the changed sections when comparing two snapshots, rather than checking each file individually.
- Data corruption is traceable and often repairable. Damaged blocks can be identified by verifying the check sums. If the file system has been built redundant, no damaged block can be recreated in most cases.
fsckis obsolete, as CoW always ensures a consistant pool.
Disadvantages
- Fragmentation occurs. Every change is written into new blocks. As a result, even files that were originally written sequentially become fragmented. The fuller
zpoolgets, the more difficult it gets to find sufficiently contiguous blocks for sequential writing processes. - Free storage space is required at all times, because even during deletion operations, the blocks that were used are not deleted; instead, new nodes and blocks must be created.
- If only parts of a data set must be changed, it can be slow independent of the
recordsize, as the whole data set must be read. For a data set withrecordsize=128kin which 8 KB are to be modified, 128 KB must be read, 8 KB must be modified in memory, and the result must then be written back as a new 128-KB record.
More information
ZFS, Part 1: Concepts and basics from Michael Plura (heise.de, 2017)
The Time Machine in Kernel Space: ZFS-Workflows on Ubuntu 24.04 (linux-magazin.de, 2026)
"ZFS: The last word in file systems." by Jeff Bonwick (web.archive.org, 2026)
Sources
- ↑ Merkle Tree (en.wikipedia.org, 2026)
- ↑ 2.0 2.1 Copy-on-Write in the OpenZFS Documentation (openzfs.github.io, 2026)
|
Author: Stefan Bohn Stefan Bohn has been employed at Thomas-Krenn.AG since 2020. Originally based in PreSales as a consultant for IT solutions, he moved to Product Management in 2022. There he dedicates himself to knowledge transfer and also drives the Thomas-Krenn Wiki. |
|
Translator: Alina Ranzinger Alina has been working at Thomas-Krenn.AG since 2024. After her training as multilingual business assistant, she got her job as assistant of the Product Management and is responsible for the translation of texts and for the organisation of the department.
|

