tar bundles many files and directories into a single archive file (a “tarball”), preserving permissions, ownership and timestamps. Combined with compression, it’s the standard way to package, move and back up files on Linux.

The options look cryptic at first, but there are only a few to learn:

Option Meaning
-c create an archive
-x extract
-t list contents
-f FILE archive file name (always last before the name)
-v verbose: print file names
-z / -j / -J gzip / bzip2 / xz compression
--zstd zstd compression (GNU tar 1.31+)
-C DIR change to DIR first

Create an archive

tar -czvf site-backup.tar.gz /var/www/example.com

Read it as: create, gzip, verbose, file site-backup.tar.gz, containing /var/www/example.com.

tar strips the leading / and prints Removing leading '/' from member names — that’s a safety feature so extraction doesn’t overwrite system paths. To store paths relative to a directory, use -C:

tar -czf site-backup.tar.gz -C /var/www example.com

The archive now contains example.com/… instead of var/www/example.com/….

Several sources at once:

tar -czf configs.tar.gz /etc/nginx /etc/php /etc/mysql

Choose a compression

tar -czf a.tar.gz  dir/     # gzip  — universal, fast
tar -cjf a.tar.bz2 dir/     # bzip2 — smaller, slower (mostly legacy)
tar -cJf a.tar.xz  dir/     # xz    — smallest, slowest
tar --zstd -cf a.tar.zst dir/   # zstd — fast and small, multithreaded
tar -cf a.tar dir/          # no compression

For backups on a modern server, zstd is the best trade-off: compression close to xz at speeds near or above gzip. Already-compressed data (JPEGs, videos, zip files) doesn’t shrink further — skip compression for those to save CPU.

Use all CPU cores with an external compressor:

tar -cf - dir/ | zstd -T0 -o dir.tar.zst
tar -cf - dir/ | pigz > dir.tar.gz

List contents without extracting

tar -tzf site-backup.tar.gz
tar -tvf site-backup.tar.gz | less      # with permissions, sizes, dates

Always check the paths inside an archive from an unknown source before extracting.

Extract

tar -xzvf site-backup.tar.gz                # into the current directory
tar -xzf site-backup.tar.gz -C /tmp/restore # into a specific directory
tar -xf archive.tar.zst                     # GNU tar detects compression automatically

With modern GNU tar, -x auto-detects gzip, bzip2, xz and zstd from the file contents — tar -xf anything.tar.* just works.

The target directory for -C must exist: mkdir -p /tmp/restore first.

Extract specific files

tar -xzf site-backup.tar.gz example.com/wp-config.php
tar -xzf site-backup.tar.gz --wildcards '*.sql'
tar -xzf site-backup.tar.gz example.com/uploads/2026/

The path must match exactly what tar -t shows.

Exclude files

tar -czf site.tar.gz \
  --exclude='node_modules' \
  --exclude='*.log' \
  --exclude='example.com/wp-content/cache' \
  -C /var/www example.com

Or list patterns in a file: --exclude-from=exclude.txt. --exclude-vcs skips .git and similar directories.

Preserve permissions and ownership

tar always stores ownership and permissions. On extraction:

  • As root, ownership and permissions are restored as stored.
  • As a regular user, files belong to you and your umask applies.

Add -p to keep exact permissions as a non-root user, and --numeric-owner when restoring to a different system where user names may map to different IDs. For ACLs and extended attributes (SELinux contexts), add --acls --xattrs.

Append and update

Uncompressed archives only:

tar -rf archive.tar newfile.txt      # append
tar -uf archive.tar dir/             # add files newer than those in the archive

Copy a directory tree between servers

tar can stream over SSH without creating an intermediate file:

tar -czf - /var/www/example.com | ssh user@new-server 'tar -xzf - -C /'

For repeated syncs, rsync is better because it only sends changes.

Dated backups with cron

#!/bin/bash
set -euo pipefail
tar --zstd -cf /var/backups/www-$(date +%F).tar.zst -C /var/www .
find /var/backups -name 'www-*.tar.zst' -mtime +7 -delete

Schedule it with cron, and copy archives off the server — a backup on the same disk isn’t a backup. For deduplicated, encrypted, incremental backups, look at BorgBackup or restic.

Verify an archive

tar -tzf backup.tar.gz > /dev/null && echo OK
gzip -t backup.tar.gz
zstd -t backup.tar.zst
tar -dzf backup.tar.gz -C /           # compare archive with the filesystem

Troubleshooting

  • tar: Exiting with failure status due to previous errors — scroll up; usually unreadable files (run as root) or files that changed while being read (file changed as we read it — harmless for logs; for databases, back up with a dump instead).
  • gzip: stdin: not in gzip format — the file isn’t gzip; check with file archive. Use tar -xf and let tar detect the format.
  • Cannot open: No such file or directory on extraction of a member — the path doesn’t match; list with tar -t first.

Also see zip and unzip on Linux for the Windows-friendly format. If you archive a lot of data, a Storage VPS is an inexpensive place to keep the tarballs.

  • Linux
  • Command Line
  • Backups