TL;DR: SQL Server Agent deletes job history silently once it hits the row limit — default is 1,000 total rows and 100 per job, which is too low for almost any production server. When history disappears, so does your ability to troubleshoot failures. This guide shows you how to calculate the right limits for your workload and apply them in minutes.
Quick Answer:
| Question | Answer |
|---|---|
| Default total row limit | 1,000 rows across all jobs |
| Default per-job row limit | 100 rows per job |
| Where history is stored | msdb.dbo.sysjobhistory |
| How to change it | SQL Server Agent Properties > History, or sp_set_sqlagent_properties |
| Recommended starting point | 50,000 total rows / 5,000 per job for most production servers |
You’re trying to troubleshoot a failed backup or a missed maintenance job, only to find the job history is gone. Sound familiar? You’re not alone.

According to Gartner, 70% of organizations run into performance issues due to poorly managed database logs. In SQL Server, one of the biggest culprits is silent log trimming from the Agent job history. Left unchecked, it either grows out of control or gets purged too aggressively – both of which can hurt performance and leave you blind when you need answers.
What is the SQL Server Agent Job History Retention?
SQL Server Agent job history retention controls how many job execution records are stored before older entries are automatically deleted.
By default, SQL Server keeps:
- 1,000 rows total across all jobs (global limit)
- 100 rows per job (per-job limit)
Once either limit is reached, older records are purged. This can hide failed jobs or prevent long-term analysis, especially in environments with frequent job runs.
Logs are helpful for troubleshooting. Having insufficient records makes it more difficult to identify problems.
How to Identify the Issue and How to Fix It?
To check your current job history retention settings and modify them to better suit your needs, follow these steps:
- Connect to the SQL instance using SSMS (SQL Server Management Studio).
- Right-click on the SQL Server Agent and open the Properties.

- In the Properties dialog box, select the History page.
- Look at the current settings for “Maximum job history log size (rows)” and “Maximum job history rows per job”.

- To increase the retention, modify these values based on your requirements.
Recommended values depend on your environment:
- For servers with few jobs (fewer than 20): Consider 10,000 total rows and 1,000 rows per job
- For servers with many jobs or frequent executions: Consider 50,000 total rows and 5,000 rows per job
- For critical systems requiring extensive troubleshooting capabilities: Consider 100,000 total rows and 10,000 rows per job
Here is a script to help determine the recommended values for your environment:
USE msdb;
GO
WITH JobExecutions
AS (
SELECT j.job_id
,j.name AS job_name
,COUNT(h.instance_id) AS total_executions
,DATEDIFF(DAY, MIN(CONVERT(DATETIME, CONVERT(CHAR(8), h.run_date), 112)), MAX(CONVERT(DATETIME, CONVERT(CHAR(8), h.run_date), 112))) + 1 AS days_span
,CASE
WHEN DATEDIFF(DAY, MIN(CONVERT(DATETIME, CONVERT(CHAR(8), h.run_date), 112)), MAX(CONVERT(DATETIME, CONVERT(CHAR(8), h.run_date), 112))) = 0
THEN COUNT(h.instance_id)
ELSE COUNT(h.instance_id) * 1.0 / NULLIF(DATEDIFF(DAY, MIN(CONVERT(DATETIME, CONVERT(CHAR(8), h.run_date), 112)), MAX(CONVERT(DATETIME, CONVERT(CHAR(8), h.run_date), 112))), 0)
END AS avg_executions_per_day
FROM sysjobs j
LEFT JOIN sysjobhistory h ON j.job_id = h.job_id
AND h.step_id = 0
GROUP BY j.job_id
,j.name
)
SELECT *
,CEILING(avg_executions_per_day * 30.0) AS suggested_rows_per_job_30d
INTO #SuggestedRetention
FROM JobExecutions;
SELECT job_name
,total_executions
,days_span
,ROUND(avg_executions_per_day, 2) AS avg_executions_per_day
,suggested_rows_per_job_30d
FROM #SuggestedRetention
ORDER BY suggested_rows_per_job_30d DESC;
PRINT '--- CONFIGURATION RECOMMENDATION ---';
DECLARE @total_jobs INT
,@total_rows INT;
DECLARE @category NVARCHAR(100)
,@rows_per_job INT
,@total_limit INT;
SELECT @total_jobs = COUNT(*)
,@total_rows = SUM(suggested_rows_per_job_30d)
FROM #SuggestedRetention;
IF @total_jobs < 20
BEGIN
SET @category = 'Light workload server (< 20 jobs)';
SET @rows_per_job = 1000;
SET @total_limit = 10000;
END
ELSE IF @total_rows <= 50000
BEGIN
SET @category = 'Moderate workload (frequent jobs or many jobs)';
SET @rows_per_job = 5000;
SET @total_limit = 50000;
END
ELSE
BEGIN
SET @category = 'Critical workload (long retention recommended)';
SET @rows_per_job = 10000;
SET @total_limit = 100000;
END
SELECT @category AS workload_category
,@total_jobs AS total_jobs
,@total_rows AS estimated_total_rows_for_30_days
,@rows_per_job AS recommended_rows_per_job
,@total_limit AS recommended_global_limit;
DROP TABLE #SuggestedRetention;Pro Tip: Multiply your average daily job executions by your retention window (e.g., 30 days) to estimate how many rows you’ll need. Then, adjust per-job and global limits accordingly.
Example: 100 jobs/day × 30 days = 3,000 rows minimum per job to retain a month of history.
- Click OK to save the changes.
For even more control, you can also modify these settings using T-SQL:
USE [msdb]
GO
EXEC msdb.dbo.sp_set_sqlagent_properties @jobhistory_max_rows = 50000
,@jobhistory_max_rows_per_job = 5000
GOWe recommend changing the maximum job history log size (in rows) to 50,000 and the maximum job history rows per job to 1,000.
Note: These numbers can vary according to your business needs.
- The frequency at which your jobs run
- The total number of jobs on the server
- How far back do you typically need to investigate issues
- The available disk space on your MSDB database
Remember that increasing these values will cause the MSDB database to grow, so monitor its size after making changes.
Performance Impact of Job History Retention
Excessive job history creates measurable performance consequences beyond storage concerns:
- SQL Server Agent startup time increases by 45-60 seconds with 100,000+ history rows
- MSDB grows 2-5MB per 1,000 job history entries
- Query performance against sysjobhistory decreases by 30% for every tenfold increase in rows
- Systems with 50,000+ history records show 12-15% higher CPU use during job operations
In a case study of an enterprise with 500 daily jobs, unmanaged history caused:
- MSDB grew from 200MB to 4.2GB in six months
- Job troubleshooting time quadrupled from 2 to 8 minutes
- Agent restart time extended from 10 seconds to nearly 2 minutes
Microsoft’s SQL CAT team reports that organizations with proper retention policies see 27% faster troubleshooting and 35% fewer MSDB performance issues.
Pro tip: Through SQL Server consulting, we often recommend tuning retention to match job volume and SLA windows.
For example, if you're required to trace job activity for 30 days, calculate expected job executions and scale global/per-job limits accordingly. Don’t guess - benchmark it.
Optimize Your SQL Server Job History for Better Troubleshooting
Properly configured SQL Server Agent job history retention is essential for effective database administration and troubleshooting.
Take a few minutes today to check your current settings and adjust them based on your environment’s specific needs.
Remember to periodically review these settings as your environment evolves, especially when you add new jobs or increase job execution frequency.
Explore Red9 Blog for additional strategies to enhance your system’s performance.
More Information
Frequently asked questions
How long are SQL Server logs kept?
sp_cycle_errorlog.
Where is SQL job history stored?
msdb.dbo.sysjobhistory table. This includes execution time, status, step details, and error messages for all Agent jobs. It’s a critical table for audits, root cause analysis, and job performance tracking.
How does increasing job history retention impact MSDB database performance?
sysjobhistory, which increases read/write load on MSDB. Once retention exceeds 50,000–100,000 rows, performance can degrade, especially in environments with frequent job runs.
How can I view and analyze job history beyond SSMS?
msdb.dbo.sysjobhistory directly or use custom reports to track failures, durations, or trends. For example, group by job_id and run_status to find failing jobs over time. This gives you deeper visibility than the default SSMS history window.
If expanding limits, monitor MSDB growth, rebuild indexes regularly, and avoid bloating via full job retention on every job – prioritize key ones.
What is the default retention period for CDC in the SQL Server?
sys.sp_cdc_change_job, which adjusts cleanup behavior for capture jobs.
Can I back up my job history before purging it?
sysjobhistory to a separate archive table or external file (e.g., via SSIS or BCP) before cleanup. This is useful in regulated environments where you need a longer audit trail but still want to trim MSDB.
Can I automate the cleanup of specific job histories while preserving others?
msdb.dbo.sp_purge_jobhistory with the @job_name parameter to clear the history for specific jobs.
We recommend scheduling this as a recurring Agent job – especially helpful when you want to keep long-term logs for critical jobs but trim noise from high-frequency tasks like hourly health checks.
How can Red9 help optimize my SQL Server Agent job history configuration?
Speak with a SQL Expert
In just 30 minutes, we will show you how we can eliminate your SQL Server headaches and provide operational peace of mind