In one line: SQL Server 2025’s ZSTD backup compression at LEVEL = LOW made a smaller backup than the old MS_XPRESS algorithm. But a backup file that already holds an MS_XPRESS backup rejects a ZSTD one WITH INIT.
Run it yourself: the scripts that reproduce everything on this page are in sqlserver-demos/zstd-backup-compression on GitHub.
What you’ll see
- Smaller backups. 168 MB of data: MS_XPRESS 17.3 MB, ZSTD LOW 13.8 MB, MEDIUM 11.5 MB, HIGH 10.9 MB.
- A backup job that fails the first night after switching to ZSTD, with error 3098: “‘ZSTD’ was requested after the media was formatted with an incompatible structure”, followed by 3013.
- Almost no saving on encrypted or already-compressed data, whichever algorithm: 87% to 88% of the original size.
Why it happens
ZSTD is a newer compression algorithm that gets more out of the same data. LEVEL trades CPU for size: HIGH was 21% smaller than LOW. What that costs in time depends on the hardware. On the emulated test container HIGH took three times as long as LOW; on native x64 CI runners the two took the same time.
A backup file starts with a media header, and the header records the compression algorithm. WITH INIT overwrites the backups in the file but keeps the header, so a file formatted for MS_XPRESS can’t take a ZSTD backup until it’s reformatted.
Random bytes, which is what encrypted data looks like, have no patterns to compress.
What to do
- Use
COMPRESSION (ALGORITHM = ZSTD, LEVEL = LOW)as the default replacement forWITH COMPRESSION. Try MEDIUM where backup size or network time matters more than CPU. - Add
WITH FORMAT, or use new file names, when switching a job that writes to a fixed file. - Make sure the restore target is a version that supports ZSTD before using it for backups you might restore elsewhere.
What doesn’t help
- HIGH on encrypted or already-compressed databases. It spends CPU for nothing.
WITH INITalone when the file was written with the other algorithm.
Check your server
-- Recent backups and the algorithm each used (compression_algorithm is
-- NULL for uncompressed backups), and the instance defaults.
SELECT TOP (20)
bs.database_name, bs.backup_finish_date,
bs.compression_algorithm,
CAST(bs.backup_size / 1048576.0 AS decimal(12,1)) AS size_mb,
CAST(bs.compressed_backup_size / 1048576.0 AS decimal(12,1)) AS compressed_mb
FROM msdb.dbo.backupset AS bs
ORDER BY bs.backup_finish_date DESC;
SELECT name, value_in_use
FROM sys.configurations
WHERE name LIKE 'backup compression%';
See it happen
The zstd-backup-compression demo backs up a 170 MB database with no compression, MS_XPRESS and the three ZSTD levels, three times each. It repeats the test on random data, reproduces the WITH INIT failure, and restores a ZSTD backup. On 2022 and earlier it reports SKIPPED.
Related: backup and restore · data compression · why is my transaction log full?
Measured on SQL Server 2025 RTM-CU9-GDR (17.0.5015.4), Linux container. Your numbers will differ; the behaviour shouldn’t.
Part of SQL Server Demos: short explanations of SQL Server problems, each backed by a runnable demo in MarlonRibunal/sqlserver-demos on GitHub. Written with the help of AI; every number comes from running the demo on SQL Server. How this was made.
