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 withfile archive. Usetar -xfand let tar detect the format.Cannot open: No such file or directoryon extraction of a member — the path doesn’t match; list withtar -tfirst.
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.