Deadlocks by Database
Overview
The Deadlocks by Database report answers three questions at once: which databases on this instance deadlock, when they do it, and what they keep doing it over.
One lane per database, one tick per deadlock, on a shared time axis. That shape matters because the timing is the finding:
Forty deadlocks in one bad hour and forty spread evenly across a month came out as the same row on the old report, and they are not the same problem. One is an incident with a date on it; the other is a design fault in an access pattern.
The object each database keeps deadlocking over is brought up onto this page rather than being buried in a drill-down, so the most common answer is visible without leaving the report.
What this fixes
The report this replaces counted the wrong thing. Its query fanned out over every process in the deadlock graph that was not the victim, so a three-process deadlock scored two, an ordinary one scored one, and a deadlock spanning two databases was counted once in each. The column header said Deadlocks and the number underneath it was blocker process instances.
Counts now come straight off the resolved database name, so an event is counted once.
Where to find it
| Route | How |
|---|---|
| Server tree | Right-click the server → Instance Level Reports → Deadlocks by DB |
| Server Overview page | Click the report link |
| Report arrows | Sits after Last DBCC CheckDB Known Good |

The page title reads Deadlocks by DB for <server name>. The help button opens https://databasehealth.com/server-overview/instance-level-reports/deadlocks-by-database/.
Requirements
-
SQL Server 2016 or newer. The monitor service collects deadlocks from the
system_healthextended events session, which earlier versions cannot be read from this way. On an older instance the report says so and stops rather than drawing a fake row:Deadlock history needs SQL Server 2016 or newer. The monitor service collects deadlocks from the system_health extended events session, which earlier versions cannot be read from this way.
-
Historic collection must be configured. This report reads the
DBHealthHistoryrepository, not the live instance. Without collection there is nothing to show.
The three views
Timeline (the default)
One lane per database, one tick per deadlock, on a shared time axis. Clusters are incidents; even spacing is a chronic access-pattern problem.

Ranking
Magnitude bars with a caret marking where the previous window sat – the view that answers is this getting worse? rather than how much is there?
Clock
A 24-hour dial with one self-scaled ring per database. This is the view that identifies a scheduled job: deadlocks clustered at the same time every day form an arc rather than being spread around the dial.
Each ring is scaled to itself, so a database with three deadlocks and one with three hundred both show their shape.
The statuses
| Status | Meaning |
|---|---|
| Active (red) | Something deadlocked here within the last day. The row to look at first. |
| Chronic (amber) | Deadlocking on most days of the window rather than in one burst. |
| Normal | Deadlocks in the window, neither live nor chronic. |
| Dormant (grey) | Nothing for long enough that it is history rather than a problem. |
| Unattributed (grey, hatched) | Deadlocks whose graph named no database. |
Unattributed deadlocks get their own hatched row rather than grouping under a nameless wedge. On the old report they drew as an unlabelled pie slice above a blank grid row.
The header lines
The summary line:
214 deadlocks across 6 databases in the last 30 days · 71% of them in OrderEntry · 2 still deadlocking today
The concentration clause appears only when one database holds 40% or more of the total – it is the number that decides where the afternoon goes.
The subtitle line:
one tick per deadlock recorded by the monitor service · history kept from Jun 8, 2026 · longest clean run 46 days in Billing
The notice band says what the page had to leave out. An empty band is the page telling you the picture is complete, which is worth as much as the picture:
- History only goes back to Jun 8 – a longer window will not reach further.
- The chart is drawn from the most recent 5,000 of 21,400 deadlocks, so the earliest days are thinner than they were; the grid counts are complete.
- Process counts and object names were not read – 21,400 deadlock graphs is more XML than this page will make you wait for. Try a shorter window.
That second one matters: when it appears, the chart is a sample and the grid is not. Trust the numbers, not the tick density.
Reading the grid

| Column | What it is |
|---|---|
| Database | Database name, or the unattributed row. |
| Deadlocks | Count in the window. One per event, not per process. Drawn with an in-cell bar. |
| Days Affected | How many distinct days had at least one. This is what separates an incident from a pattern. |
| First In Window | The earliest deadlock inside the window. |
| Last Deadlock | The most recent one. |
| Busiest Hour | The hour of day with the most deadlocks. |
| Most Involved Object | The object this database keeps deadlocking over. |
| vs Previous Window | Change against the preceding window of the same length. |
Days Affected next to Deadlocks is the pair to read together. Forty deadlocks over two days is an incident; forty over twenty-eight days is a design problem.
The toolbar
| Group | Buttons |
|---|---|
| Window | 7 days · 30 days (default) · 60 days |
| View | Timeline · Ranking · Clock |
Refresh |
There is no auto-refresh. The service collects deadlocks on a fifteen-minute timer and the window is measured in weeks, so a sixty-second heartbeat would re-scan the history table – and re-read its XML – to redraw the same picture.
Right-click actions
| Item | What it does |
|---|---|
| Open Deadlock History for <database> | The per-deadlock drill-down, with the graphs. |
| Copy Database Name to Clipboard | Just the name. |
| Copy Deadlock Detail Query to Clipboard | A read-only query against the history table for that database. |
| Copy Chart to Clipboard | (chart only) |
How to read the report
- Read the notice band. If the chart is a sample, read the grid rather than the tick density.
- Read the summary line. Concentration tells you whether this is one database’s problem or the instance’s.
- Look for Active rows. Red means it happened within the last day.
- Compare Deadlocks against Days Affected. A burst and a pattern need different responses.
- Switch to Clock. An arc rather than a scatter means a scheduled job is involved, which is usually the easiest thing to move.
- Switch to Ranking. The caret shows whether the last window was better or worse.
- Read Most Involved Object. Repeated deadlocks over the same object are usually fixed with an index or an access-order change rather than with retry logic.
- Drill in for the graphs themselves.
Common patterns
One database, ticks in a tight cluster, everything else quiet. An incident. Find what else happened at that time – a deployment, a batch run, a maintenance window.
Even ticks across the whole window, Chronic status. An access-pattern problem. Two code paths take the same objects in different orders. Retry logic hides this; it does not fix it.
Clock view shows a clean arc at the same hour daily. A scheduled job overlapping user work. The cheapest fix is usually to move the schedule.
A hatched unattributed row with a real count. Deadlocks whose graph named no database. Worth opening the drill-down – they are often cross-database or involve tempdb.
Ranking carets all pointing up. Getting worse across the board. Look for something instance-wide – a version change, a statistics problem, or growth pushing plans over a threshold.
A long clean run named in the subtitle. Somebody fixed something. Worth knowing what, and whether it applies elsewhere.
Where the data comes from
The DBHealthHistory repository, populated by the Database Health Monitor collection process from the system_health extended events session on a fifteen-minute timer.
This is a historic report. It does not query the monitored instance for deadlocks, so it works when the instance is unavailable, and it shows nothing at all if collection has never been configured.
The window buttons cannot reach further back than the retention of the history table, which is why the notice band tells you the oldest retained date.
Settings
| Setting | Default | Values |
|---|---|---|
DeadlocksByDatabaseWindowDays |
30 |
7, 30, 60 |
DeadlocksByDatabaseView |
timeline |
timeline, ranking, clock |
Messages you may see
Version too old:
Deadlock history needs SQL Server 2016 or newer.
Nothing recorded:
No deadlocks recorded on this instance in the last 30 days.
Timed out:
The deadlock history lookup did not finish in time. A long window over a large history table can take a while; try 7 days, or the Refresh button.
Related reports
| Report | Why you would go there |
|---|---|
| Deadlock History | The individual deadlocks and their graphs. |
| Blocking by Hour by Day | Blocking that has not yet become a deadlock. |
| Sessions | What is blocking right now. |
| Missing Indexes | A missing index widens the row range a statement locks, which is a common deadlock cause. |
Frequently asked questions
Why does my deadlock count differ from the old report? Because the old one counted blocker process instances, not deadlocks. A three-process deadlock scored two and a cross-database deadlock was counted twice. This counts events.
Why is there an unattributed row? Some deadlock graphs name no database. Rather than grouping them under a blank label, they get their own hatched row.
Why can I not go back further than 60 days? That is the longest window button, and the history table’s retention may be shorter still. The notice band tells you the oldest date actually held.
Why does the chart show fewer deadlocks than the grid? On a very large window the chart is drawn from a sample of the most recent events, because reading every deadlock graph’s XML would make you wait. The notice band says so when it happens, and the grid counts are always complete.
Why is there no auto-refresh? Collection runs every fifteen minutes and the window is weeks long. A sixty-second refresh would re-read the history table to draw the same picture.
What do I do about a chronic deadlock? Look at Most Involved Object first. Repeated deadlocks over one object are usually an access-order problem between two code paths, or a missing index forcing a scan that locks more rows than it needs to.