{"id":45334,"date":"2026-07-20T11:58:44","date_gmt":"2026-07-20T09:58:44","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=45334"},"modified":"2026-07-20T11:59:30","modified_gmt":"2026-07-20T09:59:30","slug":"when-an-idle-transaction-starves-the-worker-pool-threadpool","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/","title":{"rendered":"When an idle transaction starves the worker pool (THREADPOOL)"},"content":{"rendered":"\n<h2 id=\"h-context\" class=\"wp-block-heading\">Context<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A production instance, mid-afternoon, nothing unusual on any dashboard. An engineer opens a transaction to patch a single row while investigating a data issue:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nBEGIN TRANSACTION;\nUPDATE dbo.Orders SET Status = &#039;Reviewed&#039; WHERE OrderId = 482193;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">No <code>COMMIT<\/code>. No <code>ROLLBACK<\/code>. The tab gets buried under three others, the investigation moves on, and the lock is still held an hour later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Every query, every batch, every login needs a worker thread to execute on. That pool is not infinite, it is sized by <code>max worker threads<\/code>, either left on its computed default or pinned to a fixed number.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nSELECT name, value_in_use FROM sys.configurations WHERE name = &#039;max worker threads&#039;;\n\nname                                value_in_use\n----------------------------------- -------------------------------------------------------------------------------------------------------------------------\nmax worker threads                  128\n<\/pre><\/div>\n\n\n<h2 id=\"h-what-does-sleeping-really-mean\" class=\"wp-block-heading\">What does &#8220;Sleeping&#8221; really mean?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SQL Server schedules work cooperatively, not preemptively. Each worker is handed a quantum (4 milliseconds) to run before it is expected to voluntarily yield the scheduler to the next runnable task. This is the mechanism behind <code>SOS_SCHEDULER_YIELD<\/code>: a worker that still has work to do, but whose quantum has expired, stepping aside so someone else gets a turn. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"675\" height=\"478\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png\" alt=\"\" class=\"wp-image-45358\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png 675w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48-300x212.png 300w\" sizes=\"auto, (max-width: 675px) 100vw, 675px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">None of this applies to the open transaction from earlier. A session that has issued no command has no task and holds no worker. Its status in <code>sys.dm_exec_sessions<\/code> is <code><strong>sleeping<\/strong><\/code>, not <code>running<\/code>, not <code>suspended<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nSELECT\n    s.session_id,\n    s.status AS session_status,\n    ct.text\nFROM sys.dm_exec_sessions s\nLEFT JOIN sys.dm_exec_requests r ON s.session_id = r.session_id\nLEFT JOIN sys.dm_exec_connections c ON s.session_id = c.session_id\nOUTER APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) ct\nWHERE s.session_id = 54;\n\nsession_id session_status                 text\n---------- ------------------------------ --------------------------------------------------------------------------------------------------------------------\n54         sleeping                       UPDATE dbo.Orders SET Status = &#039;Reviewed&#039; WHERE OrderId = 482193;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"> It is not waiting for a quantum, because it is not competing for one. The lock it holds costs the engine nothing in scheduling terms; it is bookkeeping in the lock manager, entirely separate from the worker pool.<\/p>\n\n\n\n<h2 id=\"h-two-hundred-sessions-walk-into-a-lock\" class=\"wp-block-heading\">Two hundred sessions walk into a lock<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s say that the application wants to confirm that the orders has been reviewed now it&#8217;s in the processed state. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nBEGIN TRANSACTION;\nUPDATE dbo.Orders SET Status = &#039;Processed&#039; WHERE OrderId = 482193;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Seeing that the query didn&#8217;t complete to update the item, it will keep sending this transaction again and again, sending it 200 times let&#8217;s say. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unlike the sleeping session above, each of these has issued a command. Each one is granted a worker to execute it, immediately hits the lock, and transitions to <code>suspended<\/code>, waiting on <code>LCK_M_X<\/code>. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nwait_type                   waiting_tasks_count       wait_time_ms\nTHREADPOOL                      521                      2881770\nSOS_SCHEDULER_YIELD             710                      41\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n session_id     status        wait_type        wait_time   blocking_session_id \n    68         suspended       LCK_M_X          29873             54\n   ...\n   206         suspended       LCK_M_X          29478             68\n   207         suspended       LCK_M_X          29478             68\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nscheduler_id runnable_tasks_count work_queue_count active_workers_count\n       0              0               19                 43\n       1              0               5                  45\n       2              0               10                 45\n       3              0               2                  44\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nactive_workers    max_workers_count       \n         205                    128\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><span style=\"text-decoration: underline\">Note:<\/span> <code>max_workers_count<\/code> only counts the user-facing pool; internal system threads, including the DAC&#8217;s own reserved worker used to capture this very output, sit outside that ceiling.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The worker is not released while the task waits. It stays attached to the suspended task for the entire duration of the block, doing nothing, simply reserved, waiting for the resource (the order line to update) to be available for updates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The remainder cannot even be granted a worker to start waiting. They queue behind everyone else, and eventually give up entirely:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nLogin timeout expired\nLogin\/Query timeout: 15\/0 seconds\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">By this point the server has simply stopped accepting new connections.<\/p>\n\n\n\n<h2 id=\"h-when-the-fire-exit-is-also-on-fire\" class=\"wp-block-heading\">When the fire exit is also on fire<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Releasing the original lock should be the easy part: switch back to the session from the very first transaction, issue a <code>ROLLBACK<\/code>, and watch everything clear. Except that session, which has been sitting <code>sleeping<\/code> and worker-free this whole time, now has to issue a command of its own. And issuing a command means asking the pool for a worker (the same exhausted pool every other session is already queued for). The session responsible for the deadlock has no priority for fixing it. It gets in line like everyone else, behind two hundred sessions it created the conditions for.<\/p>\n\n\n\n<h2 id=\"h-when-dac-is-the-last-resort\" class=\"wp-block-heading\">When DAC is the last resort<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is where the Dedicated Admin Connection comes in the game. It runs on its own scheduler, with a worker reserved outside the regular pool, built specifically for an instance too exhausted to serve itself.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nsqlcmd -A -S&quot;.&quot; -E\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nSELECT blocking_session_id\nFROM sys.dm_exec_requests\nWHERE blocking_session_id &lt;&gt; 0;\n\nKILL 54;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><span style=\"text-decoration: underline\">Note:<\/span> the &#8220;.&#8221; here resolves to the local default instance but unlike an ordinary local connection (which typically uses Shared Memory), the DAC always connects over its own dedicated TCP listener on the loopback adapter, regardless of protocol settings on the port 1434 or a dynamic one (full documentation <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/database-engine\/configure-windows\/diagnostic-connection-for-database-administrators?view=sql-server-ver17\" id=\"https:\/\/learn.microsoft.com\/en-us\/sql\/database-engine\/configure-windows\/diagnostic-connection-for-database-administrators?view=sql-server-ver17\">here<\/a>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>KILL<\/code> forces the rollback from outside the exhausted pool entirely. Workers free up in cascade, and the two hundred suspended sessions complete their updates and release their own.<\/p>\n\n\n\n<h2 id=\"h-final-thoughts\" class=\"wp-block-heading\">Final thoughts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, we set the parameter <code>max worker threads <\/code>to 128 to easily saturate the worker threads. However, the default value for <code>max worker threads<\/code> is 0, which lets SQL Server compute the number of worker threads automatically at startup based on the number of logical CPUs and the platform architecture. Microsoft best practice can be found <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/database-engine\/configure-windows\/configure-the-max-worker-threads-server-configuration-option?view=sql-server-ver17\" id=\"https:\/\/learn.microsoft.com\/en-us\/sql\/database-engine\/configure-windows\/configure-the-max-worker-threads-server-configuration-option?view=sql-server-ver17\">here <\/a>and shows the following table:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table class=\"has-fixed-layout\"><thead><tr><th>Number of logical CPUs<\/th><th>64-bit computer<\/th><\/tr><\/thead><tbody><tr><td>&lt;= 4<\/td><td>512<\/td><\/tr><tr><td>&gt; 4 and &lt;= 64<\/td><td>512\u00a0+ ((logical CPUs &#8211; 4) * 16)<\/td><\/tr><tr><td>&gt; 64<\/td><td>512\u00a0+ ((logical CPUs &#8211; 4) * 32)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">And the key take-away from this experiment:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Sleeping costs nothing, suspended costs a worker.<\/strong> The distinction between an idle transaction and a blocked one is the entire mechanism behind this incident: both hold a lock, only one of them holds a thread.<\/li>\n\n\n\n<li><strong>The scheduler&#8217;s quantum explains CPU pressure, not threadpool exhaustion.<\/strong> Yielding after 4ms is about sharing a CPU among runnable workers; it has nothing to do with how many workers exist in the first place.<\/li>\n\n\n\n<li><strong>The session that caused the block is not exempt from the consequences of the block.<\/strong> It has to compete for a worker like anything else, the moment it tries to clean up after itself.<\/li>\n\n\n\n<li><strong>Never let a statement end without a <code>COMMIT<\/code> or a <code>ROLLBACK<\/code><\/strong>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How a forgotten transaction exhausted SQL Server&#8217;s worker pool, triggered THREADPOOL waits, and only DAC could fix it.<\/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":[229,99],"tags":[],"type_dbi":[],"class_list":["post-45334","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","category-sql-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.0 (Yoast SEO v28.0) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>When an idle transaction starves the worker pool (THREADPOOL) - dbi Blog<\/title>\n<meta name=\"description\" content=\"How a forgotten transaction exhausted SQL Server&#039;s worker pool, triggered THREADPOOL waits, and only DAC could fix it.\" \/>\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\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"When an idle transaction starves the worker pool (THREADPOOL)\" \/>\n<meta property=\"og:description\" content=\"How a forgotten transaction exhausted SQL Server&#039;s worker pool, triggered THREADPOOL waits, and only DAC could fix it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-20T09:58:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-20T09:59:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png\" \/>\n\t<meta property=\"og:image:width\" content=\"675\" \/>\n\t<meta property=\"og:image:height\" content=\"478\" \/>\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=\"4 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\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/\"},\"author\":{\"name\":\"Louis Tochon\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/e4195b0cb120295b3407a502c23e75b6\"},\"headline\":\"When an idle transaction starves the worker pool (THREADPOOL)\",\"datePublished\":\"2026-07-20T09:58:44+00:00\",\"dateModified\":\"2026-07-20T09:59:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/\"},\"wordCount\":819,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/06\\\/image-48.png\",\"articleSection\":[\"Database Administration &amp; Monitoring\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/\",\"name\":\"When an idle transaction starves the worker pool (THREADPOOL) - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/06\\\/image-48.png\",\"datePublished\":\"2026-07-20T09:58:44+00:00\",\"dateModified\":\"2026-07-20T09:59:30+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/e4195b0cb120295b3407a502c23e75b6\"},\"description\":\"How a forgotten transaction exhausted SQL Server's worker pool, triggered THREADPOOL waits, and only DAC could fix it.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/06\\\/image-48.png\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/06\\\/image-48.png\",\"width\":675,\"height\":478},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-an-idle-transaction-starves-the-worker-pool-threadpool\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"When an idle transaction starves the worker pool (THREADPOOL)\"}]},{\"@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\\\/e4195b0cb120295b3407a502c23e75b6\",\"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":"When an idle transaction starves the worker pool (THREADPOOL) - dbi Blog","description":"How a forgotten transaction exhausted SQL Server's worker pool, triggered THREADPOOL waits, and only DAC could fix it.","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\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/","og_locale":"en_US","og_type":"article","og_title":"When an idle transaction starves the worker pool (THREADPOOL)","og_description":"How a forgotten transaction exhausted SQL Server's worker pool, triggered THREADPOOL waits, and only DAC could fix it.","og_url":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/","og_site_name":"dbi Blog","article_published_time":"2026-07-20T09:58:44+00:00","article_modified_time":"2026-07-20T09:59:30+00:00","og_image":[{"width":675,"height":478,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png","type":"image\/png"}],"author":"Louis Tochon","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Louis Tochon","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/"},"author":{"name":"Louis Tochon","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/e4195b0cb120295b3407a502c23e75b6"},"headline":"When an idle transaction starves the worker pool (THREADPOOL)","datePublished":"2026-07-20T09:58:44+00:00","dateModified":"2026-07-20T09:59:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/"},"wordCount":819,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png","articleSection":["Database Administration &amp; Monitoring","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/","url":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/","name":"When an idle transaction starves the worker pool (THREADPOOL) - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png","datePublished":"2026-07-20T09:58:44+00:00","dateModified":"2026-07-20T09:59:30+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/e4195b0cb120295b3407a502c23e75b6"},"description":"How a forgotten transaction exhausted SQL Server's worker pool, triggered THREADPOOL waits, and only DAC could fix it.","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/06\/image-48.png","width":675,"height":478},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/when-an-idle-transaction-starves-the-worker-pool-threadpool\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"When an idle transaction starves the worker pool (THREADPOOL)"}]},{"@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\/e4195b0cb120295b3407a502c23e75b6","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\/45334","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=45334"}],"version-history":[{"count":48,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45334\/revisions"}],"predecessor-version":[{"id":45635,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45334\/revisions\/45635"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=45334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=45334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=45334"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=45334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}