tar, zip and friends: compress anything on Linux
Every developer working on a Linux server eventually faces the same awkward moment: you need to bundle up a project or restore a database dump, and you cannot remember which letters to pass to tar. Is it -xvf? -czf? Where does the archive name go?
Compression on Linux does not have to be an exercise in guesswork. Whether you are shipping build artifacts, downloading server logs, or keeping nightly backups of a web app, knowing how to pack and unpack data cleanly is an essential developer skill.
This guide gives you a grounded, side-by-side breakdown of the two most common tools on Linux—tar and zip—so you always know which tool to reach for and which flags to run.
Part 1: Archiving vs. Compressing (The Big Difference)
In the Windows and macOS worlds, “zipping” a folder does two things at once: it gathers all the files into a single container, and it shrinks the file size.
Linux separates these two jobs:
- Archiving means gluing multiple files and directories into one single file, preserving permissions and directory structures. The classic tool for this is
tar(short for Tape ARchive). An uncompressed tarball ends with.tar. - Compressing means taking a single file and shrinking its size. Linux uses dedicated tools like
gzip,bzip2, orxzfor this job.
Because gzip can only compress one file at a time, Linux pairs it with tar. First, tar bundles your files into project.tar. Then, gzip shrinks it into project.tar.gz (sometimes shortened to .tgz).
Meanwhile, zip works like it does on Windows: it archives and compresses in a single pass.
| Tool / Format | Extension | Strengths | Typical Use Case |
|---|---|---|---|
| tar + gzip | .tar.gz, .tgz |
Fast, low CPU overhead, preserves Linux file permissions natively | Server backups, source code releases, deployment packages |
| tar + xz | .tar.xz |
Best compression ratio, smaller file size, slower to compress | Distributing Linux kernel images, large static datasets |
| zip | .zip |
Universally supported across Windows, macOS, and Linux | Sharing files with non-Linux users |
Part 2: The Essential tar Cheatsheet
Modern versions of tar are smart enough to detect compression types automatically, but you will still encounter flags constantly in scripts and server documentation.
Here are the primary operation flags:
-c: Create a new archive.-x: Extract an archive.-t: Test/List the contents without extracting.
Here are the modifier flags:
-z: Filter through gzip (.tar.gz).-j: Filter through bzip2 (.tar.bz2).-J: Filter through xz (.tar.xz).-v: Verbose mode (shows files as they are processed).-f: File name (tells tar that the next argument is the archive file).
Rule of Thumb: Always keep the
fflag at the end of your flag group, becausetarexpects the archive name immediately afterf.
# Good: 'f' is directly followed by the archive name
tar -czvf my_backup.tar.gz my_folder/
# Bad: 'z' comes after 'f', so tar looks for a file called 'z'
tar -czfv my_backup.tar.gz my_folder/
Part 3: The Friendly Alternative: zip and unzip
If your system does not have zip installed, you can grab it via your package manager:
# Ubuntu / Debian
sudo apt update && sudo apt install zip unzip
# RHEL / Fedora / AlmaLinux
sudo dnf install zip unzip
Unlike tar, zip requires an explicit recursive flag (-r) when you want to pack a directory. If you forget -r, zip will only record the directory container itself, leaving out all the files inside.
- To create:
zip -r output.zip folder_name/ - To list:
unzip -l output.zip - To extract:
unzip output.zip
Part 4: Side-by-Side Recipes
Here is how common operational tasks compare side-by-side.
1. Creating an Archive
Using tar.gz:
tar -czvf app_backup.tar.gz /var/www/my-app
Using zip:
zip -r app_backup.zip /var/www/my-app
2. Inspecting Contents Without Extracting
Never extract an unknown archive directly into your working directory without checking its layout first.
Using tar:
tar -tzf app_backup.tar.gz
Using zip:
unzip -l app_backup.zip
3. Extracting to a Specific Directory
Using tar (uses capital -C):
mkdir -p /tmp/restore_target
tar -xzvf app_backup.tar.gz -C /tmp/restore_target
Using zip (uses lowercase -d):
mkdir -p /tmp/restore_target
unzip app_backup.zip -d /tmp/restore_target
4. Excluding Specific Folders (like .git or node_modules)
Using tar:
tar --exclude="node_modules" --exclude=".git" -czvf project.tar.gz ./my-project
Using zip:
zip -r project.zip ./my-project -x "*/node_modules/*" "*/.git/*"
Hands-on example: A Complete Backup and Verification Workflow
Let’s test this in a safe playground directory. Run these commands directly in your terminal:
# 1. Create a dummy project structure
mkdir -p ~/compression_lab/source/assets
mkdir -p ~/compression_lab/source/cache
echo "DATABASE_URL=postgres://localhost:5432" > ~/compression_lab/source/.env
echo "console.log('App running');" > ~/compression_lab/source/app.js
echo "Temporary cache data" > ~/compression_lab/source/cache/temp.log
echo "Logo binary data" > ~/compression_lab/source/assets/logo.png
cd ~/compression_lab
# 2. Create a tar.gz backup while skipping the cache folder
tar --exclude="source/cache" -czvf site_backup.tar.gz source/
# 3. Create a zip backup of the same directory
zip -r site_backup.zip source/ -x "source/cache/*"
# 4. Verify that 'temp.log' was excluded from both
tar -tzf site_backup.tar.gz | grep temp.log || echo "cache excluded from tar successfully"
unzip -l site_backup.zip | grep temp.log || echo "cache excluded from zip successfully"
# 5. Extract the tar.gz backup into a clean restore folder
mkdir restore_tar
tar -xzvf site_backup.tar.gz -C restore_tar/
# 6. Verify restored files
ls -la restore_tar/source
You should see your .env, app.js, and assets/ directory intact inside restore_tar/source, with cache/ completely omitted.
Common mistakes / troubleshooting
- The “Tarbomb” explosion:
If someone archives files without a root folder (
tar -czf files.tar.gz file1.txt file2.txt file3.txt), extracting it will dump hundreds of loose files into your current directory. Prevent this by checking withtar -tzf archive.tar.gzfirst, or always extract into a dedicated directory using-C target_folder. - Putting
-fin the wrong position: Runningtar -czfv backup.tar.gz folder/will fail with an error likeCannot open: No such file or directory.tartreats the flag immediately followingfas the archive filename. Always makefthe last flag in the cluster:tar -czvf. - Forgetting
-rwithzip: If you runzip backup.zip my_folder,ziponly records the directory entry itself, resulting in a tiny, empty archive. Always usezip -r. - Absolute path warnings:
If you run
tar -czf backup.tar.gz /var/log, you will seetar: Removing leading '/' from member names. This is intentional behavior:tarremoves the root slash so that when you extract the archive later, it does not accidentally overwrite your root system files.
Try it yourself
Run this quick test to build muscle memory:
- Create a directory named
docscontaining two files:resume.txtanddraft.txt. - Compress
docsintodocs.tar.xzusing thexzalgorithm (hint: look up the modifier flag in Part 2). - Check the contents of
docs.tar.xzwithout extracting it. - Extract it into a newly created folder called
extracted_docs.
What’s next
- BorgBackup and Rclone: Taking compression to production with deduplication and direct cloud syncing.
- Archive Encryption: Using
gpgto encrypt.tar.gzbundles before sending them across public networks. - Automated Cron Backups: Writing a short shell script to zip database dumps and prune archives older than 7 days.
Stay tuned for our upcoming guide: Automating Remote Backups with Cron and GPG.
Bookmark this tab for the next time you need to pack or unpack files on a server without googling tar flags!