powershelldba.de · Uwe Janke

Extended Events vs. the Old SQL Trace and Profiler

Why Profiler is deprecated, what Extended Events does differently under the hood, and a practical session for catching long-running queries with a fraction of the overhead.

SQL Trace and its GUI front-end, Profiler, have been deprecated since SQL Server 2012, and Microsoft has said plainly that a future version will remove them entirely. Most environments still have someone who opens Profiler out of habit anyway, it's familiar, it's visual, and Extended Events took years to get a comparably approachable UI. The habit is worth breaking: the underlying engine SQL Trace runs on is genuinely more expensive to run, not just older.

What's Actually Different

SQL Trace / Profiler Extended Events
Architecture Rowset-based, every event is packaged and delivered even to consumers that don't want it Lightweight event framework built into the engine itself; consumers subscribe only to what they need
Overhead Higher, especially with Profiler's live GUI attached and pulling events over the network in real time Designed for production use; asynchronous targets keep the hot path nearly untouched
Filtering Applied after the event is captured Predicates evaluated before the event is even fully collected, cheaper by design
Where output goes Trace file, trace table, or the Profiler UI's live grid Ring buffer (in-memory), event file (disk), or several other targets, selectable independently of collection
Future support Deprecated since SQL Server 2012, scheduled for eventual removal The actively developed path forward, including Azure SQL where Trace/Profiler mostly don't exist at all

A Practical Session: Catching Long-Running Queries

This is the Extended Events equivalent of the classic Profiler "Duration > threshold" trace, without the Profiler GUI's live-streaming overhead:

CREATE EVENT SESSION [LongRunningQueries] ON SERVER
ADD EVENT sqlserver.sql_statement_completed
(
    ACTION (sqlserver.sql_text, sqlserver.username, sqlserver.client_hostname)
    WHERE ([duration] > 5000000)   -- microseconds; 5,000,000 = 5 seconds
)
ADD TARGET package0.event_file
(
    SET filename = N'LongRunningQueries.xel',
        max_file_size = 50,
        max_rollover_files = 5
)
WITH (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
      MAX_DISPATCH_LATENCY = 30 SECONDS);
GO

ALTER EVENT SESSION [LongRunningQueries] ON SERVER STATE = START;
GO

-- Read it back later, no live GUI attached to the production server needed
SELECT
    event_data.value('(event/@timestamp)[1]', 'datetime2')      AS EventTime,
    event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS SqlText,
    event_data.value('(event/data[@name="duration"]/value)[1]', 'bigint') / 1000000.0 AS DurationSeconds
FROM sys.fn_xe_file_target_read_file('LongRunningQueries*.xel', NULL, NULL, NULL)
CROSS APPLY (SELECT CAST(event_data AS XML) AS event_data) AS x;

The predicate on duration is evaluated by the engine before the event is fully materialized, exactly the filtering-before-capture design that makes this cheaper than an equivalent Profiler trace watching every statement go by and filtering afterward.

Where the GUI still helps: SSMS's "Watch Live Data" window on an Extended Events session gives you the same live-grid experience Profiler users are used to, it's just attached to a session that was cheap to define and stop, rather than a Profiler trace that stays expensive for as long as it's running.

Common Gotchas

The Bottom Line

Extended Events isn't just a newer UI wrapped around the same collection mechanism, the underlying architecture is genuinely cheaper to run, which is exactly why it's the only path forward in Azure SQL and the reason SQL Trace has been on the deprecation list for over a decade. The syntax is more verbose than dragging columns into a Profiler template, but a session defined once in T-SQL is also easier to version, deploy consistently, and tear down cleanly than a GUI trace nobody remembers configuring.