ozip is a fast, parallel zip compression tool written in Go. Drop-in replacement for zip with smart defaults, powerful exclusion patterns, and production-ready reliability.
Contact us and let us know on how many servers you'd like to use it so you can get you a good price for it.
ozip vs zip: Full Comparison
Test Setup
testdir/
├── root.log
├── keep.txt
├── dir1/
│ ├── level1.log
│ └── dir2/
│ ├── level2.log
│ └── dir3/
│ ├── level3.log
│ └── level3.txt
├── logs/
│ └── app.log
└── deep/
└── nested/
└── path/
└── file.LOG
Exclude Pattern Behavior
| Behavior | zip (Info-ZIP) | ozip |
|---|---|---|
| Case sensitivity | Case-sensitive | Case-insensitive |
* crosses / |
Yes | No |
Simple pattern (*.log) matches all levels |
Yes | Yes (basename match) |
Path pattern (dir1/*.log) |
Matches ALL depths under dir1/ | Matches only dir1/level1.log |
Trailing / = directory only |
No effect | Yes |
| Regex support | No | Yes (--app-xr) |
Test Results
Simple pattern: *.log
zip: Excludes root.log, level1.log, level2.log, level3.log, app.log. Does NOT exclude file.LOG (case-sensitive).
ozip: Excludes all of the above AND file.LOG (case-insensitive).
Path pattern: dir1/*.log — the key difference
zip: Excludes dir1/level1.log, dir1/dir2/level2.log, AND dir1/dir2/dir3/level3.log. The * crosses / boundaries, matching all .log files at any depth under dir1/.
ozip: Excludes only dir1/level1.log. The * stays within a single path segment (Go's filepath.Match behavior). To exclude all depths, use regex: --app-xr 'dir1/.*\.log$'.
Wildcard dir1/* — crosses all levels in zip
zip: dir1/* excludes the entire dir1/ subtree — all files and subdirectories at every depth.
ozip: dir1/* excludes only direct children of dir1/ (one level). For the full subtree, use dir1/ (trailing slash) or --app-xr 'dir1/'.
Case sensitivity: *.LOG
zip: Only excludes file.LOG. Does NOT exclude .log files.
ozip: Excludes ALL .log and .LOG files. Both pattern and path are lowercased before matching.
Directory-only: dir2/
zip: Trailing slash has no special effect. dir2/ did NOT exclude the dir2 directory — it was still included in the archive.
ozip: Trailing slash restricts the pattern to directories only. dir2/ excludes the directory and its entire subtree.
Summary
Where ozip improves on zip
Case-insensitive matching. A single -x '*.log' catches file.log, FILE.LOG, debug.Log, and every variation. On web servers where file naming is inconsistent, this prevents files from slipping through.
*Predictable `behavior.** In zip,dir1/.logsilently matches 3 levels deep. In ozip,always means one path segment — no surprises. When you need multi-level matching, use regex (--app-xr`) which makes the intent explicit.
Directory-only patterns. Trailing / in ozip excludes directories and their subtrees. In zip, trailing / has no effect — you need dir/* instead, which also crosses boundaries unpredictably.
Regex support. ozip's --app-xr flag provides full regex exclusions for complex patterns that globs can't express:
# Exclude all cache and backup directories
ozip --app-xr '(cache|backup|\.tmp)/' archive.zip .
# Exclude log files only in wp-content
ozip --app-xr 'wp-content/.*\.log$' archive.zip .
Where zip differs
*`crosses/boundaries.** This can be convenient (dir1/excludes the whole subtree) but also dangerous —.log` in a path pattern may match more files than expected at deeper levels.
Case-sensitive. Matches exactly what you type. Requires separate patterns for *.log and *.LOG if both exist.
Beyond Exclude Patterns
Compression
| Feature | zip (Info-ZIP) | ozip |
|---|---|---|
| Parallel compression | No (single-threaded) | Yes (multi-core, configurable workers) |
| Compression levels | 0-9 (level 6 default) | 0-9 (level 6 default) |
| Smart store for compressed files | No (re-compresses .jpg, .mp4, .gz) | Yes (auto-detects and stores at level 0) |
| Streaming compression | Buffered but single-pass | Buffered I/O (256 KB) with parallel workers |
zip uses a single thread. ozip uses all available CPU cores by default with a parallel pipeline: feeder -> N workers -> sequential writer. Each worker compresses independently using CreateRaw with pre-compressed data. On multi-core servers, ozip is significantly faster on large directory trees.
ozip auto-detects already-compressed files (.jpg, .png, .mp4, .gz, .zip, .rar, .woff2, .pdf, .docx, etc.) and stores them at level 0 instead of wasting CPU. zip re-compresses everything regardless.
Archive Operations
| Feature | zip (Info-ZIP) | ozip |
|---|---|---|
Update existing archive (-u) |
Yes | Yes |
Freshen existing files (-f) |
Yes | Yes |
Test archive integrity (-T) |
Yes | Yes (CRC32 verification) |
| Password protection | Yes (ZipCrypto, weak) | Yes (via 7z: AES-256, .7z also encrypts filenames) |
| 7z format support | No | Yes (delegates to external 7z binary) |
| Archive comment | Yes (-z) |
Yes (--app-comment or OZIP_COMMENT) |
Junk paths (-j) |
Yes | Yes |
| Zip directory prefix | No | Yes (--app-zip-dir-prefix) |
| Stdout output | Yes (-) |
Yes (-) |
zip's built-in encryption uses ZipCrypto which is known to be weak and crackable. ozip delegates to 7z for AES-256 encryption. When using .7z format, filenames are also encrypted.
Reliability
| Feature | zip (Info-ZIP) | ozip |
|---|---|---|
| Atomic writes on update | No | Yes (temp file + fsync + rename) |
| Signal cleanup | No (leaves partial archive) | Yes (SIGTERM/SIGINT removes partial file) |
| Disk space check | No | Yes (--app-check-disk-space) |
| File locking | No | Yes (shared read locks with 30s timeout) |
fsync before reporting success |
No | Yes |
| Self-exclusion | No (can archive itself) | Yes (auto-detects output file in source tree) |
zip writes directly to the output. If the process is killed, you get a corrupted archive. ozip uses temp file + fsync + atomic rename for update/freshen operations, and removes partial archives on signal interrupt.
ozip automatically detects when the output archive is inside the source directory and excludes it. zip will happily include itself in the archive, causing corruption or infinite growth.
Automation
| Feature | zip (Info-ZIP) | ozip |
|---|---|---|
| Lifecycle hooks | No | Yes (pre/post/complete/error) |
| Email notifications | No | Yes (--app-notify-email) |
| Dry run | No | Yes (--app-dry-run) |
| Progress output | No | Yes (--app-progress) |
| Nice level | External (nice -n 10 zip ...) |
Built-in (--app-nice 10) |
Quiet mode (-q) |
Yes | Yes |
| Regex exclusions | No | Yes (--app-xr) |
| Environment variable config | ZIPOPT for default flags |
Full config: OZIP_LEVEL, OZIP_WORKERS, OZIP_COMMENT, etc. |
ozip hooks enable automated backup workflows:
ozip --app-pre-hook 'echo "Starting backup"' \
--app-complete-hook 'rsync $OZIP_ARCHIVE remote:backups/' \
--app-error-hook 'curl -X POST https://alerts.example.com' \
--app-notify-email admin@example.com \
--app-nice 10 \
backup.zip /var/www
Deployment
| Feature | zip (Info-ZIP) | ozip |
|---|---|---|
| Installation | Package manager (apt install zip) |
Single static binary, zero dependencies |
| Self-update | No | Yes (ozip cli update) |
| Cross-platform binary | Separate packages per OS | Linux + macOS from single build script |
| Thread safety on constrained servers | N/A (single-threaded) | Auto-caps workers based on ulimit -u |
| Last updated | 2008 (Zip 3.0) | Actively maintained |
Info-ZIP's last release was 2008. ozip is actively maintained with modern Go, parallel compression, and features designed for current server environments.
When to use zip
- Maximum compatibility — zip is pre-installed on most systems
- You need ZipCrypto encryption specifically (some legacy systems require it)
- Simple one-off compression where speed doesn't matter
When to use ozip
- Speed matters — parallel compression on multi-core servers
- Large web sites with thousands of files (.jpg, .mp4 auto-detected)
- Backup automation with hooks, email, error handling
- Shared hosting with low
ulimit -u— ozip auto-adjusts worker count - Stronger encryption (AES-256 via 7z)
- You want case-insensitive, predictable exclude patterns
- Single binary with self-update — no package manager needed
ozip vs tar: Full Comparison
Test Setup
tartest/
├── root.log
├── keep.txt
├── dir1/
│ ├── level1.log
│ └── dir2/
│ ├── level2.log
│ └── dir3/
│ ├── level3.log
│ └── level3.txt
├── logs/
│ └── app.log
└── deep/
└── nested/
└── path/
└── file.LOG
Exclude Pattern Behavior
| Behavior | tar (bsdtar) | ozip |
|---|---|---|
| Case sensitivity | Case-sensitive | Case-insensitive |
* crosses / |
No | No |
Simple pattern (*.log) matches all levels |
Yes | Yes (basename match) |
Path pattern (dir1/*.log) |
Matches only dir1/level1.log |
Matches only dir1/level1.log |
Trailing / = directory only |
Yes | Yes |
| Regex support | No | Yes (--app-xr) |
Test Results
Simple pattern: *.log
Both tar and ozip exclude .log files at every directory level.
tar: Excludes root.log, level1.log, level2.log, level3.log, app.log. Does NOT exclude file.LOG.
ozip: Excludes all of the above AND file.LOG (case-insensitive).
Path pattern: dir1/*.log
Both tar and ozip only match one level deep — * does not cross /.
tar: Excludes only dir1/level1.log. Does NOT exclude dir1/dir2/level2.log or deeper.
ozip: Same behavior. filepath.Match treats * as a single path segment.
Case sensitivity: *.LOG
tar: Only excludes file.LOG. Does NOT exclude root.log, level1.log, etc.
ozip: Excludes ALL .log and .LOG files. ozip lowercases both pattern and path before matching.
Directory-only: dir2/
tar: Excludes the entire dir2/ directory and its subtree.
ozip: Same behavior. Trailing / restricts the pattern to directories only.
Key Differences
Case-insensitive matching (ozip)
ozip always matches case-insensitively. This is intentional for web hosting environments where file naming is inconsistent (e.g. image.JPG, backup.Sql, FILE.LOG). A single -x '*.log' catches all variations.
tar requires --ignore-case (GNU tar only) or separate patterns for each case variation.
Regex support (ozip only)
ozip supports regex exclusions via --app-xr:
ozip --app-xr 'node_modules/' archive.zip .
ozip --app-xr '\.(log|tmp|bak)$' archive.zip .
tar has no built-in regex support for exclusions.
Suffix sliding (ozip)
For path patterns containing /, ozip tries the pattern against the full path and every suffix. This means */wp-content/*cache*/ matches public_html/wp-content/cache-fast/ even with extra leading segments.
tar matches the pattern against the member name as stored in the archive.
GNU tar vs bsdtar
GNU tar's default is --wildcards-match-slash for exclusions, meaning * can cross / boundaries. bsdtar (macOS) does NOT let * cross /. ozip behaves like bsdtar — * stays within a single path segment.
Beyond Exclude Patterns
Compression
| Feature | tar | ozip |
|---|---|---|
| Format | tar (uncompressed), tar.gz, tar.bz2, tar.xz | zip, 7z (via external 7z binary) |
| Parallel compression | No (single-threaded) | Yes (multi-core, configurable workers) |
| Compression levels | Depends on compressor (gzip -1 to -9) | 0-9 (level 6 default) |
| Smart store for compressed files | No | Yes (auto-detects .jpg, .zip, .mp4, etc. and stores at level 0) |
tar compresses with a single thread. ozip uses all available CPU cores by default, with a parallel pipeline: feeder goroutine -> N worker goroutines -> sequential writer. On a 4-core machine compressing a large site, ozip can be 3-4x faster.
ozip auto-detects already-compressed files (.jpg, .png, .mp4, .gz, .zip, etc.) and stores them at level 0 instead of wasting CPU trying to recompress them.
Archive Operations
| Feature | tar | ozip |
|---|---|---|
Update existing archive (-u) |
Yes | Yes |
Freshen existing files (-f) |
No | Yes (only replace older, no new files) |
Test archive integrity (-T) |
No built-in | Yes (CRC32 verification) |
| Password protection | No | Yes (via 7z backend) |
| Archive comment | No | Yes (--app-comment) |
Junk paths (-j) |
No | Yes (store files without directory structure) |
| Zip directory prefix | No | Yes (--app-zip-dir-prefix) |
Reliability
| Feature | tar | ozip |
|---|---|---|
| Atomic writes | No (partial file on interrupt) | Yes (temp file + rename) |
| Signal cleanup | No (leaves partial archive) | Yes (SIGTERM/SIGINT removes partial archive) |
| Disk space check | No | Yes (--app-check-disk-space) |
| File locking | No | Yes (shared read locks with timeout) |
fsync before reporting success |
No | Yes |
tar writes directly to the output file. If interrupted (Ctrl+C, kill), you get a partial corrupted archive. ozip writes to a temp file first, calls fsync, then atomically renames. On interrupt, the signal handler removes the partial temp file — you never get a half-written archive.
Automation
| Feature | tar | ozip |
|---|---|---|
| Lifecycle hooks | No | Yes (pre/post/complete/error) |
| Email notifications | No | Yes (--app-notify-email) |
| Dry run | No | Yes (--app-dry-run) |
| Progress output | No | Yes (--app-progress) |
| Nice level | External (nice -n 10 tar ...) |
Built-in (--app-nice 10) |
| Environment variable config | No | Yes (OZIP_LEVEL, OZIP_WORKERS, etc.) |
ozip hooks run shell commands at key lifecycle points and receive environment variables (archive path, file count, bytes written, elapsed time). This enables cron-based backup workflows:
ozip --app-pre-hook 'echo "Starting backup"' \
--app-complete-hook 'rsync $OZIP_ARCHIVE remote:backups/' \
--app-error-hook 'curl -X POST https://alerts.example.com' \
--app-notify-email admin@example.com \
backup.zip /var/www
Deployment
| Feature | tar | ozip |
|---|---|---|
| Installation | Pre-installed on all Unix systems | Single static binary, zero dependencies |
| Self-update | No | Yes (ozip cli update) |
| Cross-platform binary | N/A | Linux + macOS from single build script |
| Thread safety on constrained servers | N/A | Auto-caps workers based on ulimit -u |
When to use tar
- You need tar format specifically (e.g. Docker images, Linux packages)
- tar.xz for maximum compression ratio (xz compresses better than deflate)
- You need to preserve Unix permissions, ownership, and extended attributes exactly
- The archive will be extracted on Unix systems only
When to use ozip
- You need zip format (cross-platform, Windows compatibility)
- Speed matters — parallel compression on multi-core servers
- Backup automation with hooks, email notifications, and error handling
- Web hosting with low
ulimit -u— ozip auto-adjusts - You want a single binary with self-update, no package manager needed