sql server hub / backup guide

SQL Serverbackup guide

Backup jobs are not the same as recovery capability. A useful backup setup proves what can be restored, how far back, how fast, and by whom.

Use this guide to check backup history, log-chain continuity, restore history, backup files, retention, checksum, compression, encryption, and backup job alerting before a failure turns theory into pressure.

backup history

log chain

restore tests

Guide

Guide~10 min readUpdated 19 Apr 2026

Share

LinkedInXEmail
  1. 01SQL Server backup types and when to use them
  2. 02What a SQL Server backup plan has to answer
  3. 03Why RPO and RTO come before backup schedules
  4. 04How to read SQL Server backup history in msdb
  5. 05What full, differential, and log backups cover
  6. 06How to check the SQL Server log backup chain
  7. 07Why restore tests matter more than backup jobs
  8. 08Where SQL Server backup files and retention fail
  9. 09How checksum, compression, and encryption change backups
  10. 10What not to change in a SQL Server backup setup
  11. 11When to get a SQL Server backup review

SQL Server backup types and when to use them

A SQL Server backup is a restorable copy of database data, log records, or selected database files. Job success is only one part of it. The backup also has to support the restore path you would need during an incident.

Most recovery plans use a mix of full, differential, and transaction log backups. Copy-only and tail-log backups matter in specific situations, especially ad hoc work, migrations, and incidents. The scripts below use placeholder paths; adjust database names, backup locations, retention, encryption, and scheduling before running anything in production.

Full backup

A full backup is the normal baseline for a database restore. It contains enough database data, plus enough transaction log, to recover the database to a consistent point when restored.

Use it at the start of a backup chain, before major changes, and as the base for differential backups. It does not by itself give point-in-time recovery between full backups; that needs log backups in the right recovery model.

How to create a full database backup

Creates a full backup file with compression, checksum validation, and progress output.

BACKUP DATABASE [YourDatabase]
TO DISK = N'X:\SQLBackups\YourDatabase_full_20260527_2200.bak'
WITH
    COMPRESSION,
    CHECKSUM,
    STATS = 10;

Use a dedicated backup location with enough free space and tested restore access. CHECKSUM asks SQL Server to validate page checksums while backing up and write backup checksums. COMPRESSION usually reduces storage and I/O, but check CPU impact on busy systems. This is usually the first file restored in a full, differential, and log restore sequence.

Differential backup

A differential backup captures changes since the last full backup that acts as the differential base. It is useful when full backups are too large or too slow to run frequently.

Use it to shorten restore work between full backups. A common restore sequence is full backup, latest useful differential backup, then log backups after that point if the database uses full or bulk-logged recovery.

How to create a differential database backup

Creates a differential backup based on the current full-backup base.

BACKUP DATABASE [YourDatabase]
TO DISK = N'X:\SQLBackups\YourDatabase_diff_20260527_2300.bak'
WITH
    DIFFERENTIAL,
    COMPRESSION,
    CHECKSUM,
    STATS = 10;

A differential backup depends on a valid full backup base. Restore only the latest useful differential after the full backup, not every differential. Copy-only full backups do not reset the differential base. The restore plan still needs log backups if point-in-time recovery is required.

Transaction log backup

A transaction log backup captures log records for a database in full or bulk-logged recovery model. It is what usually makes point-in-time recovery possible.

Use log backups often enough to match the recovery point target and to prevent the transaction log from growing without reuse. The log backup chain must stay intact from the full backup through the target recovery point.

How to create a transaction log backup

Creates a transaction log backup for a database using full or bulk-logged recovery model.

-- Use this only for databases in FULL or BULK_LOGGED recovery model.
BACKUP LOG [YourDatabase]
TO DISK = N'X:\SQLBackups\YourDatabase_log_20260527_2315.trn'
WITH
    COMPRESSION,
    CHECKSUM,
    STATS = 10;

Log backups are not supported for the master database. The database must use full or bulk-logged recovery model. The cadence should match the agreed data-loss target, not a generic schedule. Broken, missing, or inaccessible log backup files can remove point-in-time recovery.

Copy-only backup

A copy-only backup is an ad hoc backup that is independent of the normal backup sequence. It is useful when someone needs a one-off backup without changing the regular plan.

Use a copy-only full backup before risky manual work, for a temporary migration copy, or for troubleshooting. Do not use it as a lazy replacement for the regular scheduled backup chain.

How to create copy-only backups

Creates one-off copy-only backups without disturbing the normal differential base or log archive point.

-- Ad hoc full backup that does not reset the differential base.
BACKUP DATABASE [YourDatabase]
TO DISK = N'X:\SQLBackups\YourDatabase_copyonly_20260527_1800.bak'
WITH
    COPY_ONLY,
    COMPRESSION,
    CHECKSUM,
    STATS = 10;

-- Less common: copy-only log backup.
BACKUP LOG [YourDatabase]
TO DISK = N'X:\SQLBackups\YourDatabase_log_copyonly_20260527_1815.trn'
WITH
    COPY_ONLY,
    COMPRESSION,
    CHECKSUM,
    STATS = 10;

A copy-only full backup does not reset the differential base. A copy-only log backup preserves the existing log archive point. COPY_ONLY has no effect when combined with DIFFERENTIAL. Record why the copy exists so it does not confuse later restore work.

Tail-log backup

A tail-log backup captures log records that have not yet been backed up. It is usually the last backup taken before restoring a database to the latest possible point.

Use it when the database is online and you are about to restore over it, or after a failure when the current log can still be captured. Do not run the online example casually: WITH NORECOVERY leaves the database in restoring state.

How to create a tail-log backup before restore

Captures the tail of the log before restore. Review the state of the database before using this in production.

-- Use before restore when you need the latest log records.
-- WITH NORECOVERY leaves the database in restoring state.
BACKUP LOG [YourDatabase]
TO DISK = N'X:\SQLBackups\YourDatabase_tail_20260527_2330.trn'
WITH
    NORECOVERY,
    CHECKSUM,
    STATS = 10;

-- If the database is damaged, review the situation before using:
-- WITH CONTINUE_AFTER_ERROR

Use this only when the recovery plan needs log records after the last regular log backup. WITH NORECOVERY is expected before a restore, but it makes the database unavailable. Damaged databases may need CONTINUE_AFTER_ERROR, and the backup can still fail if the log is not usable. A tail-log backup is unnecessary if the recovery point is already covered by earlier backups.

What a SQL Server backup plan has to answer

A backup strategy must prove more than job completion. It must show what data can be restored, which files are needed, whether the log chain is usable, who can access the backups, and whether restore timing fits the business need.

msdb backup and restore history is the starting point. It does not replace a restore drill, but it shows whether the recovery story is already missing a basic piece.

LayerWhat it answers
Backup historyWhich full, differential, and log backups completed.
Log chainWhether point-in-time recovery is still plausible.
Restore historyWhether restores or drills are actually happening.
Files and protectionWhere backups live, how they are protected, and whether SQL Server can use them.

Why RPO and RTO come before backup schedules

Recovery point objective decides how much data loss is acceptable. Recovery time objective decides how long the system can be unavailable. These two targets should shape backup type, frequency, storage, restore testing, and alerting.

Without those targets, backup schedules become habit. A nightly full backup may be fine for one database and completely inadequate for another.

QuestionWhy it matters
How much data loss is acceptable?This decides whether log backups and tighter cadence are required.
How fast must recovery be?This affects restore chain length, storage access, and drill quality.
Which databases matter most?Not every database needs the same backup posture.
Who accepts the recovery risk?The backup plan should match owned business expectations, not guesswork.

How to read SQL Server backup history in msdb

Start with the backup history SQL Server recorded in msdb. Check backup type, finish time, duration, size, checksums, copy-only status, and physical destination.

Job success alone is too indirect. Read the backup records because they tell you whether SQL Server actually produced backup sets.

Recent backup history

Reads recent full, differential, and log backups from msdb with size, checksum, copy-only flag, and device path.

SELECT TOP (100)
    bs.database_name,
    CASE bs.type
        WHEN 'D' THEN 'Full'
        WHEN 'I' THEN 'Differential'
        WHEN 'L' THEN 'Log'
        ELSE bs.type
    END AS backup_type,
    bs.backup_start_date,
    bs.backup_finish_date,
    DATEDIFF(second, bs.backup_start_date, bs.backup_finish_date) AS duration_seconds,
    CONVERT(decimal(18,2), bs.backup_size / 1024.0 / 1024.0) AS backup_size_mb,
    CONVERT(decimal(18,2), bs.compressed_backup_size / 1024.0 / 1024.0) AS compressed_size_mb,
    bs.is_copy_only,
    bs.has_backup_checksums,
    bmf.physical_device_name
FROM msdb.dbo.backupset AS bs
LEFT JOIN msdb.dbo.backupmediafamily AS bmf
    ON bmf.media_set_id = bs.media_set_id
WHERE bs.backup_start_date >= DATEADD(day, -14, SYSDATETIME())
ORDER BY bs.backup_start_date DESC;

backup_finish_date shows when SQL Server completed the backup set. backup_type separates full, differential, and log coverage. physical_device_name shows where SQL Server wrote the backup. has_backup_checksums and is_copy_only help identify backup quality and chain behavior.

What full, differential, and log backups cover

Full, differential, and log backups solve different recovery problems. The right mix depends on recovery model and recovery targets.

A database in full or bulk-logged recovery model usually needs regular log backups for point-in-time recovery and log management. A full backup alone is not the same protection.

Last backup per database by type

Shows the last full, differential, and log backup recorded for each database.

WITH LastBackups AS (
    SELECT
        bs.database_name,
        bs.type,
        MAX(bs.backup_finish_date) AS last_backup_finish_date
    FROM msdb.dbo.backupset AS bs
    WHERE bs.type IN ('D', 'I', 'L')
    GROUP BY bs.database_name, bs.type
)
SELECT
    d.name AS database_name,
    d.recovery_model_desc,
    MAX(CASE WHEN lb.type = 'D' THEN lb.last_backup_finish_date END) AS last_full_backup,
    MAX(CASE WHEN lb.type = 'I' THEN lb.last_backup_finish_date END) AS last_differential_backup,
    MAX(CASE WHEN lb.type = 'L' THEN lb.last_backup_finish_date END) AS last_log_backup
FROM sys.databases AS d
LEFT JOIN LastBackups AS lb
    ON lb.database_name = d.name
WHERE d.name <> N'tempdb'
GROUP BY d.name, d.recovery_model_desc
ORDER BY d.name;

last_full_backup is the baseline for restore planning. last_differential_backup can shorten restore work after the full backup. last_log_backup matters for full and bulk-logged databases. Compare the timestamps with the agreed RPO and RTO.

Missing or stale full backups

Finds databases with no recorded full backup or a full backup older than one day.

WITH LastFull AS (
    SELECT
        bs.database_name,
        MAX(bs.backup_finish_date) AS last_full_backup
    FROM msdb.dbo.backupset AS bs
    WHERE bs.type = 'D'
    GROUP BY bs.database_name
)
SELECT
    d.name AS database_name,
    d.recovery_model_desc,
    lf.last_full_backup,
    DATEDIFF(hour, lf.last_full_backup, SYSDATETIME()) AS hours_since_last_full
FROM sys.databases AS d
LEFT JOIN LastFull AS lf
    ON lf.database_name = d.name
WHERE d.name <> N'tempdb'
  AND (
      lf.last_full_backup IS NULL
      OR lf.last_full_backup < DATEADD(day, -1, SYSDATETIME())
  )
ORDER BY lf.last_full_backup;

A missing full backup is a serious restore-readiness gap. The one-day threshold is a sample; adjust it to the agreed policy. New or restored databases may need special interpretation. If this query returns production databases, check jobs and backup destinations next.

Missing recent log backups

Finds full or bulk-logged recovery databases without a log backup in the last hour.

WITH LastLog AS (
    SELECT
        bs.database_name,
        MAX(bs.backup_finish_date) AS last_log_backup
    FROM msdb.dbo.backupset AS bs
    WHERE bs.type = 'L'
    GROUP BY bs.database_name
)
SELECT
    d.name AS database_name,
    d.recovery_model_desc,
    ll.last_log_backup,
    DATEDIFF(minute, ll.last_log_backup, SYSDATETIME()) AS minutes_since_last_log
FROM sys.databases AS d
LEFT JOIN LastLog AS ll
    ON ll.database_name = d.name
WHERE d.name <> N'tempdb'
  AND d.recovery_model_desc IN (N'FULL', N'BULK_LOGGED')
  AND (
      ll.last_log_backup IS NULL
      OR ll.last_log_backup < DATEADD(hour, -1, SYSDATETIME())
  )
ORDER BY ll.last_log_backup;

minutes_since_last_log should match the recovery-point target. A NULL last_log_backup means no log backup was found in msdb history. The one-hour threshold is a sample, not a universal policy. If logs are stale, validate job status and the log chain before changing cadence.

How to check the SQL Server log backup chain

Log backups are useful only when the chain is intact and the required files can be restored in order. LSNs help review whether log backups line up with the expected recovery path.

This query is a review aid. A real restore test is still the stronger proof.

Recent log-chain review

Shows recent log backup LSNs with previous last LSN for continuity review.

SELECT TOP (100)
    bs.database_name,
    bs.backup_start_date,
    bs.backup_finish_date,
    bs.first_lsn,
    bs.last_lsn,
    bs.database_backup_lsn,
    bs.checkpoint_lsn,
    bs.is_copy_only,
    LAG(bs.last_lsn) OVER (
        PARTITION BY bs.database_name
        ORDER BY bs.backup_start_date
    ) AS previous_last_lsn
FROM msdb.dbo.backupset AS bs
WHERE bs.type = 'L'
  AND bs.backup_start_date >= DATEADD(day, -7, SYSDATETIME())
ORDER BY bs.database_name, bs.backup_start_date;

first_lsn and last_lsn show the covered log range. previous_last_lsn helps spot unexpected gaps or ordering issues. is_copy_only should be understood before interpreting unusual backups. If the chain looks wrong, do not promise point-in-time recovery until a restore test confirms it.

Why restore tests matter more than backup jobs

Restore history shows whether restores have happened on the instance. It may include real incidents, migrations, refreshes, and test restores, so read it with destination database names and timing.

RESTORE VERIFYONLY can catch some backup-file problems, especially with checksum, but it does not prove the application can run from the restored database or that recovery time is acceptable.

Recent restore history

Reads recent restore operations with source backup timing, restore type, recovery flag, and destination file paths.

SELECT TOP (100)
    rh.destination_database_name,
    rh.restore_date,
    rh.restore_type,
    rh.replace,
    rh.recovery,
    bs.database_name AS source_database_name,
    bs.backup_start_date,
    bs.backup_finish_date,
    CASE bs.type
        WHEN 'D' THEN 'Full'
        WHEN 'I' THEN 'Differential'
        WHEN 'L' THEN 'Log'
        ELSE bs.type
    END AS backup_type,
    rf.destination_phys_name
FROM msdb.dbo.restorehistory AS rh
LEFT JOIN msdb.dbo.backupset AS bs
    ON bs.backup_set_id = rh.backup_set_id
LEFT JOIN msdb.dbo.restorefile AS rf
    ON rf.restore_history_id = rh.restore_history_id
ORDER BY rh.restore_date DESC;

restore_date shows whether restore testing is recent enough to trust. destination_database_name can reveal test databases or real recovery events. restore_type and recovery help explain the restore sequence. No restore history is a reason to schedule a restore drill, not a reason to assume failure.

Restore validation example

Example command for a chosen backup file. Use a real path and confirm SQL Server can read it before running.

-- Choose the exact backup file first.
-- Confirm SQL Server can read the path and that CHECKSUM was used when possible.
RESTORE VERIFYONLY
FROM DISK = N'X:\SqlBackups\YourDatabase_full_20260520.bak'
WITH CHECKSUM;

VERIFYONLY checks whether the backup set is complete and readable enough for additional validation. WITH CHECKSUM adds checksum validation when the backup contains checksums. This does not replace restoring the database and checking application-level usefulness. Run a time-measured restore drill for recovery readiness.

Where SQL Server backup files and retention fail

Backup history is only useful if the files still exist, SQL Server can access them, and retention keeps enough restore points for the recovery target. Device paths also show whether backups are concentrated in one fragile location.

Retention should account for bad data discovered late, storage failure, accidental deletion, ransomware, offsite copies, and any legal or operational retention requirement.

QuestionWhy it matters
Can SQL Server read the backup path?A backup file that exists but cannot be read during restore is not ready.
Are usable copies stored separately?One credential or storage failure should not remove every restore option.
Does retention cover late discovery?Data corruption or bad writes may be noticed days after they happen.
Can the right file be found quickly?Incident recovery should not depend on manual file archaeology.

How checksum, compression, and encryption change backups

Backup options affect reliability, performance, storage, and restore access. Checksums help detect backup corruption. Compression changes size and CPU/I/O tradeoffs. Encryption protects the backup, but only if keys and certificates can also be restored.

Review these options together with file destination and access control. Backups are production data in portable form.

Backup files and backup options

Reads recent backup size, compression ratio, checksum flag, encryption metadata, and physical device path.

SELECT TOP (100)
    bs.database_name,
    CASE bs.type
        WHEN 'D' THEN 'Full'
        WHEN 'I' THEN 'Differential'
        WHEN 'L' THEN 'Log'
        ELSE bs.type
    END AS backup_type,
    bs.backup_finish_date,
    CONVERT(decimal(18,2), bs.backup_size / 1024.0 / 1024.0) AS backup_size_mb,
    CONVERT(decimal(18,2), bs.compressed_backup_size / 1024.0 / 1024.0) AS compressed_size_mb,
    CONVERT(decimal(18,2),
        bs.backup_size / NULLIF(bs.compressed_backup_size, 0)
    ) AS compression_ratio,
    bs.has_backup_checksums,
    bs.is_password_protected,
    bs.encryptor_type,
    bs.key_algorithm,
    bmf.physical_device_name
FROM msdb.dbo.backupset AS bs
LEFT JOIN msdb.dbo.backupmediafamily AS bmf
    ON bmf.media_set_id = bs.media_set_id
WHERE bs.backup_finish_date >= DATEADD(day, -30, SYSDATETIME())
ORDER BY bs.backup_finish_date DESC;

has_backup_checksums shows whether backup checksums were used. compression_ratio can reveal whether compression is active and effective. encryptor_type and key_algorithm show encrypted backup metadata when present. physical_device_name should be checked against expected storage and access policy.

Backup job failures and warnings

Reads recent SQL Agent history for backup jobs and failed or warning job steps.

SELECT TOP (100)
    j.name AS job_name,
    h.step_id,
    h.step_name,
    h.run_status,
    DATETIMEFROMPARTS(
        h.run_date / 10000,
        (h.run_date % 10000) / 100,
        h.run_date % 100,
        h.run_time / 10000,
        (h.run_time % 10000) / 100,
        h.run_time % 100,
        0
    ) AS run_start_time,
    ((h.run_duration / 10000) * 3600)
      + (((h.run_duration % 10000) / 100) * 60)
      + (h.run_duration % 100) AS run_duration_seconds,
    h.message
FROM msdb.dbo.sysjobhistory AS h
JOIN msdb.dbo.sysjobs AS j
    ON j.job_id = h.job_id
WHERE h.run_date >= CONVERT(int, CONVERT(char(8), DATEADD(day, -14, SYSDATETIME()), 112))
  AND (
      h.run_status <> 1
      OR j.name LIKE N'%backup%'
      OR h.step_name LIKE N'%backup%'
  )
ORDER BY run_start_time DESC;

run_status other than 1 needs review. message often contains the path, permission, space, or backup command error. Long duration can point to storage, compression, network, or workload timing problems. Job history should support backup history, not replace it.

What not to change in a SQL Server backup setup

Backup changes affect recovery promises. Make the recovery target clear before changing cadence, retention, encryption, cleanup, or storage paths.

1

Do not treat SQL Agent job success as proof that recovery works.

2

Do not change backup cadence before RPO and RTO are agreed.

3

Do not assume a full backup alone protects databases in full recovery model.

4

Do not break the log chain with ad hoc backups or unmanaged copy-only confusion.

5

Do not delete old backups until retention, restore targets, legal needs, and offsite copies are understood.

6

Do not enable encryption without confirming certificate and key backup plus restore access.

7

Do not rely on RESTORE VERIFYONLY as a substitute for a real restore test.

8

Do not store all usable backups where one credential, storage failure, or cleanup job can remove them.

When to get a SQL Server backup review

A recovery readiness review makes sense when backups appear to exist but the restore path is unclear, log-chain continuity is unverified, restore tests are missing, or backup storage and access rules are not trusted.

Send backup history, restore history, backup file locations, job output, error logs, RPO/RTO targets, retention rules, encryption/key details, and the last restore-test output.

Next step

If backups exist but the restore path is not proven, use the SQL Server recovery readiness page or request the review above.

Next useful reads: the SQL Server recovery guide for restore sequence and runbooks, the SQL Server monitoring guide for alerting, the SQL Server migration guide for planned moves, and the SQL Server health check guide for broader review.