ZSTD backup compression (SQL Server 2025)

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 for WITH 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 INIT alone 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.

Verified by MonsterInsights