{"id":47916,"date":"2026-10-19T15:05:13","date_gmt":"2026-10-19T13:05:13","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=47916"},"modified":"2026-10-19T15:05:15","modified_gmt":"2026-10-19T13:05:15","slug":"sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/","title":{"rendered":"SQL Server 2025: is optimized locking really working? Ask the Extended Events"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Optimized locking<\/strong> is probably the SQL Server 2025 feature I was the most curious about as a DBA. On paper, lock escalation should almost disappear. Let\u2019s check it with a simple test: 200,000 rows, an update on the first 10,000, and a transaction we leave open.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nBEGIN TRANSACTION;\nUPDATE dbo.orders SET status = 1 WHERE id &lt;= 10000;\n\nSELECT resource_type, request_mode, COUNT(*) AS locks\nFROM sys.dm_tran_locks\nWHERE request_session_id = @@SPID\nGROUP BY resource_type, request_mode;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Without optimized locking:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"346\" height=\"104\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png\" alt=\"\" class=\"wp-image-47927\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png 346w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70-300x90.png 300w\" sizes=\"auto, (max-width: 346px) 100vw, 346px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">With optimized locking:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"351\" height=\"125\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-66.png\" alt=\"\" class=\"wp-image-47928\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-66.png 351w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-66-300x107.png 300w\" sizes=\"auto, (max-width: 351px) 100vw, 351px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">In the first case, SQL Server escalated the row locks to an <code>X<\/code> lock on the whole table. In the second, there is no escalation anymore, only one <code>X<\/code> lock on the transaction ID (<code>XACT<\/code>), next to the intent lock (IX) on the table (the <code>IS<\/code> lock in both results is on the small function I used to run this query).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is nice in a demo, but on a real server nobody is looking at <code>sys.dm_tran_locks<\/code> at the right moment. I wanted to know how a DBA can check what optimized locking does once it is enabled. SQL Server 2025 has a few <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/extended-events\/quick-start-extended-events-in-sql-server?view=sql-server-ver17\" data-type=\"link\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/extended-events\/quick-start-extended-events-in-sql-server?view=sql-server-ver17\">Extended Events<\/a> for that, and I found some of their fields easy to misread and one of them reports LAQ as enabled on a database where it never ran once.<\/p>\n\n\n\n<h2 id=\"h-a-quick-reminder\" class=\"wp-block-heading\">A quick reminder<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"470\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-1.gif\" alt=\"\" class=\"wp-image-47929\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\" data-type=\"link\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\">Optimized locking<\/a> is made of two parts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With TID locking, SQL Server still takes row and page locks when it modifies data, but it releases each of them as soon as the row is modified. Until the commit, instead of thousands of row and page locks, the transaction keeps one <code>X<\/code> lock on its transaction ID, plus the intent lock (IX) on the table.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lock after qualification (LAQ) evaluates the <code>WHERE<\/code> clause on the <strong>last committed version of each row<\/strong>, without locking it, and only locks the rows that qualify. LAQ needs read committed snapshot isolation (RCSI). Optimized locking itself only needs accelerated database recovery (ADR).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My colleague <a href=\"https:\/\/www.linkedin.com\/in\/roger-schoenmann\/?isSelfProfile=false\" data-type=\"link\" data-id=\"https:\/\/www.linkedin.com\/in\/roger-schoenmann\/?isSelfProfile=false\">Roger Sch\u00f6nmann<\/a> already showed both parts with demos on <a href=\"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-optimized-locking\/\" data-type=\"link\" data-id=\"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-optimized-locking\/\">this blog<\/a>, so I will stay on the monitoring side here.<\/p>\n\n\n\n<h2 id=\"h-the-events\" class=\"wp-block-heading\">The events<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here are the events to know:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Event<\/th><th>When it fires<\/th><th>What it gives<\/th><\/tr><\/thead><tbody><tr><td><code>lock_escalation<\/code><\/td><td>at each escalation<\/td><td>the table, the cause, the number of locks converted<\/td><\/tr><tr><td><code>locking_stats<\/code><\/td><td>every few minutes for each database, <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\" data-type=\"link\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\">even if optimized locking is disabled<\/a><\/td><td>counters for the interval: escalations, LAQ attempts, reasons why LAQ was skipped, and whether TID locking and LAQ are enabled<\/td><\/tr><tr><td><code>locking_stats2<\/code><\/td><td>at the same time as <code>locking_stats<\/code> (observed)<\/td><td>skip index locks and LAQ heuristics counters (SQL Server and Azure SQL Managed Instance only)<\/td><\/tr><tr><td><code>lock_after_qual_stmt_abort<\/code><\/td><td>at each restart<\/td><td>a statement that LAQ had to restart, with its plan hash<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft Learn presents these events, but the 70 or so fields of <code>locking_stats<\/code> and <code>locking_stats2<\/code> are not listed there. You can still get a short description of each one from the engine:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nSELECT object_name AS event_name, name AS field, description\nFROM sys.dm_xe_object_columns\nWHERE object_name IN (N&#039;locking_stats&#039;, N&#039;locking_stats2&#039;, N&#039;lock_after_qual_stmt_abort&#039;)\n  AND column_type = N&#039;data&#039;\nORDER BY event_name, field;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here is the session I used:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nCREATE EVENT SESSION optimized_locking ON SERVER\nADD EVENT sqlserver.lock_escalation\n    (ACTION (sqlserver.sql_text) WHERE (sqlserver.database_name = N&#039;&lt;DB_NAME&gt;&#039;)),\nADD EVENT sqlserver.lock_after_qual_stmt_abort\n    (ACTION (sqlserver.sql_text) WHERE (sqlserver.database_name = N&#039;&lt;DB_NAME&gt;&#039;)),\nADD EVENT sqlserver.locking_stats,\nADD EVENT sqlserver.locking_stats2\nADD TARGET package0.event_file (SET filename = N&#039;optimized_locking.xel&#039;, max_file_size = 50)\nWITH (MAX_DISPATCH_LATENCY = 5 SECONDS);\n\nALTER EVENT SESSION optimized_locking ON SERVER STATE = START;\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Most counters of <code>locking_stats<\/code> are at zero, so reading the raw XML gets tiring quickly. I used this query, which returns one row per non-zero field for one database:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nDECLARE @log nvarchar(260) = CAST(SERVERPROPERTY(&#039;ErrorLogFileName&#039;) AS nvarchar(260));\nDECLARE @xel nvarchar(260) = LEFT(@log, LEN(@log) - CHARINDEX(N&#039;\\&#039;, REVERSE(@log)) + 1) + N&#039;optimized_locking*.xel&#039;;\n\nSELECT CAST(x.timestamp_utc AS datetime2(0))       AS ts_utc,\n       x.object_name,\n       d.n.value(&#039;@name&#039;, &#039;sysname&#039;)                AS field,\n       d.n.value(&#039;(value)&#x5B;1]&#039;, &#039;nvarchar(400)&#039;)     AS value\nFROM sys.fn_xe_file_target_read_file(@xel, NULL, NULL, NULL) AS x\nCROSS APPLY (SELECT CAST(x.event_data AS xml)) AS t(e)\nCROSS APPLY t.e.nodes(&#039;\/event\/data&#039;) AS d(n)\nWHERE x.object_name IN (N&#039;locking_stats&#039;, N&#039;locking_stats2&#039;)\n  AND t.e.value(&#039;(\/event\/data&#x5B;@name=&quot;database_id&quot;]\/value)&#x5B;1]&#039;, &#039;int&#039;) = DB_ID(N&#039;&lt;DB_NAME&gt;&#039;)\n  AND d.n.value(&#039;@name&#039;, &#039;sysname&#039;) &lt;&gt; N&#039;database_id&#039;\n  AND d.n.value(&#039;(value)&#x5B;1]&#039;, &#039;nvarchar(400)&#039;) NOT IN (N&#039;0&#039;, N&#039;false&#039;)\nORDER BY ts_utc, x.object_name, field;\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">You cannot force <code>locking_stats<\/code> to fire, you have to wait. In my lab it came <strong>every 5 minutes<\/strong> for an active database.<\/p>\n\n\n\n<h2 id=\"h-without-optimized-locking-the-escalation\" class=\"wp-block-heading\">Without optimized locking: the escalation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Back to the 10,000-row update, on a database without optimized locking. The <code>lock_escalation<\/code> event arrives right away, and the next <code>locking_stats<\/code> counts it:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"178\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-67.png\" alt=\"\" class=\"wp-image-47925\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-67.png 640w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-67-300x83.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">The escalation was caused by the lock count (<code>Lock threshold<\/code>), and 6,249 locks were converted into the table lock. I got exactly 6,249 every time I ran this test. About five minutes later, <code>locking_stats<\/code> showed <code>lock_escalations_lock_threshold = 1<\/code>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>lock_escalation<\/code> is the one to use when you look for the statement that escalated. The counter in <code>locking_stats<\/code> is cheaper to collect, for all databases, and it is a good way to compare the number of escalations before and after enabling optimized locking.<\/p>\n\n\n\n<h2 id=\"h-with-optimized-locking-reading-the-waits\" class=\"wp-block-heading\">With optimized locking: reading the waits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After enabling ADR and optimized locking, the same update didn&#8217;t produce any <code>lock_escalation<\/code> event. A second session updating <code>id = 150000<\/code>, a row far from the first 10,000, was not blocked anymore.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the second session updates a row that the first one modified, it still has to wait, but now it waits on the transaction. The wait type is <code>LCK_M_S_XACT_MODIFY<\/code>, and <code>wait_resource<\/code> shows the transaction and the row together:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nXACT: 30:4417:0 KEY: 30:72057594047234048 (c1ceb6ec8491)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">With a parallel plan, I was surprised at first: <code>sys.dm_exec_requests<\/code> showed only <code>CXCONSUMER<\/code> for the blocked statement. The lock waits (<code>LCK_M_S_XACT<\/code>) were visible on the parallel tasks, in <code>sys.dm_os_waiting_tasks<\/code>.<\/p>\n\n\n\n<h2 id=\"h-laq-shows-as-enabled-but-it-never-ran\" class=\"wp-block-heading\">LAQ shows as enabled, but it never ran<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At this stage, the database had ADR and optimized locking, but RCSI was still off. I ran two updates on two different customers. The second one stayed blocked until the first one rolled back. Then I read the next <code>locking_stats<\/code>:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"667\" height=\"215\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-69.png\" alt=\"\" class=\"wp-image-47926\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-69.png 667w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-69-300x97.png 300w\" sizes=\"auto, (max-width: 667px) 100vw, 667px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>is_tid_locking_enabled<\/code> is <code>true<\/code>, as expected. <code>is_lock_after_qualification_enabled<\/code> is <code>true<\/code> as well, <span style=\"text-decoration: underline\"><a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\" data-type=\"link\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\">even though LAQ cannot work without RCSI<\/a><\/span>. Both flags simply follow the <code>OPTIMIZED_LOCKING<\/code> setting of the database. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The information is in what the grid doesn&#8217;t show. There is no <code>num_lock_after_qualification_attempts<\/code> row, so LAQ was not used a single time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On a fresh database with ADR, optimized locking and RCSI enabled, I ran the same test. This time the second update went through immediately, and the next locking_stats looked like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"636\" height=\"201\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-72.png\" alt=\"\" class=\"wp-image-47939\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-72.png 636w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-72-300x95.png 300w\" sizes=\"auto, (max-width: 636px) 100vw, 636px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The flags are the same as before, but now <code>num_lock_after_qualification_attempts = 2<\/code>: both updates used LAQ. <code>num_lock_after_qualification_without_requalify = 2<\/code> says that neither of them had to evaluate a row again, which makes sense since they never touched the same customer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So if you want to know whether LAQ is really working on a database,<code> num_lock_after_qualification_attempts<\/code> is the field to check. If it never appears while updates are running, LAQ is not being used.<\/p>\n\n\n\n<h2 id=\"h-when-laq-restarts-a-statement\" class=\"wp-block-heading\">When LAQ restarts a statement<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With RCSI enabled, LAQ has to deal with rows modified by another transaction. The statement waits for that transaction, then evaluates the row again (a requalification, counted in <code>num_lock_after_qualification_requalifies<\/code>). When the plan doesn&#8217;t allow it, SQL Server restarts the statement <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/optimized-locking?view=sql-server-ver17\">without LAQ<\/a>, and the work done before the restart <a href=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/introducing-optimized-locking-v2\/4468745\" data-type=\"link\" data-id=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/introducing-optimized-locking-v2\/4468745\">is wasted<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To get this case, session 1 updates customer 1 and keeps its transaction open. Session 2 runs <code>UPDATE dbo.orders SET amount = amount + 10 WHERE customer_id IN (1, 2)<\/code> and waits. Then session 1 commits:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"53\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-68-1024x53.png\" alt=\"\" class=\"wp-image-47924\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-68-1024x53.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-68-300x16.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-68-751x39.png 751w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-68.png 1194w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><code>logical_reads_before_retry<\/code> gives the work lost before the restart, 3 reads here. In two earlier runs of the same test, the next locking_stats showed <code>num_lock_after_qualification_requalifies_not_supported = 1<\/code> and <code>num_lock_after_qualification_unsupported_op = 2<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In my tests, the plan made the difference. <strong>With <code>OPTION (MAXDOP 1)<\/code>, the same scenario ended with one requalified row and no restart. With a parallel plan (<code>Gather Streams<\/code> before the <code>Clustered Index Update<\/code>), the statement was restarted each time.<\/strong> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An occasional restart is not a problem. If the same plan hash comes back again and again, that is wasted work. In the <em>optimized locking v2<\/em> <a href=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/introducing-optimized-locking-v2\/4468745\" data-type=\"link\" data-id=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/introducing-optimized-locking-v2\/4468745\">post<\/a>, Dimitri Furman explains what SQL Server does about it:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">With the new improvement, in addition to tracking at the database level, the engine also tracks LAQ feedback at the query plan level and persists it in Query Store. If thresholds are exceeded for a particular query plan, <strong>LAQ is disabled only for that plan rather than for the entire database. The rest of the workload still benefits from LAQ<\/strong>.<\/p>\n<\/blockquote>\n\n\n\n<h2 id=\"h-conclusion\" class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Optimized locking doesn\u2019t require rewriting queries, but lock hints, OUTPUT or MERGE keep LAQ out, as the skip reasons show. To check what it actually does, you have to read the right fields, because the <code>enabled<\/code> flags only reflect the database setting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is what I would look at on a SQL Server 2025 instance:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Question<\/th><th>Where to look<\/th><\/tr><\/thead><tbody><tr><td>Do escalations still happen?<\/td><td><code>lock_escalation<\/code>, and <code>lock_escalations_lock_threshold<\/code> \/ <code>lock_escalations_memory_pressure<\/code> in <code>locking_stats<\/code><\/td><\/tr><tr><td>Is LAQ really used?<\/td><td><code>num_lock_after_qualification_attempts<\/code> (the <code>is_lock_after_qualification_enabled<\/code> flag is not enough)<\/td><\/tr><tr><td>Why is LAQ skipped?<\/td><td>the <code>laq_skip_reason_*<\/code> counters (lock hints, <code>OUTPUT<\/code>, <code>MERGE<\/code>, columnstore, wasted work&#8230;)<\/td><\/tr><tr><td>Are statements restarted?<\/td><td><code>lock_after_qual_stmt_abort<\/code>, then the plan hash in Query Store<\/td><\/tr><tr><td>Who is blocking whom?<\/td><td>the <code>XACT<\/code> part of <code>wait_resource<\/code>, and <code>sys.dm_os_waiting_tasks<\/code> for parallel plans<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To go further, Microsoft&#8217;s support team followed <a href=\"https:\/\/techcommunity.microsoft.com\/blog\/azuredbsupport\/understanding-optimized-locking-in-azure-sql-database\/4358636\" data-type=\"link\" data-id=\"https:\/\/techcommunity.microsoft.com\/blog\/azuredbsupport\/understanding-optimized-locking-in-azure-sql-database\/4358636\">the locks one by one with Extended Events<\/a>, and the <em>optimized locking v2<\/em> <a href=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/introducing-optimized-locking-v2\/4468745\" data-type=\"link\" data-id=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/introducing-optimized-locking-v2\/4468745\">post <\/a>measures skipped index locks with <code>lock_acquired<\/code> and a histogram target.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.<\/p>\n","protected":false},"author":157,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":"","_members_access_role":[],"_members_access_error":""},"categories":[368,99],"tags":[4285,51],"type_dbi":[],"class_list":["post-47916","post","type-post","status-publish","format-standard","hentry","category-development-performance","category-sql-server","tag-optimized-locking","tag-sql-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.7 (Yoast SEO v28.7) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>SQL Server 2025: is optimized locking really working? Ask the Extended Events - dbi Blog<\/title>\n<meta name=\"description\" content=\"How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL Server 2025: is optimized locking really working? Ask the Extended Events\" \/>\n<meta property=\"og:description\" content=\"How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-19T13:05:13+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-19T13:05:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png\" \/>\n\t<meta property=\"og:image:width\" content=\"346\" \/>\n\t<meta property=\"og:image:height\" content=\"104\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Louis Tochon\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Louis Tochon\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/\"},\"author\":{\"name\":\"Louis Tochon\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/23211c7524fbe5264dbe8f294dab9ba0\"},\"headline\":\"SQL Server 2025: is optimized locking really working? Ask the Extended Events\",\"datePublished\":\"2026-10-19T13:05:13+00:00\",\"dateModified\":\"2026-10-19T13:05:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/\"},\"wordCount\":1240,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/10\\\/image-70.png\",\"keywords\":[\"optimized locking\",\"SQL Server\"],\"articleSection\":[\"Development &amp; Performance\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/\",\"name\":\"SQL Server 2025: is optimized locking really working? Ask the Extended Events - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/10\\\/image-70.png\",\"datePublished\":\"2026-10-19T13:05:13+00:00\",\"dateModified\":\"2026-10-19T13:05:15+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/23211c7524fbe5264dbe8f294dab9ba0\"},\"description\":\"How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/10\\\/image-70.png\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/10\\\/image-70.png\",\"width\":346,\"height\":104},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL Server 2025: is optimized locking really working? Ask the Extended Events\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/23211c7524fbe5264dbe8f294dab9ba0\",\"name\":\"Louis Tochon\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g\",\"caption\":\"Louis Tochon\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/louistochon\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"SQL Server 2025: is optimized locking really working? Ask the Extended Events - dbi Blog","description":"How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/","og_locale":"en_US","og_type":"article","og_title":"SQL Server 2025: is optimized locking really working? Ask the Extended Events","og_description":"How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.","og_url":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/","og_site_name":"dbi Blog","article_published_time":"2026-10-19T13:05:13+00:00","article_modified_time":"2026-10-19T13:05:15+00:00","og_image":[{"width":346,"height":104,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png","type":"image\/png"}],"author":"Louis Tochon","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Louis Tochon","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/"},"author":{"name":"Louis Tochon","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/23211c7524fbe5264dbe8f294dab9ba0"},"headline":"SQL Server 2025: is optimized locking really working? Ask the Extended Events","datePublished":"2026-10-19T13:05:13+00:00","dateModified":"2026-10-19T13:05:15+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/"},"wordCount":1240,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png","keywords":["optimized locking","SQL Server"],"articleSection":["Development &amp; Performance","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/","url":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/","name":"SQL Server 2025: is optimized locking really working? Ask the Extended Events - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png","datePublished":"2026-10-19T13:05:13+00:00","dateModified":"2026-10-19T13:05:15+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/23211c7524fbe5264dbe8f294dab9ba0"},"description":"How to check what SQL Server 2025 optimized locking really does with Extended Events: escalations, LAQ attempts and restarts.","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/10\/image-70.png","width":346,"height":104},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-2025-is-optimized-locking-really-working-ask-the-extended-events\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"SQL Server 2025: is optimized locking really working? Ask the Extended Events"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/23211c7524fbe5264dbe8f294dab9ba0","name":"Louis Tochon","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g","caption":"Louis Tochon"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/louistochon\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/47916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/157"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=47916"}],"version-history":[{"count":21,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/47916\/revisions"}],"predecessor-version":[{"id":47958,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/47916\/revisions\/47958"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=47916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=47916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=47916"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=47916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}