powershelldba.de
REF: PSDB-DLC-2026 SCOPE: SQL Server 2008 R2+ STATUS: In production since 2018
Module

Every deadlock, captured automatically — no trace to configure.

DeadlockCollector is a free T-SQL solution, not a PowerShell module or an application: two scripts set up a dedicated database and an hourly SQL Agent job that reads deadlock graphs straight out of the system_health Extended Events session every SQL Server already runs. No custom trace, no separate service — just a persisted, deduplicated history you can query in SSMS.

Why this exists

The ring buffer forgets. This doesn't.

Every deadlock already lands in system_health's ring buffer — but it ages out, nobody's watching, and there's no history to spot a pattern in.

Without itWith DeadlockCollector
Deadlocks age out of the ring buffer before anyone looksCollected hourly into a dedicated, persistent database
Capturing deadlocks means configuring a custom XE sessionReads the system_health session every instance already runs
No record of which hour or which database gets hit hardestViews aggregating by day, by hour, and by database
Re-running a collector re-imports the same deadlocksDeduplicated by hash, safe to run repeatedly
An AG secondary generates false alarms from a read-only copySkips collection entirely on a read-only replica
Requirements

What it needs.

SQL Server2008 R2 or later — anywhere the system_health session exists; explicitly tested on 2016, 2019, and 2022
SQL Server AgentRunning, to execute the hourly collection job
Rights to installsysadmin — the setup script creates a database, objects, and a server-level Agent job
OptionalSQL Server 2012 or later, only if importing a saved .xel file instead of reading the live ring buffer
DependenciesNone — pure T-SQL. No PowerShell, no dbatools, no installer
How it works

Piggybacks on the session that's already running.

  1. No custom XE sessionIt reads the ring buffer target of the built-in system_health Extended Events session — the one every SQL Server instance runs by default, not something you have to set up.
  2. Hourly collection jobA SQL Agent job calls dbo.Collect once an hour.
  3. AG-awaredbo.Collect checks whether the database is read/write and skips the run entirely if it's a read-only Availability Group secondary.
  4. Full deadlock detail parseddbo.InsertDeadLock extracts the victim list, process list, and resource list from the deadlock XML, plus per-process detail — database, SPID, login, host, application name, wait resource, lock mode, isolation level, and input buffer — for both processes involved.
  5. Query text and plan, where still cachedEach process's sqlhandle is used to pull the actual SQL text and query plan from the plan cache, if it hasn't been evicted yet.
  6. Deduplicated automaticallyA hash over the timestamp and graph XML prevents the same deadlock being inserted twice if the job runs again before the ring buffer rotates it out.

dbo.InsertDeadLock also accepts an @XESource parameter pointing at a saved .xel file instead of the live ring buffer, for importing a capture from elsewhere — that path requires SQL Server 2012 or later.

Database objects

What gets installed.

ObjectPurpose
dbo.DeadLockThe central table — one row per deadlock, with per-process detail and the full graph as XML
dbo.CollectEntry point called by the SQL Agent job — checks read/write status, then calls InsertDeadLock
dbo.InsertDeadLockParses the deadlock XML and writes new, deduplicated rows to dbo.DeadLock
dbo.deleteDeadLockRetention cleanup — removes rows older than a given date
dbo.sel_xml_ListScalar function extracting the victim/process/resource lists from a deadlock XML graph
dbo.vwvDeadlockInfosBase view over every captured deadlock
dbo.vwvDeadLockByDayDeadlock and victim counts per day
dbo.vwvDeadLockByDayHourDeadlocks per day and hour — for spotting a recurring time-of-day hotspot
dbo.vwvDeadLockByDayAndDatabaseDeadlocks per day and database
dbo.vwvDeadLockCombinationBySQLTextThe most frequent SQL-text combinations — for spotting a repeat offender query pattern
Viewing a deadlock

No separate viewer — SSMS already renders it.

There's no custom GUI. Query dbo.vwvDeadlockInfos or the underlying table, and click the graph XML value in the SSMS results grid — SSMS renders the native deadlock diagram, exactly as if you'd captured it by hand from an XE session.

Installation

Two scripts, run once.

-- Step 1: create the database and objects
:r SetUpDeadlockCollectorDb.sql

-- Step 2: create the hourly SQL Agent job
:r SetUpDeadlockCollectorJob.sql

Run both in SSMS or via SQLCMD as a sysadmin. The first script creates the database, tables, views, and stored procedures; the second creates the SQL Agent job that calls dbo.Collect hourly. dbo.deleteDeadLock is there for retention — run it on a schedule of your own choosing to trim rows past a given date.

Comparison

DeadlockCollector, or Get-sqmDeadlockReport?

sqmSQLTool has its own deadlock command, and the two solve related but different problems — use one, the other, or both.

DeadlockCollectorGet-sqmDeadlockReport
TypeT-SQL, installed oncePowerShell cmdlet (sqmSQLTool, requires dbatools)
TriggerScheduled hourly SQL Agent jobOn-demand — run whenever you need a report
StorageDedicated database, deduplicatedNone — reads the ring buffer live each time
Time windowContinuous, since the day it was installedConfigurable, defaults to the last 24 hours
AG-awarenessSkips read-only secondaries automaticallyNot AG-aware
OutputSQL views, SSMS-native deadlock diagramsPowerShell objects, or .xdl files for SSMS

DeadlockCollector gives you a persistent baseline you never have to remember to run; Get-sqmDeadlockReport is the tool for a quick on-demand pull in the middle of an incident.

Licensing

Free to use.

DeadlockCollector is released under the MIT License — no trial, no activation, same as the rest of the free tools in this suite.

Next steps

Pair it with an on-demand check, or browse the full reference.