SQL Server 2025 Series : OPTIMIZED_SP_EXECUTESQL — End the Compilation Storm Killing SQL Performance

When dozens of threads hit the same query simultaneously on a cold cache, SQL Server compiles the same plan over and over — burning CPU, wasting resources, and degrading throughput right when your system is most vulnerable. This is a compilation storm, and SQL Server 2025 has a one-line fix for it.


What is a compilation storm?

Every query needs a compiled execution plan before SQL Server can run it. Plans are cached — but when the cache is cold (after a restart, failover, or deployment) and many threads fire the same query at once, each thread independently compiles the same plan:

Comparison of SQL execution performance with and without optimized sp_executeSQL, illustrating cache misses and hits across multiple threads.

One thread pays the compilation cost. Everyone else waits a millisecond and reuses for free.

Step-by-step demo script

The full script below walks through all 10 steps end to end. Run each section in order.

1) Create the database and tables

Sets up jbexecute with Customers, Products, Orders, and a CompilationMetrics table to store before/after results.

USE master;
GO
IF EXISTS (SELECT 1 FROM sys.databases WHERE name = N'jbexecute')
BEGIN
ALTER DATABASE jbexecute SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE jbexecute;
END
GO
CREATE DATABASE jbexecute;
GO
ALTER DATABASE jbexecute SET RECOVERY SIMPLE;
GO
USE jbexecute;
GO
CREATE TABLE dbo.Customers
(
CustomerID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
FirstName NVARCHAR(50) NOT NULL,
LastName NVARCHAR(50) NOT NULL,
Email NVARCHAR(100) NOT NULL,
Region NVARCHAR(30) NOT NULL,
CreatedDate DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
);
GO
CREATE TABLE dbo.Products
(
ProductID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
ProductName NVARCHAR(100) NOT NULL,
Category NVARCHAR(50) NOT NULL,
UnitPrice DECIMAL(10,2) NOT NULL,
StockQty INT NOT NULL DEFAULT 1000
);
GO
CREATE TABLE dbo.Orders
(
OrderID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
CustomerID INT NOT NULL REFERENCES dbo.Customers(CustomerID),
ProductID INT NOT NULL REFERENCES dbo.Products(ProductID),
Quantity INT NOT NULL,
TotalAmount DECIMAL(12,2) NOT NULL,
OrderStatus NVARCHAR(20) NOT NULL DEFAULT N'Pending',
OrderDate DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
);
GO
CREATE TABLE dbo.CompilationMetrics
(
MetricID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
Phase NVARCHAR(10) NOT NULL,
CapturedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
CompileEvents INT NOT NULL,
TotalDurationNs BIGINT NOT NULL,
TotalDurationMs AS (TotalDurationNs / 1000000.),
Notes NVARCHAR(500) NULL
);

2) Seed sample Data

200 customers, 50 products, 5,000 orders.

;WITH cte AS
(
SELECT TOP 200 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM sys.all_columns a CROSS JOIN sys.all_columns b
)
INSERT INTO dbo.Customers (FirstName, LastName, Email, Region)
SELECT
N'FirstName' + CAST(n AS NVARCHAR(10)),
N'LastName' + CAST(n AS NVARCHAR(10)),
N'user' + CAST(n AS NVARCHAR(10)) + N'@shop.com',
CHOOSE((n % 5) + 1, N'North', N'South', N'East', N'West', N'Central')
FROM cte;
GO
;WITH cte AS
(
SELECT TOP 50 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM sys.all_columns
)
INSERT INTO dbo.Products (ProductName, Category, UnitPrice, StockQty)
SELECT
N'Product_' + CAST(n AS NVARCHAR(10)),
CHOOSE((n % 6) + 1,
N'Electronics', N'Clothing', N'Books',
N'Home & Garden', N'Sports', N'Toys'),
CAST((n * 7.99) AS DECIMAL(10,2)),
500 + (n * 10)
FROM cte;
GO
;WITH cte AS
(
SELECT TOP 5000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM sys.all_columns a CROSS JOIN sys.all_columns b
)
INSERT INTO dbo.Orders (CustomerID, ProductID, Quantity, TotalAmount, OrderStatus)
SELECT
(n % 200) + 1,
(n % 50) + 1,
(n % 10) + 1,
CAST(((n % 50) + 1) * 7.99 * ((n % 10) + 1) AS DECIMAL(12,2)),
CHOOSE((n % 4) + 1, N'Pending', N'Shipped', N'Delivered', N'Cancelled')
FROM cte;

3) Set feature OFF and create Extended Events session

Captures query_post_compilation_showplan (compilation time) and sql_batch_completed (execution) to an .xel file.

-- Disable for BEFORE test
ALTER DATABASE SCOPED CONFIGURATION
SET ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY = OFF;
ALTER DATABASE SCOPED CONFIGURATION
SET OPTIMIZED_SP_EXECUTESQL = OFF;
GO
USE master;
GO
IF EXISTS (SELECT 1 FROM sys.server_event_sessions WHERE name = N'Demo_CompilationStorm')
DROP EVENT SESSION Demo_CompilationStorm ON SERVER;
GO
CREATE EVENT SESSION [Demo_CompilationStorm] ON SERVER
ADD EVENT sqlserver.query_post_compilation_showplan
(
ACTION
(
sqlserver.sql_text,
sqlserver.database_name,
sqlserver.client_app_name,
sqlserver.session_id
)
WHERE ([sqlserver].[database_name] = N'jbexecute')
),
ADD EVENT sqlserver.sql_batch_completed
(
ACTION (sqlserver.sql_text, sqlserver.database_name)
WHERE ([sqlserver].[database_name] = N'jbexecute' AND [duration] > 0)
)
ADD TARGET package0.event_file
(
SET filename = N'C:\temp\JBExecute\Demo_CompilationStorm.xel',
max_file_size = 1024,
max_rollover_files = 5
)
WITH (MAX_DISPATCH_LATENCY = 5 SECONDS, TRACK_CAUSALITY = ON);
GO
ALTER EVENT SESSION [Demo_CompilationStorm] ON SERVER STATE = START;
GO

4) Create the workload file (workload.sql)

Save this as a .sql file. It is what ostress will fire on every thread and iteration.

DECLARE @custID INT;
DECLARE @prodID INT;
DECLARE @qty INT;
DECLARE @amount DECIMAL(12,2);
DECLARE @status NVARCHAR(20);
DECLARE @sql NVARCHAR(MAX);
DECLARE @params NVARCHAR(MAX);
SET @sql = N'
INSERT INTO dbo.Orders (CustomerID, ProductID, Quantity, TotalAmount, OrderStatus)
VALUES (@cid, @pid, @qty, @amt, @stat);
UPDATE dbo.Products
SET StockQty = StockQty - @qty
WHERE ProductID = @pid AND StockQty >= @qty;
SELECT o.OrderID,
c.FirstName + '' '' + c.LastName AS CustomerName,
p.ProductName,
o.Quantity,
o.TotalAmount,
o.OrderStatus
FROM dbo.Orders o
JOIN dbo.Customers c ON c.CustomerID = o.CustomerID
JOIN dbo.Products p ON p.ProductID = o.ProductID
WHERE o.CustomerID = @cid
ORDER BY o.OrderDate DESC;
';
SET @params = N'@cid INT, @pid INT, @qty INT, @amt DECIMAL(12,2), @stat NVARCHAR(20)';
SET @custID = (ABS(CHECKSUM(NEWID())) % 200) + 1;
SET @prodID = (ABS(CHECKSUM(NEWID())) % 50) + 1;
SET @qty = (ABS(CHECKSUM(NEWID())) % 5) + 1;
SET @amount = CAST(@prodID * 7.99 * @qty AS DECIMAL(12,2));
SET @status = N'Pending';
EXEC sp_executesql @sql, @params,
@cid = @custID, @pid = @prodID, @qty = @qty,
@amt = @amount, @stat = @status;

5) Run BEFORE workload with ostress

Clear the plan cache first. Demo servers only. Then fire ostress.

-- Clear plan cache (DEMO SERVER ONLY)
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
-- Run from command prompt:
-- ostress -S"YOUR_SERVER" -E -i"C:\temp\JBExecute\workload.sql" -n100 -r5 -q -djbexecute
ALTER EVENT SESSION [Demo_CompilationStorm] ON SERVER STATE = STOP;
GO
WAITFOR DELAY '00:00:05';

6) Capture and save BEFORE metrics

Reads the .xel file and stores compile event count and total compile duration into CompilationMetrics.

USE jbexecute;
GO
;WITH events AS
(
SELECT
n.value('(@name)[1]', 'NVARCHAR(100)') AS event_name,
n.value('(data[@name="duration"]/value)[1]', 'BIGINT') AS duration_ns,
n.value('(action[@name="database_name"]/value)[1]', 'NVARCHAR(128)') AS db_name
FROM
(
SELECT CAST(event_data AS XML) AS event_xml
FROM sys.fn_xe_file_target_read_file(
N'C:\temp\JBExecute\Demo_CompilationStorm*.xel',
NULL, NULL, NULL)
) src
CROSS APPLY src.event_xml.nodes('//event') AS t(n)
)
SELECT
'BEFORE (No Feature)' AS Phase,
event_name,
COUNT(*) AS CompileEventCount,
SUM(duration_ns) AS TotalDuration_ns,
SUM(duration_ns) / 1000000. AS TotalDuration_ms,
AVG(duration_ns) AS AvgDuration_ns,
MAX(duration_ns) AS MaxDuration_ns
FROM events
WHERE event_name = 'query_post_compilation_showplan'
AND db_name = 'jbexecute'
GROUP BY event_name;
-- Save to metrics table
;WITH events AS
(
SELECT
n.value('(@name)[1]', 'NVARCHAR(100)') AS event_name,
n.value('(data[@name="duration"]/value)[1]', 'BIGINT') AS duration_ns
FROM
(
SELECT CAST(event_data AS XML) AS event_xml
FROM sys.fn_xe_file_target_read_file(
N'C:\temp\JBExecute\Demo_CompilationStorm*.xel',
NULL, NULL, NULL)
) src
CROSS APPLY src.event_xml.nodes('//event') AS t(n)
)
INSERT INTO dbo.CompilationMetrics (Phase, CompileEvents, TotalDurationNs, Notes)
SELECT
'BEFORE',
COUNT(*),
ISNULL(SUM(duration_ns), 0),
'SQL Server without Optimized sp_executesql — concurrent compilation storm'
FROM events
WHERE event_name = 'query_post_compilation_showplan';

7) Enable OPTIMIZED_SP_EXECUTESQL

One line. No downtime. No application changes.

USE jbexecute;
GO
ALTER DATABASE SCOPED CONFIGURATION
SET ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY = ON;
ALTER DATABASE SCOPED CONFIGURATION
SET OPTIMIZED_SP_EXECUTESQL = ON;
GO
-- Verify
SELECT name, value, value_for_secondary
FROM sys.database_scoped_configurations
WHERE name IN (N'OPTIMIZED_SP_EXECUTESQL',
N'ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY');
GO
-- Fresh start for AFTER test
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
ALTER EVENT SESSION [Demo_CompilationStorm] ON SERVER STATE = STOP;
GO
ALTER EVENT SESSION [Demo_CompilationStorm] ON SERVER STATE = START;
GO
-- Run ostress again with identical parameters, then:
ALTER EVENT SESSION [Demo_CompilationStorm] ON SERVER STATE = STOP;
GO
WAITFOR DELAY '00:00:05';

8) Capture and save AFTER metrics

USE jbexecute;
GO
;WITH events AS
(
SELECT
n.value('(@name)[1]', 'NVARCHAR(100)') AS event_name,
n.value('(data[@name="duration"]/value)[1]', 'BIGINT') AS duration_ns,
n.value('(action[@name="database_name"]/value)[1]', 'NVARCHAR(128)') AS db_name
FROM
(
SELECT CAST(event_data AS XML) AS event_xml
FROM sys.fn_xe_file_target_read_file(
N'C:\Temp\JBExecute\Demo_CompilationStorm*.xel',
NULL, NULL, NULL)
) src
CROSS APPLY src.event_xml.nodes('//event') AS t(n)
)
SELECT
'AFTER (Optimized sp_executesql ON)' AS Phase,
event_name,
COUNT(*) AS CompileEventCount,
SUM(duration_ns) AS TotalDuration_ns,
SUM(duration_ns) / 1000000. AS TotalDuration_ms,
AVG(duration_ns) AS AvgDuration_ns,
MAX(duration_ns) AS MaxDuration_ns
FROM events
WHERE event_name = 'query_post_compilation_showplan'
AND db_name = 'jbexecute'
GROUP BY event_name;
;WITH events AS
(
SELECT
n.value('(@name)[1]', 'NVARCHAR(100)') AS event_name,
n.value('(data[@name="duration"]/value)[1]', 'BIGINT') AS duration_ns
FROM
(
SELECT CAST(event_data AS XML) AS event_xml
FROM sys.fn_xe_file_target_read_file(
N'C:\Temp\JBExecute\Demo_CompilationStorm*.xel',
NULL, NULL, NULL)
) src
CROSS APPLY src.event_xml.nodes('//event') AS t(n)
)
INSERT INTO dbo.CompilationMetrics (Phase, CompileEvents, TotalDurationNs, Notes)
SELECT
'AFTER',
COUNT(*),
ISNULL(SUM(duration_ns), 0),
'SQL Server 2025 with OPTIMIZED_SP_EXECUTESQL = ON — serialized compilation'
FROM events
WHERE event_name = 'query_post_compilation_showplan';

9) Compare before vs after

Shows compile event count, total compile duration, and average compile time per event — all with % reduction.

-- Phase detail
SELECT
Phase, CapturedAt, CompileEvents,
TotalDurationNs, TotalDurationMs AS TotalDuration_ms,
CASE WHEN Phase = 'BEFORE'
THEN 'Baseline — N compilations per burst'
ELSE 'Optimized — 1 compilation per unique batch'
END AS Description, Notes
FROM dbo.CompilationMetrics
ORDER BY MetricID;
-- Reduction summary
SELECT
b.CompileEvents AS BEFORE_CompileEvents,
a.CompileEvents AS AFTER_CompileEvents,
b.CompileEvents - a.CompileEvents AS Compilations_Saved,
CAST(100.0 * (b.CompileEvents - a.CompileEvents)
/ NULLIF(b.CompileEvents, 0) AS DECIMAL(5,1)) AS Compilations_Pct_Reduction,
b.TotalDurationMs AS BEFORE_TotalCompileDuration_ms,
a.TotalDurationMs AS AFTER_TotalCompileDuration_ms,
b.TotalDurationMs - a.TotalDurationMs AS CompileDuration_ms_Saved,
CAST(100.0 * (b.TotalDurationMs - a.TotalDurationMs)
/ NULLIF(b.TotalDurationMs, 0) AS DECIMAL(5,1)) AS CompileDuration_Pct_Reduction,
CASE WHEN b.CompileEvents > 0
THEN b.TotalDurationNs / b.CompileEvents END AS BEFORE_AvgCompile_ns,
CASE WHEN a.CompileEvents > 0
THEN a.TotalDurationNs / a.CompileEvents END AS AFTER_AvgCompile_ns,
CASE WHEN b.CompileEvents > 0 AND a.CompileEvents > 0
THEN (b.TotalDurationNs / b.CompileEvents)
- (a.TotalDurationNs / a.CompileEvents) END AS AvgCompile_ns_Saved,
CAST(
100.0 *
( (b.TotalDurationNs / NULLIF(b.CompileEvents, 0))
- (a.TotalDurationNs / NULLIF(a.CompileEvents, 0)) )
/ NULLIF(b.TotalDurationNs / NULLIF(b.CompileEvents, 0), 0)
AS DECIMAL(5,1)) AS AvgCompile_Pct_Reduction
FROM
(SELECT TOP 1 * FROM dbo.CompilationMetrics WHERE Phase = 'BEFORE' ORDER BY MetricID DESC) b
CROSS JOIN
(SELECT TOP 1 * FROM dbo.CompilationMetrics WHERE Phase = 'AFTER' ORDER BY MetricID DESC) a;
GO

10) Cleanup

ALTER EVENT SESSION [Demo_CompilationStorm] ON SERVER STATE = STOP;
DROP EVENT SESSION [Demo_CompilationStorm] ON SERVER;
GO
USE master;
ALTER DATABASE jbexecute SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE jbexecute;
GO

Things to know before enabling in production

  • SQL Server 2025 only. OPTIMIZED_SP_EXECUTESQL is not available on 2022 or earlier. ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY is available from 2022 onwards.
  • Waiting threads add latency. Non-first threads wait for the compiling thread. Negligible in most cases — but test carefully if you have genuinely slow-compiling queries.
  • sp_executesql only. Ad-hoc SQL, stored procedures, and batches where the SQL text varies between calls are not covered by this feature.
  • Does not fix bad plans. This serializes compilation — it does not improve plan quality. Use Query Store for plan stability alongside this.
  • Test before production. Validate with Extended Events as shown in this demo. Every workload is different.

Watch the Full Demo

I’ve recorded a complete walkthrough of this setup on my YouTube channel JBSWiki. If you’re a visual learner, go check it out!

👉 Watch here: https://www.youtube.com/watch?v=3BF9wn_IXWQ


Thank You,

Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided “AS IS” with no warranties, and confers no rights.

SQL Server 2025 Series : ABORT_QUERY_EXECUTION Explained with Full Live Demo!

If you manage production workloads, you’ve probably seen situations where one problematic query keeps hurting performance for everyone else. In SQL Server 2025, Microsoft highlights ABORT_QUERY_EXECUTION as a Query Store hint that lets administrators block the future execution of a known problematic query without changing application code. That makes it a practical DBA-focused safeguard when you need control quickly.

In this blog, I’ll explain what ABORT_QUERY_EXECUTION is, why it matters, the prerequisites, and then walk through a full live demo using only the code shown below. I’ll also show how to verify whether the hint is configured and how to list blocked queries recorded in Query Store. Microsoft’s product and demo references position this feature as part of the broader query-processing and administrative control improvements in SQL Server 2025.


What is ABORT_QUERY_EXECUTION?

ABORT_QUERY_EXECUTION is a query hint showcased for SQL Server 2025 that can be applied through Query Store hints to block future executions of a specific query. The available Microsoft and demo references consistently describe it as an administrative control for stopping a known bad query from continuing to impact workload stability, while avoiding application code changes.

One important clarification: this feature is described as preventing future executions of the targeted query. The references do not describe it as a general-purpose replacement for terminating a query that is already running.


Why was this introduced?

The purpose is simple and practical. Sometimes a query is known to be expensive or disruptive, but the application team cannot change the code immediately. In that situation, Query Store hints already provide a way to influence query behavior without redeploying code, and ABORT_QUERY_EXECUTION extends that model by allowing the query to be blocked from future execution.

Available references describe this feature as a way to stop rogue or problematic queries from harming the rest of the workload and to improve reliability during incidents. That is what makes it a useful operational safety valve for DBAs.


Prerequisites

Before testing this feature, the main prerequisite is that Query Store must be enabled, because ABORT_QUERY_EXECUTION works through Query Store hints. This requirement is explicitly reflected in the demo references and supporting guidance.

For this walkthrough, you need:

  • SQL Server 2025
  • A database where your demo query can be captured in Query Store
  • Query Store enabled for that database

Full Demo Code

-- ABORT_QUERY_EXECUTION
CREATE OR ALTER procedure [dbo].[usp_procdisplaydata] @Col2 int
as
begin
SELECT top (150000)
[Col1],
[Col2],
[Col3],
[Col4],
[Col5]
FROM dbo.Table1
WHERE [Col2] = @Col2
ORDER BY [Col3];
END
EXEC [dbo].[usp_procdisplaydata] @Col2=2
SELECT TOP (20)
q.query_id,
qt.query_sql_text,
rs.count_executions,
rs.avg_duration,
rs.last_duration
FROM sys.query_store_query_text qt
JOIN sys.query_store_query q
ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan p
ON q.query_id = p.query_id
JOIN sys.query_store_runtime_stats rs
ON p.plan_id = rs.plan_id
WHERE qt.query_sql_text LIKE N'%SELECT top (150000)%'
ORDER BY rs.last_execution_time DESC;
GO -- Query Id 38
EXEC sys.sp_query_store_set_hints
@query_id = 38,
@query_hints = N'OPTION (USE HINT (''ABORT_QUERY_EXECUTION''))';
GO
SELECT *
FROM sys.query_store_query_hints
WHERE query_id = 38;
GO
EXEC [dbo].[usp_procdisplaydata] @Col2=2
EXEC sys.sp_query_store_clear_hints
@query_id = 38;
GO
-- Blocked queries in Query Store
SELECT qsh.query_id,
q.query_hash,
qt.query_sql_text
FROM sys.query_store_query_hints AS qsh
INNER JOIN sys.query_store_query AS q
ON qsh.query_id = q.query_id
INNER JOIN sys.query_store_query_text AS qt
ON q.query_text_id = qt.query_text_id
WHERE UPPER(qsh.query_hint_text) LIKE '%ABORT[_]QUERY[_]EXECUTION%'

Step-by-Step Demo Explanation

1) Create the procedure and execute it once

The first part of the demo creates a stored procedure and executes it so the query text is captured in Query Store. That step is important because the feature is implemented through Query Store hints, and you need the corresponding query_id before you can apply the hint.

2) Find the query in Query Store

The next query searches the Query Store catalog views using the text pattern SELECT top (150000) to identify the relevant query and retrieve its query_id. In this demo script, the query id used is 38. The overall approach aligns with the feature’s dependency on Query Store metadata.

3) Apply ABORT_QUERY_EXECUTION

The core configuration step is:

EXEC sys.sp_query_store_set_hints
@query_id = 38,
@query_hints = N'OPTION (USE HINT (''ABORT_QUERY_EXECUTION''))';

This applies the ABORT_QUERY_EXECUTION query hint through Query Store for the specific query. The available demo and product materials explicitly show this feature being implemented through sp_query_store_set_hints.

4) Verify that the hint is configured

The following verification query checks the Query Store catalog view for the configured hint:

SELECT *
FROM sys.query_store_query_hints
WHERE query_id = 38;

This is a practical way to verify whether ABORT_QUERY_EXECUTION has been configured for that query in your database.

5) Execute the procedure again

After the hint is applied, the procedure is executed again so you can validate the configured behavior. Based on the available references, ABORT_QUERY_EXECUTION is designed to block future executions of the targeted query once the hint is in place.

6) Clear the hint

Once testing is complete, the hint is removed using:

EXEC sys.sp_query_store_clear_hints
@query_id = 38;

This completes the full end-to-end lifecycle: identify the query, apply the hint, verify it, test it, and clear it when it is no longer needed.

7) List blocked queries in Query Store

The final query in the script looks for entries in sys.query_store_query_hints where the configured hint text contains ABORT_QUERY_EXECUTION. This is useful when you want to audit or review queries that have been configured with this hint

SELECT qsh.query_id,
q.query_hash,
qt.query_sql_text
FROM sys.query_store_query_hints AS qsh
INNER JOIN sys.query_store_query AS q
ON qsh.query_id = q.query_id
INNER JOIN sys.query_store_query_text AS qt
ON q.query_text_id = qt.query_text_id
WHERE UPPER(qsh.query_hint_text) LIKE '%ABORT[_]QUERY[_]EXECUTION%'

ABORT_QUERY_EXECUTION is one of the more practical DBA-oriented capabilities highlighted in SQL Server 2025. It gives administrators a way to block the future execution of a known problematic query using Query Store hints, without changing application code. That makes it especially valuable when immediate workload protection is needed.


Watch the Full Demo

I’ve recorded a complete walkthrough of this setup on my YouTube channel JBSWiki. If you’re a visual learner, go check it out!

👉 Watch here: https://www.youtube.com/watch?v=SjjC18u-jjM


Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided “AS IS” with no warranties, and confers no rights.