Database Backups 101
Jeff Taylor
Principal Data Consultant
Database Consulting, LLC
PHOTOGRAPHY DURING THE SESSION
Feel free to capture the moment! Taking pictures of the presentation during the session is perfectly fine.
SELFIES WITH THE SPEAKER
We encourage interaction! If you'd like a selfie with the speaker, don't hesitate to ask — most are happy to oblige during appropriate breaks.
RECORDING AND LIVE STREAMING
Recording or live streaming the session, in part or in full, is strictly prohibited. Thank you for respecting our content and speakers.
Jeff Taylor
Principal Data Consultant
Database Consulting, LLC
Super Hero Suit
Database Backups 101
Jeff Taylor
Principal Data Consultant
Database Consulting, LLC
Questions
What is a database backup?
A copy of your data captured at a point in time, so you can put the database back the way it was.
…and it only counts if you can restore it.
Questions
Questions
Why should you back up your databases?
Because that's what you were hired to do.
Questions
Why should you restore your backups?
So you don't get fired!
A backup you've never tested is a hope, not a recovery plan.
Backup Types
What Backup Types Are There?
Recovery Models
What Backup Types are supported based on your Recovery Model
Recovery Model - Simple
Simple - Maximum Risk, No Point In Time Recovery
Recovery Model - Full/Bulk Logged
Full, Bulk Logged - Minimum Risk, Point in Time Recovery (RTO), Recovery Point (RPO)
Backup Type - Copy Only
Backup Type - Full
Backup Type - Transaction Logs
VLFs
Manage your VLFs (log fragmentation)
sys.dm_db_log_info (2016 SP2+/2017+) or DBCC LOGINFODBCC SHRINKFILE → regrow once via ALTER DATABASE … MODIFY FILE (SIZE = …); set autogrowth to a fixed chunk (e.g. 512 MB–1 GB)VLFs
Pedro Lopes's VLF script (TigerToolbox)
/* Pedro Lopes (Microsoft) - aka.ms/sqlinsights
TigerToolbox \ Fixing-VLFs \ Fix_VLFs.sql
Surveys every DB, then PRINTs the shrink + regrow fix.
Rule of thumb in the script: flag DBs with >= 50 VLFs. */
-- Quick check (SQL 2016 SP2+ / 2017+):
SELECT DB_NAME(d.database_id) AS [Database],
COUNT(li.vlf_sequence_number) AS VLFs
FROM sys.databases d
CROSS APPLY sys.dm_db_log_info(d.database_id) li
GROUP BY d.database_id
HAVING COUNT(li.vlf_sequence_number) >= 50
ORDER BY VLFs DESC;Full script outputs Actual vs Potential VLFs and the exact SHRINKFILE + MODIFY FILE commands
https://github.com/microsoft/tigertoolbox/blob/master/Fixing-VLFs/Fix_VLFs.sql
Backup Retention
@CleanupTime, e.g. 7–14 daysRetention & long-term backups
RPO vs RTO
RPO vs RTO — don't mix them up
Software
Backup-DbaDatabase: full/diff/log, compression, encryption, striping, Azure blob, built-in verifyBackup software options
Cons
Full Sample
USE [DBA];
GO
EXEC [dbo].[DatabaseBackup]
@Databases = 'ALL_DATABASES',
@Directory = 'C:\Files\DatabaseBackups',
@BackupType = 'FULL',
@Verify = 'Y',
@CheckSum = 'Y',
@CleanupMode = 'AFTER_BACKUP',
@Compress = 'Y',
@CopyOnly = 'N',
@ChangeBackupType = 'Y',
@BackupSoftware = NULL,
@NumberOfFiles = 4,
@Description = 'Full Backup',
@DirectoryStructure = '{BackupType}{DirectorySeparator}{DatabaseName}{DirectorySeparator}',
@FileName = '{DatabaseName}_{BackupType}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@CleanupTime = 336,
@LogToTable = 'Y';Differential Sample
USE [DBA];
GO
EXEC [dbo].[DatabaseBackup]
@Databases = 'ALL_DATABASES',
@Directory = 'C:\Files\DatabaseBackups',
@BackupType = 'DIFF',
@Verify = 'Y',
@CheckSum = 'Y',
@CleanupMode = 'AFTER_BACKUP',
@Compress = 'Y',
@CopyOnly = 'N',
@ChangeBackupType = 'N',
@BackupSoftware = NULL,
@NumberOfFiles = 4,
@Description = 'Diff Backup',
@DirectoryStructure = '{BackupType}{DirectorySeparator}{DatabaseName}{DirectorySeparator}',
@FileName = '{DatabaseName}_{BackupType}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@CleanupTime = 168,
@LogToTable = 'Y';Transaction Sample
USE [DBA];
GO
EXEC [dbo].[DatabaseBackup]
@Databases = 'ALL_DATABASES',
@Directory = 'C:\Files\DatabaseBackups',
@BackupType = 'LOG',
@Verify = 'Y',
@CheckSum = 'Y',
@CleanupMode = 'AFTER_BACKUP',
@Compress = 'Y',
@BackupSoftware = NULL,
@NumberOfFiles = 1,
@Description = 'Tran Backup',
@DirectoryStructure = '{BackupType}{DirectorySeparator}{DatabaseName}{DirectorySeparator}',
@FileName = '{DatabaseName}_{BackupType}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@CleanupTime = 7,
@LogToTable = 'Y';Performance
@BufferCount)@MaxTransferSize)@BlockSize)Compression
Compression
BACKUP DATABASE [StackOverflow]
TO
DISK = N'C:\DatabaseBackups\2025\StackOverflow2025.Compression.Medium.bak'
WITH
NOFORMAT,
NOINIT,
NAME = N'StackOverflow-Full Database Backup',
SKIP,
NOREWIND,
NOUNLOAD,
COMPRESSION (ALGORITHM = MS_XPRESS, LEVEL = MEDIUM),
STATS = 10,
CHECKSUM;
GOZSTD Benchmark
| Backup | Time | Size | Savings | Restore |
|---|---|---|---|---|
| No compression | 38:45 | 258 GB | — | 8:22 |
| MS_XPRESS · Low | 27:28 | 128 GB | 50.4% | 9:21 |
| MS_XPRESS · Medium | 25:13 | 121 GB | 53.1% | 7:00 |
| MS_XPRESS · High | 30:18 | 121 GB | 53.1% | 7:01 |
| ZSTD · Low | 16:15 | 129 GB | 50.0% | 5:22 |
| ZSTD · Medium | 28:28 | 106 GB | 58.9% | 6:26 |
| ZSTD · High | 1:06:00 | 100 GB | 61.2% | 6:30 |
444 GB Stack Overflow · 16-core i9, 64 GB RAM, NVMe · each run verified. Winner: ZSTD Low.
| Files | Time | Backup Type | Compression | Level | Restore |
|---|---|---|---|---|---|
| 2 | 9:34 | Full | ZSTD | Low | |
| 4 | 9:20 | Full | ZSTD | Low | |
| 8 | 9:36 | Full | ZSTD | Low | |
| 12 | 8:42 | Full | ZSTD | Low | |
| 16 | 8:38 | Full | ZSTD | Low | 4:07 |
444 GB Stack Overflow · ZSTD Low on every run · 16-core i9, 64 GB RAM, NVMe. Winner: 16 files at 8:38.
File Count
| Metric | 1 File | 16 Files | Faster |
|---|---|---|---|
| Backup | 16:15 | 8:38 | 47% |
| Restore | 5:22 | 4:07 | 23% |
Same 444 GB DB, ZSTD Low. Striping to 16 files nearly halved backup (16:15 to 8:38) and cut restore (5:22 to 4:07).
Backup + Restore
ZSTD Takeaways
Restore
WITH NORECOVERY; only the final step is WITH RECOVERYSTOPAT = '2025-11-16 14:32:00' to recover to an exact secondSTANDBY leaves the DB readable between log restoresA backup is only as good as your last successful restore.
Test Restores
RESTORE VERIFYONLY only checks the media is readable — it does not prove the DB restoresRestore-DbaDatabase / Ola Hallengren DatabaseRestore)Always
Always
https://learn.microsoft.com/en-us/sql/relational-databases/backup-restore/backup-overview-sql-server
https://learn.microsoft.com/en-us/sql/t-sql/statements/backup-transact-sql
https://www.jefftaylor.io/post/sql-server-2025-backups-new-zstd-compression
https://www.jefftaylor.io/post/sql-server-2025-backup-compression-and-restore-review
https://github.com/microsoft/tigertoolbox/tree/master/Fixing-VLFs
Let's talk backups — and restores.
Thank you for attending my session today.
If you have any additional questions, please don't hesitate to reach out.