tar vs gzip: stop confusing archives with compression and master both

introduction: why this matters

if you've ever worked with linux servers, deployed applications, or managed backups, you've probably encountered files ending in .tar, .gz, or .tar.gz. yet many beginners — and even some experienced developers — confuse what tar and gzip actually do. they are not the same thing, and understanding the difference is a fundamental skill for anyone in devops, full stack development, or general coding.

in this guide, we'll break down both tools, show you exactly how they work with real commands, and by the end, you'll never confuse an archive with compression again.

the core difference: archiving vs. compression

before we dive into the tools, let's establish the most important concept in this entire article:

  • archiving means combining multiple files and directories into a single file. it does not reduce the file size.
  • compression means reducing the file size by encoding data more efficiently. it works on a single file.

think of it this way: archiving is like packing all your clothes into one suitcase, while compression is like vacuum-sealing those clothes so they take up less space inside the suitcase. two different steps, two different purposes.

what is tar? (the archiver)

tar stands for tape archive. it was originally created in the early days of unix to back up files to tape drives. today, it's the standard archiving utility on linux and macos systems.

what tar does

tar takes multiple files and directories and bundles them into a single .tar file (sometimes called a "tarball"). this makes it easier to transfer, store, or manage groups of files. crucially, tar alone does not compress anything — the resulting .tar file is roughly the same size as the original files combined.

essential tar commands

here are the most commonly used tar commands with explanations:

create an archive:

tar -cf archive.tar /path/to/directory
  • -ccreate a new archive
  • -f → specify the filename of the archive

create an archive with verbose output (see what's being added):

tar -cvf archive.tar /path/to/directory
  • -vverbose mode — lists files as they are processed

extract an archive:

tar -xf archive.tar
  • -xextract files from an archive

extract to a specific directory:

tar -xf archive.tar -c /path/to/destination

list the contents of an archive without extracting:

tar -tf archive.tar
  • -tlist the contents of an archive

a real-world example

suppose you have a project folder with the following structure:

my-project/
├── index.html
├── style.css
├── app.js
└── images/
    ├── logo.png
    └── banner.jpg

you can archive the entire folder like this:

tar -cvf my-project.tar my-project/

the output will show:

my-project/
my-project/index.html
my-project/style.css
my-project/app.js
my-project/images/
my-project/images/logo.png
my-project/images/banner.jpg

now you have a single file, my-project.tar, that contains all those files and directories bundled together. but the file size? it's essentially the same as the total size of all the original files. no space was saved.

what is gzip? (the compressor)

gzip stands for gnu zip. it's a compression utility that uses the deflate algorithm to reduce the size of a file. unlike tar, gzip works on only one file at a time — it cannot handle multiple files or directories on its own.

what gzip does

gzip takes a single file and replaces it with a smaller, compressed version. the original file is deleted by default and replaced with a file ending in .gz.

essential gzip commands

compress a file:

gzip filename.txt

this creates filename.txt.gz and removes the original filename.txt.

compress and keep the original file:

gzip -k filename.txt
  • -kkeep the original file

compress with maximum compression level:

gzip -9 filename.txt
  • -9 → use the best compression (slower but smaller file)

decompress a .gz file:

gzip -d filename.txt.gz

or equivalently:

gunzip filename.txt.gz

view compression statistics:

gzip -v filename.txt

output example:

filename.txt:  78.2% -- replaced with filename.txt.gz

a real-world example

let's say you have a log file that's 100mb:

$ ls -lh server.log
-rw-r--r-- 1 user user 100m server.log

$ gzip -k server.log

$ ls -lh server.log.gz
-rw-r--r-- 1 user user 22m server.log.gz

the compressed file is only 22mb — that's a 78% reduction in size. this is incredibly useful for log files, backups, and transferring data over a network.

but here's the key limitation: gzip cannot compress a directory. if you try, you'll get an error:

$ gzip my-project/
gzip: my-project/ is a directory -- ignored

this is exactly why tar and gzip need each other.

tar vs gzip: a side-by-side comparison

feature tar gzip
primary purpose archiving (bundling files) compression (reducing file size)
reduces file size? no yes
handles multiple files? yes no (one file at a time)
handles directories? yes no
output extension .tar .gz
preserves file permissions? yes no
algorithm none (just bundling) deflate

how tar and gzip work together: .tar.gz (tarballs)

here's where the magic happens. since gzip can only compress a single file, and tar can bundle multiple files into one, combining them gives you the best of both worlds: multiple files archived into one, then compressed to save space.

the process looks like this:

  1. tar bundles all files and directories into a single .tar file
  2. gzip compresses that single .tar file into a .tar.gz file

think of it as: tar packs the suitcase, gzip shrinks the suitcase.

creating a .tar.gz archive

the most common way to create a compressed archive is to add the -z flag to tar, which tells it to pipe the output through gzip automatically:

tar -czvf archive.tar.gz /path/to/directory
  • -ccreate a new archive
  • -z → filter the archive through gzip
  • -vverbose output
  • -f → specify the filename

here's a practical example backing up an entire project:

tar -czvf my-website-backup.tar.gz /home/user/my-website/

extracting a .tar.gz archive

tar -xzvf archive.tar.gz
  • -xextract
  • -z → decompress with gzip first
  • -vverbose output
  • -f → specify the filename

extract to a specific directory:

tar -xzvf archive.tar.gz -c /path/to/destination

the two-step equivalent

if you wanted to do the same thing manually in two steps (useful for understanding the process):

# step 1: create a tar archive
tar -cvf archive.tar /path/to/directory

# step 2: compress the tar archive with gzip
gzip archive.tar

this produces the exact same result as tar -czvf archive.tar.gz. the -z flag simply automates both steps into one command.

other compression tools that work with tar

gzip isn't the only compression tool available. tar supports multiple compression algorithms via different flags:

  • bzip2 (-j flag) → better compression than gzip, but slower. produces .tar.bz2 files.
  • xz (-j flag) → best compression ratio, but slowest. produces .tar.xz files.
  • lz4 → very fast compression, decent ratio. great for real-time scenarios.
  • zstd → modern algorithm offering an excellent balance of speed and compression. increasingly popular in devops pipelines.

here's how the commands compare:

# gzip compression (fast, widely compatible)
tar -czvf archive.tar.gz directory/

# bzip2 compression (better ratio, slower)
tar -cjvf archive.tar.bz2 directory/

# xz compression (best ratio, slowest)
tar -cjvf archive.tar.xz directory/

# zstd compression (modern, fast, great ratio)
tar --zstd -cvf archive.tar.zst directory/

compression comparison on a 500mb folder

tool output size compression time extension
tar only (no compression) ~500mb fastest .tar
tar + gzip ~150mb fast .tar.gz / .tgz
tar + bzip2 ~120mb medium .tar.bz2
tar + xz ~100mb slow .tar.xz
tar + zstd ~130mb very fast .tar.zst

note: actual results vary depending on file types. text files compress much better than images or already-compressed files.

common tar.gz recipes for devops and full stack developers

1. backing up a web application

tar -czvf website-backup-$(date +%y%m%d).tar.gz /var/www/html/

this creates a date-stamped backup file like website-backup-20250101.tar.gz. the $(date +%y%m%d) part dynamically generates today's date.

2. deploying code to a server

a common pattern in devops workflows is to package your code and transfer it to a remote server:

# create the archive locally
tar -czvf deploy.tar.gz ./build/

# transfer to remote server
scp deploy.tar.gz user@server:/var/www/app/

# extract on the server
ssh user@server "tar -xzvf /var/www/app/deploy.tar.gz -c /var/www/app/"

3. excluding files from an archive

when archiving a project, you often want to skip node_modules, .git, or other large directories:

tar -czvf project.tar.gz \
    --exclude='node_modules' \
    --exclude='.git' \
    --exclude='*.log' \
    ./my-project/

4. incremental backups

for large file systems, you can create incremental backups that only save files changed since the last backup:

# create a snapshot file to track changes
tar -czvf full-backup.tar.gz \
    --listed-incremental=/tmp/snapshot.snar \
    /data/

# later, create an incremental backup (only new/changed files)
tar -czvf incremental-backup.tar.gz \
    --listed-incremental=/tmp/snapshot.snar \
    /data/

5. splitting large archives

if you need to upload a massive archive to a service with file size limits:

# create the archive and split it into 100mb chunks
tar -czvf - /large/directory/ | split -b 100m - archive-part-

# reassemble and extract later
cat archive-part-* | tar -xzvf -

common mistakes to avoid

mistake 1: using gzip on a directory

# ❌ wrong - gzip cannot compress directories
gzip my-folder/

# ✅ correct - tar first, then compress
tar -czvf my-folder.tar.gz my-folder/

mistake 2: forgetting what's inside the archive

always check the contents before extracting, especially from untrusted sources:

# list contents before extracting
tar -tzf archive.tar.gz

mistake 3: extracting with wrong permissions

by default, tar preserves file permissions from the archive. if you extract as a regular user but the archive was created by root, you might get permission errors. use --no-same-owner if needed:

tar -xzvf archive.tar.gz --no-same-owner

mistake 4: accidentally overwriting files

if you want tar to not overwrite existing files during extraction:

tar -xzvkf archive.tar.gz
  • -kkeep existing files, don't overwrite

mistake 5: confusing .tgz with .tar.gz

good news: .tgz and .tar.gz are exactly the same format. .tgz is simply a shorter file extension. both commands work identically:

tar -czvf file.tgz directory/
tar -czvf file.tar.gz directory/

quick reference cheat sheet

bookmark this section for daily use:

╔══════════════════════════════════════════════════════════════╗
║                    tar + gzip cheat sheet                   ║
╠══════════════════════════════════════════════════════════════╣
║                                                              ║
║  create                                                      ║
║  ──────                                                      ║
║  tar -cvf  archive.tar dir/       → archive only             ║
║  tar -czvf archive.tar.gz dir/    → archive + gzip compress  ║
║  tar -cjvf archive.tar.bz2 dir/   → archive + bzip2          ║
║  tar -cjvf archive.tar.xz dir/    → archive + xz             ║
║                                                              ║
║  extract                                                     ║
║  ───────                                                     ║
║  tar -xvf  archive.tar            → extract .tar             ║
║  tar -xzvf archive.tar.gz         → extract .tar.gz          ║
║  tar -xjvf archive.tar.bz2        → extract .tar.bz2         ║
║  tar -xjvf archive.tar.xz         → extract .tar.xz          ║
║                                                              ║
║  list                                                        ║
║  ────                                                        ║
║  tar -tvf  archive.tar            → list .tar contents       ║
║  tar -tzvf archive.tar.gz         → list .tar.gz contents    ║
║                                                              ║
║  useful flags                                                ║
║  ────────────                                                ║
║  -v    verbose (show files)                                  ║
║  -k    don't overwrite existing files                        ║
║  -c    extract to specified directory                        ║
║  --exclude    exclude files matching pattern                 ║
║                                                              ║
╚══════════════════════════════════════════════════════════════╝

how to choose: when to use what

  • need to bundle multiple files/directories into one? → use tar
  • need to reduce the size of a single file? → use gzip (or bzip2, xz, zstd)
  • need to bundle and compress? → use tar with the -z flag (.tar.gz)
  • transferring files between servers?.tar.gz is the most universally compatible
  • maximum compression, speed doesn't matter?.tar.xz
  • fast compression and decompression?.tar.zst (zstd) is the modern choice
  • docker images, ci/cd pipelines?.tar.gz is the standard

conclusion

the confusion between tar and gzip is one of the most common stumbling blocks for newcomers in devops, full stack, and coding in general. but once you internalize the fundamental difference — tar bundles, gzip shrinks — everything clicks into place.

remember these key takeaways:

  • tar is an archiver — it bundles files together without compression
  • gzip is a compressor — it reduces file size but only works on single files
  • .tar.gz combines both: tar bundles the files, then gzip compresses the bundle
  • modern alternatives like zstd are worth exploring for better performance

practice these commands on your own system. try creating an archive, inspecting its contents, and extracting it. within a few uses, the syntax will become second nature. happy archiving! 🗂️

Comments

Discussion

Share your thoughts and join the conversation

Loading comments...

Join the Discussion

Please log in to share your thoughts and engage with the community.