How to Perform tar Incremental Backup on Linux

Deepak Prasad
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/:

bash
mkdir -p /tmp/glc-tar-inc/{data,metadata,archives}

Add five 10 KiB files to the source directory:

bash
for i in 1 2 3 4 5; do fallocate -l 10K /tmp/glc-tar-inc/data/file$i; done

List the source files before the first backup:

bash
ls -l /tmp/glc-tar-inc/data/

Sample output:

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 file5

Run 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:

bash
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 data

Sample output:

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/file5

Inspect 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:

bash
tar --list --incremental -vv --file=/tmp/glc-tar-inc/archives/data-full.tgz

Sample output:

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/file5

All 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:

bash
rm -f /tmp/glc-tar-inc/data/file5

Append to an existing file so tar treats it as changed:

bash
echo "changed" >> /tmp/glc-tar-inc/data/file2

Add a new file for the incremental run to pick up:

bash
fallocate -l 10K /tmp/glc-tar-inc/data/file6

Confirm the live directory before the incremental backup:

bash
ls -l /tmp/glc-tar-inc/data/

Sample output:

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 file6

Run the next backup with the same snapshot file and a new archive name:

bash
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 data

Sample output:

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/file6

Only file2 (modified) and file6 (new) changed since level 0, so the incremental archive is much smaller. List the incremental archive:

bash
tar --list --incremental -vv --file=/tmp/glc-tar-inc/archives/data-inc1.tgz

Sample output:

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/file6

Y 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:

bash
rm -rf /tmp/glc-tar-inc/data

Extract the level 0 archive first. Point --listed-incremental at /dev/null so restore does not update the snapshot file:

bash
tar --extract --listed-incremental=/dev/null --file=/tmp/glc-tar-inc/archives/data-full.tgz -C /tmp/glc-tar-inc

List the recovered files — you should see the original five files, including file5:

bash
ls -l /tmp/glc-tar-inc/data/

Sample output:

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 file5

Apply the level 1 incremental on top:

bash
tar --extract --listed-incremental=/dev/null --file=/tmp/glc-tar-inc/archives/data-inc1.tgz -C /tmp/glc-tar-inc

Check the final tree — file5 should be gone, file6 present, and file2 should reflect the appended change (10248 bytes here):

bash
ls -l /tmp/glc-tar-inc/data/

Sample output:

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 file6

The 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.tgzY 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.


Frequently Asked Questions

1. What is a level 0 tar incremental backup?

Level 0 is the first listed-incremental backup for a source tree. GNU tar creates it when the snapshot file does not exist yet, or when you pass --level=0. It archives every file under the source directory and writes the snapshot metadata.

2. What is the tar snapshot file used for?

The file passed to --listed-incremental stores GNU tar metadata about the last backup. On the next run tar compares the live filesystem to that snapshot and archives only new or changed files into the next incremental archive.

3. How do I restore tar incremental backups?

Extract the level 0 archive first with --listed-incremental=/dev/null, then apply each later incremental archive in order the same way. /dev/null tells tar not to update the snapshot file during restore.

4. Does BSD tar support --listed-incremental?

Listed-incremental backups are a GNU tar feature. On macOS or systems with BSD tar, install GNU tar as gtar or use a Linux host with GNU tar for this workflow.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration