| Tested on | RHEL 10.2 (Coughlan) — vm1.lab.example |
|---|---|
| Package | tar 1.35-11.el10 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Fedora, Ubuntu, and Debian with GNU tar |
| Privilege | Read access to the source tree; write access to backup and snapshot paths |
| Scope | GNU tar --listed-incremental level 0 and level 1 backup, archive inspection, and restore. Does not cover dump/restore, rsync, or full automation scripting. |
| Related guides | tar command bzip2 command Copy files between servers LVM snapshot backup Backup a Linux partition |
An incremental tar backup stores only files that
changed since the last run. GNU tar tracks state in a snapshot file you pass
with --listed-incremental. The first backup is level 0 (full); later runs
produce smaller archives with just new or modified files.
This walkthrough uses a disposable lab tree under /tmp/glc-tar-inc/, takes
a full backup, changes a few files, takes one incremental backup, then restores
the tree from both archives.
Quick answer
| Task | Command pattern |
|---|---|
| Level 0 (full) backup | tar -czg SNAPSHOT -f ARCHIVE.tgz -C PARENT SOURCE_DIR |
| Next incremental backup | Same command with the same snapshot file and a new archive name |
| Inspect archive members | tar --list --incremental -vv -f ARCHIVE.tgz |
| Restore full then incremental | tar -xg /dev/null -f ARCHIVE.tgz -C DEST for each archive in order |
-g is short for --listed-incremental. -z compresses with gzip. Keep the
snapshot file safe between backup runs; without it, tar cannot tell what
changed.
How GNU tar incremental backup works
GNU tar writes a snapshot file when you pass --listed-incremental=FILE (or
-g FILE). That file records which paths existed and their metadata at the end
of the backup. On the next run:
- new or changed files go into the new archive;
- unchanged files are skipped;
- deleted files are not stored as normal file members, but the incremental archive records directory state (dumpdirs) so GNU tar can remove them during an incremental restore.
The first backup for a source tree is level 0. If the snapshot file does not
exist yet, tar treats the run as level 0 automatically. You can also force it
with --level=0.
Restore is the reverse: extract the level 0 archive first, then apply each
incremental archive in chronological order. Use
--listed-incremental=/dev/null during extract so tar does not rewrite the
snapshot file on disk.
Take a level 0 backup
Create a small source tree and backup directories under /tmp/glc-tar-inc/:
mkdir -p /tmp/glc-tar-inc/{data,metadata,archives}Add five 10 KiB files to the source directory:
for i in 1 2 3 4 5; do fallocate -l 10K /tmp/glc-tar-inc/data/file$i; doneList the source files before the first backup:
ls -l /tmp/glc-tar-inc/data/Sample output:
total 60
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file1
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file2
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file3
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file4
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file5Run the level 0 backup from the parent of data/. The snapshot file
metadata/data.snar does not exist yet, so tar archives the full tree:
tar -cvz --listed-incremental=/tmp/glc-tar-inc/metadata/data.snar --file=/tmp/glc-tar-inc/archives/data-full.tgz -C /tmp/glc-tar-inc dataSample output:
drwxr-xr-x root/root 0 2026-08-21 13:43 data/
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file1
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file2
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file3
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file4
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file5Inspect what the archive stored. With --list --incremental, tar prints
Y when the path is stored in this archive and N when the path existed
when the backup was made but was not archived because it had not changed
since the previous backup:
tar --list --incremental -vv --file=/tmp/glc-tar-inc/archives/data-full.tgzSample output:
drwxr-xr-x root/root 36 2026-08-21 13:43 data/
Y file1
Y file2
Y file3
Y file4
Y file5
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file1
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file2
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file3
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file4
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file5All five files show Y because this is the full backup. tar also created
metadata/data.snar on disk — keep that file for the next incremental run.
Take a level 1 incremental backup
Change the live source tree: delete one file, modify another, and add a new file:
rm -f /tmp/glc-tar-inc/data/file5Append to an existing file so tar treats it as changed:
echo "changed" >> /tmp/glc-tar-inc/data/file2Add a new file for the incremental run to pick up:
fallocate -l 10K /tmp/glc-tar-inc/data/file6Confirm the live directory before the incremental backup:
ls -l /tmp/glc-tar-inc/data/Sample output:
total 60
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file1
-rw-r--r--. 1 root root 10248 Aug 21 13:43 file2
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file3
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file4
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file6Run the next backup with the same snapshot file and a new archive name:
tar -cvz --listed-incremental=/tmp/glc-tar-inc/metadata/data.snar --file=/tmp/glc-tar-inc/archives/data-inc1.tgz -C /tmp/glc-tar-inc dataSample output:
drwxr-xr-x root/root 0 2026-08-21 13:43 data/
-rw-r--r-- root/root 10248 2026-08-21 13:43 data/file2
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file6Only file2 (modified) and file6 (new) changed since level 0, so the
incremental archive is much smaller. List the incremental archive:
tar --list --incremental -vv --file=/tmp/glc-tar-inc/archives/data-inc1.tgzSample output:
drwxr-xr-x root/root 36 2026-08-21 13:43 data/
N file1
Y file2
N file3
N file4
Y file6
-rw-r--r-- root/root 10248 2026-08-21 13:43 data/file2
-rw-r--r-- root/root 10240 2026-08-21 13:43 data/file6Y file2 and Y file6 are the changed and new members stored in this
archive. N marks paths that existed when the backup ran but were unchanged
since the previous backup. file5 does not appear because it was deleted
on disk; the incremental archive still records directory state so tar can
drop file5 during restore.
Restore from incremental archives
Simulate data loss by removing the source tree:
rm -rf /tmp/glc-tar-inc/dataExtract the level 0 archive first. Point --listed-incremental at /dev/null
so restore does not update the snapshot file:
tar --extract --listed-incremental=/dev/null --file=/tmp/glc-tar-inc/archives/data-full.tgz -C /tmp/glc-tar-incList the recovered files — you should see the original five files, including
file5:
ls -l /tmp/glc-tar-inc/data/Sample output:
total 60
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file1
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file2
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file3
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file4
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file5Apply the level 1 incremental on top:
tar --extract --listed-incremental=/dev/null --file=/tmp/glc-tar-inc/archives/data-inc1.tgz -C /tmp/glc-tar-incCheck the final tree — file5 should be gone, file6 present, and file2
should reflect the appended change (10248 bytes here):
ls -l /tmp/glc-tar-inc/data/Sample output:
total 60
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file1
-rw-r--r--. 1 root root 10248 Aug 21 13:43 file2
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file3
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file4
-rw-r--r--. 1 root root 10240 Aug 21 13:43 file6The incremental extract applied the modified file2, added file6, and
removed file5 using the directory-state metadata in the incremental archive.
If you create more incremental archives with the same evolving snapshot file, restore the full archive first and then apply every subsequent incremental archive in creation order.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Next backup archives everything again | Snapshot file missing or wrong path | Reuse the same --listed-incremental file from the level 0 run |
tar: unrecognized option for -g |
BSD tar instead of GNU tar | Install GNU tar; on some systems the binary is gtar |
| Restore leaves deleted files behind | Incremental that removed the file was not applied | Extract full backup first, then each incremental in order |
| Snapshot and archives out of sync | Restored with snapshot file instead of /dev/null |
Re-run extract with --listed-incremental=/dev/null |
| Archive much larger than expected | Source files changed timestamps or permissions | Normal for incremental metadata; compare with --list --incremental |
References
Summary
GNU tar incremental backup uses a snapshot file with --listed-incremental.
The first run produces a level 0 full archive and writes snapshot metadata.
Later runs with the same snapshot file create smaller archives that contain
only new or changed files.
Inspect an archive with tar --list --incremental -vv -f ARCHIVE.tgz — Y
means the path is stored in that archive; N means it existed when the backup
ran but was skipped as unchanged. To recover, extract the full backup first,
then each incremental in order, always passing --listed-incremental=/dev/null
so tar does not overwrite the snapshot during restore. Incremental extracts
also apply directory-state metadata to remove files deleted since the previous
backup.
Keep the snapshot file alongside your archives in production, and name each incremental archive with the date or level so restore order stays obvious. For live filesystem snapshots before backup, see LVM snapshot backup.

