<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Microsoft SQL Server Operations Guides on Netdata</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/</link><description>Recent content in Microsoft SQL Server Operations Guides on Netdata</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://www.netdata.cloud/guides/microsoft-sql-server/index.xml" rel="self" type="application/rss+xml"/><item><title>How Microsoft SQL Server actually works in production: a mental model for operators</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-how-it-works-in-production/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-how-it-works-in-production/</guid><description>&lt;h1 id="how-microsoft-sql-server-actually-works-in-production-a-mental-model-for-operators">How Microsoft SQL Server actually works in production: a mental model for operators&lt;/h1>
&lt;p>Most SQL Server incidents look confusing because operators bring a Linux-process mental model to a system that is not one. &lt;code>sqlservr&lt;/code> (&lt;code>sqlservr.exe&lt;/code> on Windows) is a single multi-threaded process, but inside it runs SQLOS, a user-mode operating system with its own scheduler, memory manager, and I/O completion handling. The host OS does not schedule your queries, does not cache your data pages, and does not decide which transaction gets a lock. SQL Server does all of that itself.&lt;/p></description></item><item><title>Microsoft SQL Server monitoring checklist: the signals every production instance needs</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-monitoring-checklist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-monitoring-checklist/</guid><description>&lt;h1 id="microsoft-sql-server-monitoring-checklist-the-signals-every-production-instance-needs">Microsoft SQL Server monitoring checklist: the signals every production instance needs&lt;/h1>
&lt;p>Most SQL Server outages are not exotic. The transaction log fills because a backup job silently stopped. A sleeping session with an open transaction blocks forty other sessions until the worker pool runs dry. TempDB runs out of space and every database on the instance stalls at once. All of these are visible hours or days in advance if you collect the right signals. Most teams do not.&lt;/p></description></item><item><title>Microsoft SQL Server monitoring maturity model: from survival to expert</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-monitoring-maturity-model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-monitoring-maturity-model/</guid><description>&lt;h1 id="microsoft-sql-server-monitoring-maturity-model-from-survival-to-expert">Microsoft SQL Server monitoring maturity model: from survival to expert&lt;/h1>
&lt;p>Most SQL Server outages are not exotic. The transaction log fills because nobody noticed log backups stopped. A head blocker sits idle with an open transaction while the worker thread pool drains. Error 825 appears in the error log for weeks before the disk actually fails. In each case, the signal was available; the monitoring just was not looking at it.&lt;/p></description></item><item><title>SQL Server AG send and redo queues growing: replication lag and failover RTO</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-ag-send-redo-queue-growing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-ag-send-redo-queue-growing/</guid><description>&lt;h1 id="sql-server-ag-send-and-redo-queues-growing-replication-lag-and-failover-rto">SQL Server AG send and redo queues growing: replication lag and failover RTO&lt;/h1>
&lt;p>Two queues decide whether your Always On Availability Group can actually fail over: the send queue (log generated on the primary but not yet shipped to the secondary) and the redo queue (log received by the secondary but not yet replayed). When either grows without bound, replication lag is the visible symptom, but the hidden cost is failover RTO. On forced or automatic failover, the new primary must drain the entire redo queue before it accepts writes, so a queue that looks tolerable during steady state can turn a 30-second failover into a 30-minute one.&lt;/p></description></item><item><title>SQL Server AlwaysOn failover readiness: quorum, health checks, and the failover you assume works</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-ag-failover-readiness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-ag-failover-readiness/</guid><description>&lt;h1 id="sql-server-alwayson-failover-readiness-quorum-health-checks-and-the-failover-you-assume-works">SQL Server AlwaysOn failover readiness: quorum, health checks, and the failover you assume works&lt;/h1>
&lt;p>An AG that reports &amp;ldquo;healthy&amp;rdquo; in the dashboard can still fail to failover when you need it. The synchronization state tells you data is flowing between replicas. It says nothing about whether the cluster can orchestrate a failover, whether the health detection policy will catch the specific failure you are about to have, or whether the cluster has already exhausted its automatic failover budget for the period.&lt;/p></description></item><item><title>SQL Server Availability Group not synchronizing: NOT_HEALTHY replicas and failover risk</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-ag-not-synchronizing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-ag-not-synchronizing/</guid><description>&lt;h1 id="sql-server-availability-group-not-synchronizing-not_healthy-replicas-and-failover-risk">SQL Server Availability Group not synchronizing: NOT_HEALTHY replicas and failover risk&lt;/h1>
&lt;p>The symptom arrives as an alert or a dashboard color change: a synchronous-commit secondary replica is reporting &lt;code>synchronization_health_desc = NOT_HEALTHY&lt;/code> or &lt;code>connected_state_desc = DISCONNECTED&lt;/code> in &lt;code>sys.dm_hadr_availability_replica_states&lt;/code>. The primary is still accepting writes, but the protection you assumed is degraded or gone.&lt;/p>
&lt;p>In synchronous-commit mode, the primary waits for the secondary to harden log records before acknowledging commits. When the secondary drops or stops keeping up, the primary either continues unprotected or stops accepting writes entirely, depending on &lt;code>required_synchronized_secondaries_to_commit&lt;/code>. Either way, your recovery point objective and your recovery time objective are both at risk.&lt;/p></description></item><item><title>SQL Server backup freshness: the recovery point you only discover you lack during an incident</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-backup-freshness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-backup-freshness/</guid><description>&lt;h1 id="sql-server-backup-freshness-the-recovery-point-you-only-discover-you-lack-during-an-incident">SQL Server backup freshness: the recovery point you only discover you lack during an incident&lt;/h1>
&lt;p>The recovery point you actually have is the recovery point you can restore to, not the one your schedule promises. Backup freshness is the gap between those two, measured as the time since the last successful full, differential, and transaction log backup per database. When that gap is wrong, you find out during restore: either an analyst files a ticket for missing data, or an incident forces point-in-time recovery and the chain breaks.&lt;/p></description></item><item><title>SQL Server blocking chains: finding the head blocker before workers run out</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-blocking-chain/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-blocking-chain/</guid><description>&lt;h1 id="sql-server-blocking-chains-finding-the-head-blocker-before-workers-run-out">SQL Server blocking chains: finding the head blocker before workers run out&lt;/h1>
&lt;p>SQL Server is unresponsive. CPU and I/O counters are low. Connections succeed but queries hang. Timeouts and login failures follow. This is the shape of a blocking chain that has crossed into worker-thread exhaustion.&lt;/p>
&lt;p>One session holds a lock. Conflicting sessions queue behind it, each waiting on an &lt;code>LCK_M_*&lt;/code> wait and each pinning a worker from SQL Server&amp;rsquo;s fixed-size pool. As the chain deepens, the worker pool drains. Once exhausted, new requests get &lt;code>THREADPOOL&lt;/code> waits and the instance appears down to applications, even though the OS shows &lt;code>sqlservr&lt;/code> healthy and storage idle.&lt;/p></description></item><item><title>SQL Server buffer cache hit ratio low: when the working set no longer fits in memory</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-buffer-cache-hit-ratio-low/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-buffer-cache-hit-ratio-low/</guid><description>&lt;h1 id="sql-server-buffer-cache-hit-ratio-low-when-the-working-set-no-longer-fits-in-memory">SQL Server buffer cache hit ratio low: when the working set no longer fits in memory&lt;/h1>
&lt;p>A low buffer cache hit ratio (BCHR) gets two reactions in production: teams page on-call for a single dip during a maintenance window, or they ignore a sustained decline because the counter is &amp;ldquo;unreliable.&amp;rdquo; Both are wrong. BCHR is a weak signal alone, but paired with Page Life Expectancy (PLE), &lt;code>PAGEIOLATCH_*&lt;/code> waits, and workload context, it tells you whether your working set still fits in the buffer pool.&lt;/p></description></item><item><title>SQL Server CPU utilization high: telling query load apart from a bad plan</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-cpu-utilization-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-cpu-utilization-high/</guid><description>&lt;h1 id="sql-server-cpu-utilization-high-telling-query-load-apart-from-a-bad-plan">SQL Server CPU utilization high: telling query load apart from a bad plan&lt;/h1>
&lt;p>Your monitoring says the SQL Server host is at 98% CPU. Before you page anyone or start killing sessions: SQL Server is designed to use available CPU. A cold buffer pool after restart, backup compression, an ETL window, or a well-parallelized reporting query will all legitimately pin CPU at 90%+. High CPU is a symptom with no severity attached until you answer two questions: who is burning the CPU (SQL Server or something else on the host), and is the work useful (throughput) or wasted (a bad plan, a compilation storm, or spinlock contention).&lt;/p></description></item><item><title>SQL Server CXPACKET and CXCONSUMER waits: parallelism, MAXDOP, and what is actually wrong</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-cxpacket-cxconsumer-waits/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-cxpacket-cxconsumer-waits/</guid><description>&lt;h1 id="sql-server-cxpacket-and-cxconsumer-waits-parallelism-maxdop-and-what-is-actually-wrong">SQL Server CXPACKET and CXCONSUMER waits: parallelism, MAXDOP, and what is actually wrong&lt;/h1>
&lt;p>You opened &lt;code>sys.dm_os_wait_stats&lt;/code>, excluded the idle noise, and CXPACKET is sitting at the top consuming 40, 50, maybe 70 percent of total wait time. The first search result tells you parallelism is out of control. The second tells you to set MAXDOP to 1. Both are usually wrong.&lt;/p>
&lt;p>CXPACKET is routinely the number one wait on healthy systems. Its presence alone means parallel queries are running, and parallel threads spend much of their existence waiting for each other. The wait is a side effect of work being done in parallel, not the disease. The real questions are whether that parallel work is skewed, whether the queries going parallel should be parallel at all, and whether the engine is burning worker threads and CPU on plans that would be faster serial.&lt;/p></description></item><item><title>SQL Server database in SUSPECT or RECOVERY_PENDING: an offline database and how to recover it</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-database-suspect-recovery-pending/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-database-suspect-recovery-pending/</guid><description>&lt;h1 id="sql-server-database-in-suspect-or-recovery_pending-an-offline-database-and-how-to-recover-it">SQL Server database in SUSPECT or RECOVERY_PENDING: an offline database and how to recover it&lt;/h1>
&lt;p>A production database is showing &lt;code>state_desc = SUSPECT&lt;/code> or &lt;code>RECOVERY_PENDING&lt;/code> in &lt;code>sys.databases&lt;/code>. Applications cannot open connections to that database. Users are seeing login failures, query timeouts, or generic &amp;ldquo;database cannot be opened&amp;rdquo; errors. The SQL Server instance itself is up, and every other database on it may be fine.&lt;/p>
&lt;p>&lt;code>RECOVERY_PENDING&lt;/code> rarely means corruption. It usually means SQL Server could not get the resources it needed during recovery: a missing file, a full log volume, a permissions change, or a transient I/O failure at startup. &lt;code>SUSPECT&lt;/code> is more serious because recovery actually ran and failed, but it still does not automatically mean data loss. The wrong move is to jump straight to &lt;code>DBCC CHECKDB&lt;/code> with &lt;code>REPAIR_ALLOW_DATA_LOSS&lt;/code>. The right move is to fix the underlying resource, re-run recovery, and only fall back to repair or restore when that fails.&lt;/p></description></item><item><title>SQL Server Error 1205: transaction was deadlocked and chosen as the deadlock victim</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-1205-deadlock-victim/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-1205-deadlock-victim/</guid><description>&lt;h1 id="sql-server-error-1205-transaction-was-deadlocked-and-chosen-as-the-deadlock-victim">SQL Server Error 1205: transaction was deadlocked and chosen as the deadlock victim&lt;/h1>
&lt;p>The error text returned to the client is explicit:&lt;/p>
&lt;blockquote>
&lt;p>Transaction (Process ID %d) was deadlocked on %.*ls resources with another process and has been chosen as the deadlock victim. Rerun the transaction.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;code>%d&lt;/code> is the SPID. &lt;code>%.*ls&lt;/code> names the resource type, typically &lt;code>lock&lt;/code>. The message tells the application to rerun the transaction but not why the deadlock happened, which resource was contended, or which other session was involved. To answer those questions you need the deadlock graph.&lt;/p></description></item><item><title>SQL Server Error 18456: login failed for user, and what the state code means</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-18456-login-failed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-18456-login-failed/</guid><description>&lt;p>SQL Server Error 18456 is the universal &amp;ldquo;Login failed for user X&amp;rdquo; message. It is deliberately vague: every client, from &lt;code>sqlcmd&lt;/code> to the application&amp;rsquo;s connection pool, sees the same string with severity 14 and state 1. The client never learns whether the password was wrong, the login does not exist, the database is offline, or the account is disabled. That information lives only in the SQL Server error log, encoded as a state code.&lt;/p></description></item><item><title>SQL Server Error 701: there is insufficient system memory to run this query</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-701-insufficient-memory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-701-insufficient-memory/</guid><description>&lt;p>Error 701 is one of SQL Server&amp;rsquo;s bluntest messages: &amp;ldquo;There is insufficient system memory in resource pool &amp;lsquo;default&amp;rsquo; to run this query.&amp;rdquo; When it fires, the engine could not satisfy an allocation. Queries that were running fine seconds ago start failing, and the failure cascades into application timeouts, retry storms, and a flood of related errors (17890, 8645).&lt;/p>
&lt;p>The error itself tells you very little. It does not say whether the buffer pool is starved, whether a single query is hoarding a memory grant, whether an Extended Events ring buffer has eaten 50 GB, or whether the OS is reclaiming memory from a VM balloon driver. Investigate by source.&lt;/p></description></item><item><title>SQL Server Error 823 and 824: I/O and logical consistency errors</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-823-824-io-errors/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-823-824-io-errors/</guid><description>&lt;p>Errors 823 and 824 are SQL Server&amp;rsquo;s severity-24 storage integrity alarms. 823 means the operating system reported a hard failure on a file API call. 824 means the call succeeded but the page failed an internal integrity check. Both are PAGE-worthy the moment they appear; they do not self-resolve, and continued use of the affected files risks losing data that was fine minutes earlier.&lt;/p>
&lt;p>Error 825 is the soft warning that usually precedes both: SQL Server retried a read that initially failed and eventually succeeded. The query did not fail and no connection was killed, which is why most teams do not alert on it. It is also the most reliable predictor that an 823 or 824 is coming.&lt;/p></description></item><item><title>SQL Server Error 825: read-retry succeeded and the disk is failing</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-825-read-retry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-825-read-retry/</guid><description>&lt;h1 id="sql-server-error-825-read-retry-succeeded-and-the-disk-is-failing">SQL Server Error 825: read-retry succeeded and the disk is failing&lt;/h1>
&lt;p>Error 825 is what SQL Server writes to the error log when a disk read failed on the first attempt but succeeded on a retry (attempt 2, 3, or 4). The query completes. The application sees no failure. But the storage underneath just told you it is failing.&lt;/p>
&lt;p>Most monitoring setups never surface Error 825. It is a severity-10 informational message, and typical SQL Server Agent alert configurations target severity 19 and above. The error sits quietly in the log until something harder arrives: an 823 (hard I/O error) or an 824 (logical consistency error). By then the page may already be unreadable.&lt;/p></description></item><item><title>SQL Server Error 9002: the transaction log for the database is full</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-9002-transaction-log-full/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-error-9002-transaction-log-full/</guid><description>&lt;h1 id="sql-server-error-9002-the-transaction-log-for-the-database-is-full">SQL Server Error 9002: the transaction log for the database is full&lt;/h1>
&lt;p>Your application is throwing write failures and the SQL Server error log shows: &amp;ldquo;The transaction log for database &amp;lsquo;X&amp;rsquo; is full due to &amp;lsquo;LOG_BACKUP&amp;rsquo;&amp;rdquo; (or ACTIVE_TRANSACTION, AVAILABILITY_REPLICA, REPLICATION, or another reason in quotes). Every INSERT, UPDATE, and DELETE against that database now fails with error 9002. Read-only queries may still work, which makes the outage look confusingly partial from the outside.&lt;/p></description></item><item><title>SQL Server failed login storm: brute force, credential drift, and service-account failures</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-failed-login-storm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-failed-login-storm/</guid><description>&lt;h1 id="sql-server-failed-login-storm-brute-force-credential-drift-and-service-account-failures">SQL Server failed login storm: brute force, credential drift, and service-account failures&lt;/h1>
&lt;p>A failed-login storm fills ERRORLOG with &amp;ldquo;Login failed for user&amp;rdquo; entries (Error 18456). Counting them is the first instinct and the wrong one. Aggregate rate cannot tell brute force from a batch job running on rotated secrets, a service account whose password just expired, an application pool recycling, or &lt;!-- TODO: verify --> a SQL Server 2025 replication secondary emitting benign noise every few minutes.&lt;/p></description></item><item><title>SQL Server HADR_SYNC_COMMIT waits: a synchronous secondary throttling primary commits</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-hadr-sync-commit-waits/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-hadr-sync-commit-waits/</guid><description>&lt;h1 id="sql-server-hadr_sync_commit-waits-a-synchronous-secondary-throttling-primary-commits">SQL Server HADR_SYNC_COMMIT waits: a synchronous secondary throttling primary commits&lt;/h1>
&lt;p>HADR_SYNC_COMMIT at the top of your wait statistics is a counterintuitive failure. The primary replica looks idle: CPU is low, local I/O is fast, batch requests look normal. Yet every write transaction stalls. The cause is not on the primary but on the synchronous secondary, the network between replicas, or the AG transport itself.&lt;/p>
&lt;p>In synchronous-commit mode, the primary cannot acknowledge a transaction commit until the secondary hardens the log record to disk. Every write transaction pays that round-trip tax. When the secondary or the path to it degrades, that tax becomes seconds of latency per commit. Under sustained write load, the delays lengthen lock hold times on the primary and cascade into blocking, worker thread growth, and eventually THREADPOOL waits. The application experiences this as a general slowdown, but the root cause is a single replica that cannot keep up.&lt;/p></description></item><item><title>SQL Server high compilations per second: plan cache pollution and CPU burn</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-high-compilations-per-second/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-high-compilations-per-second/</guid><description>&lt;h1 id="sql-server-high-compilations-per-second-plan-cache-pollution-and-cpu-burn">SQL Server high compilations per second: plan cache pollution and CPU burn&lt;/h1>
&lt;p>SQL Compilations/sec is climbing, CPU is pinned, and the application is reporting latency even though storage and locking look clean. Nothing is &amp;ldquo;broken&amp;rdquo; in the error log, but the engine is spending a large share of its CPU budget turning query text into execution plans instead of executing them.&lt;/p>
&lt;p>Compilation is expensive. Every new plan costs parse, optimization, and often a compile-time memory grant. When the ratio of SQL Compilations/sec to Batch Requests/sec climbs past roughly 10%, the plan cache is failing to do its job. Sustained above 20% with CPU pressure, you have an active problem.&lt;/p></description></item><item><title>SQL Server high recompilations: stale statistics and schema changes churning plans</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-high-recompilations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-high-recompilations/</guid><description>&lt;h1 id="sql-server-high-recompilations-stale-statistics-and-schema-changes-churning-plans">SQL Server high recompilations: stale statistics and schema changes churning plans&lt;/h1>
&lt;p>CPU is climbing, &lt;code>SOS_SCHEDULER_YIELD&lt;/code> is creeping up, batch requests look normal, and your top waits are not obviously I/O or lock related. Check the SQL Statistics counters: if &lt;code>SQL Re-Compilations/sec&lt;/code> is running well above 10% of &lt;code>SQL Compilations/sec&lt;/code>, you have a plan stability problem, not a plan cache efficiency problem.&lt;/p>
&lt;p>Recompilations are not the same as first-time compilations. First-time compilations (or recompilations forced by plan cache eviction under memory pressure) belong in &lt;a href="https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-high-compilations-per-second/">SQL Server high compilations per second&lt;/a>. Recompilations mean SQL Server had a cached plan, decided it could no longer trust it, and spent CPU rebuilding it. Each recompile is CPU work, and if the recompiling statement sits inside a multi-statement batch or stored procedure, the cost cascades across dependent statements.&lt;/p></description></item><item><title>SQL Server high VLF count: transaction log fragmentation that slows recovery</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-vlf-count-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-vlf-count-high/</guid><description>&lt;h1 id="sql-server-high-vlf-count-transaction-log-fragmentation-that-slows-recovery">SQL Server high VLF count: transaction log fragmentation that slows recovery&lt;/h1>
&lt;p>A database restarts and takes 45 minutes to come back ONLINE. An AlwaysOn failover completes in seconds, but the new primary sits in RECOVERING for an hour while the redo queue drains. The error log shows nothing obviously wrong: no 823 or 824, no corruption, no missing files. CPU and I/O during recovery look modest, just stretched out. Users escalate.&lt;/p></description></item><item><title>SQL Server I/O stall high: per-file storage latency from dm_io_virtual_file_stats</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-io-stall-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-io-stall-high/</guid><description>&lt;h1 id="sql-server-io-stall-high-per-file-storage-latency-from-dm_io_virtual_file_stats">SQL Server I/O stall high: per-file storage latency from dm_io_virtual_file_stats&lt;/h1>
&lt;p>When &lt;code>PAGEIOLATCH_*&lt;/code> or &lt;code>WRITELOG&lt;/code> climbs to the top of &lt;code>sys.dm_os_wait_stats&lt;/code>, the question is whether storage is the bottleneck or whether SQL Server is doing too much physical I/O because the buffer pool is undersized. &lt;code>sys.dm_io_virtual_file_stats(NULL, NULL)&lt;/code> is the only DMV that answers this at file granularity from inside the engine.&lt;/p>
&lt;p>The values it returns are cumulative since the SQL Server service last started, so a single snapshot is almost useless. Compute deltas over a short window (15-60 seconds during the incident) and divide stall time by operation count to get current per-file latency. Lifetime averages on a long-running instance hide the bad minutes that matter.&lt;/p></description></item><item><title>SQL Server instance down: no response on port 1433 and where to look first</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-instance-down/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-instance-down/</guid><description>&lt;h1 id="sql-server-instance-down-no-response-on-port-1433-and-where-to-look-first">SQL Server instance down: no response on port 1433 and where to look first&lt;/h1>
&lt;p>Your availability probe just fired: TCP connect plus &lt;code>SELECT 1&lt;/code> against port 1433 has failed three or more times over at least 60 seconds. Before you restart anything, separate the two failure modes that get lumped together as &amp;ldquo;SQL Server is down&amp;rdquo;. They have different causes, different fixes, and different blast radii.&lt;/p>
&lt;p>Mode one: no TCP connect at all. The listener is not accepting connections on 1433 (or the named instance&amp;rsquo;s dynamic port). The service is stopped, the host is down, the network path is broken, or the listener is misconfigured, commonly after an AlwaysOn failover. The engine is not there to talk to.&lt;/p></description></item><item><title>SQL Server LCK_M waits high: lock contention and what the suffixes mean</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-lck-m-waits-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-lck-m-waits-high/</guid><description>&lt;h1 id="sql-server-lck_m-waits-high-lock-contention-and-what-the-suffixes-mean">SQL Server LCK_M waits high: lock contention and what the suffixes mean&lt;/h1>
&lt;p>When LCK_M_* wait types dominate &lt;code>sys.dm_os_wait_stats&lt;/code>, worker threads are suspended waiting for locks instead of doing work. The prefix is uniform; the suffix is the lock mode the waiter requested, and it is the diagnostic signal. &lt;code>LCK_M_S&lt;/code> means a reader is blocked. &lt;code>LCK_M_IX&lt;/code> means an intent-exclusive writer is queued behind a conflicting holder. &lt;code>LCK_M_SCH_M&lt;/code> is a DDL operation waiting on schema modification. The mode narrows the suspect list immediately.&lt;/p></description></item><item><title>SQL Server lock escalation: when row locks become a table lock and block everyone</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-lock-escalation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-lock-escalation/</guid><description>&lt;h1 id="sql-server-lock-escalation-when-row-locks-become-a-table-lock-and-block-everyone">SQL Server lock escalation: when row locks become a table lock and block everyone&lt;/h1>
&lt;p>A batch UPDATE or DELETE runs longer than usual. CPU looks fine, I/O looks fine, and then dozens of sessions start waiting on &lt;code>LCK_M_*&lt;/code> waits, all blocked by the batch session. By the time you log in, the worker thread pool is draining and the instance is heading toward &lt;code>THREADPOOL&lt;/code>. The root cause is not a hung transaction or a resource bottleneck. It is lock escalation: SQL Server traded thousands of row locks for a single table lock, and every other session that wants to touch that table is now serialized behind it.&lt;/p></description></item><item><title>SQL Server log autogrow stall: why every write pauses while the log file grows</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-autogrow-stall/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-autogrow-stall/</guid><description>&lt;h1 id="sql-server-log-autogrow-stall-why-every-write-pauses-while-the-log-file-grows">SQL Server log autogrow stall: why every write pauses while the log file grows&lt;/h1>
&lt;p>Applications report periodic, mysterious write stalls. Throughput drops briefly, then recovers. Repeat. The transaction log on the affected database is creeping upward, and there are no alarms on disk space. What you are seeing is almost certainly log autogrow stall: every write transaction in the database pauses while SQL Server expands and zero-initializes the transaction log file.&lt;/p></description></item><item><title>SQL Server log backups missing: the full-recovery log that grows forever</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-backup-chain-broken/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-backup-chain-broken/</guid><description>&lt;h1 id="sql-server-log-backups-missing-the-full-recovery-log-that-grows-forever">SQL Server log backups missing: the full-recovery log that grows forever&lt;/h1>
&lt;p>The application starts throwing write errors. The database is online, reads work, but every INSERT, UPDATE, and DELETE fails with error 9002: the transaction log is full. The log volume is at zero free space, or the log file has auto-grown to many times the size of the data files. When you ask when the last log backup ran, nobody knows.&lt;/p></description></item><item><title>SQL Server log_reuse_wait_desc: why the transaction log will not truncate</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-reuse-wait-desc/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-reuse-wait-desc/</guid><description>&lt;h1 id="sql-server-log_reuse_wait_desc-why-the-transaction-log-will-not-truncate">SQL Server log_reuse_wait_desc: why the transaction log will not truncate&lt;/h1>
&lt;p>The database is throwing error 9002, writes are failing, the log file has eaten the volume, and someone is about to add another log file or shrink the existing one. Before anyone touches file sizes, run one query:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> name, recovery_model_desc, log_reuse_wait_desc
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> sys.databases;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That third column is the root-cause field most teams skip. It tells you why log truncation could not clear any Virtual Log Files (VLFs) the last time SQL Server tried. Every fix for a full log flows from this value. Adding disk space without reading it treats the symptom: the log fills again, usually within hours, and now you also have VLF fragmentation to deal with.&lt;/p></description></item><item><title>SQL Server max server memory: setting it so the OS and buffer pool both survive</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-max-server-memory-configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-max-server-memory-configuration/</guid><description>&lt;h1 id="sql-server-max-server-memory-setting-it-so-the-os-and-buffer-pool-both-survive">SQL Server max server memory: setting it so the OS and buffer pool both survive&lt;/h1>
&lt;p>SQL Server is built to consume memory until something stops it. On a dedicated box with no cap, the engine will eat nearly all physical RAM for the buffer pool and keep going until the OS pushes back. That is not a leak; it is the design. &lt;code>max server memory&lt;/code> is the one knob that turns that behavior into something safe to run next to other processes.&lt;/p></description></item><item><title>SQL Server Memory Grants Pending above zero: queries queued before they can run</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-memory-grants-pending/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-memory-grants-pending/</guid><description>&lt;h1 id="sql-server-memory-grants-pending-above-zero-queries-queued-before-they-can-run">SQL Server Memory Grants Pending above zero: queries queued before they can run&lt;/h1>
&lt;p>Memory Grants Pending is a SQLServer:Memory Manager counter that should almost always be zero. When it rises above zero, queries are fully parsed and optimized but cannot start execution because the query workspace memory pool is exhausted. Applications see queries that appear hung: connections stay open, latency climbs, and CPU and I/O may look idle.&lt;/p>
&lt;p>The counter pairs with the RESOURCE_SEMAPHORE wait type. The counter shows how many queries are queued right now. The wait type aggregates how long they spent in that queue. Both point at the same bottleneck: SQL Server cannot honor a memory grant request because the workspace memory pool has been drained by other queries, by one oversized grant from a bad plan, or by external OS pressure on max server memory.&lt;/p></description></item><item><title>SQL Server memory pressure spiral: PLE collapse, physical reads, and I/O saturation</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-memory-pressure-spiral/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-memory-pressure-spiral/</guid><description>&lt;h1 id="sql-server-memory-pressure-spiral-ple-collapse-physical-reads-and-io-saturation">SQL Server memory pressure spiral: PLE collapse, physical reads, and I/O saturation&lt;/h1>
&lt;p>The signature of a memory pressure spiral is a rapid Page Life Expectancy (PLE) drop combined with rising &lt;code>PAGEIOLATCH_*&lt;/code> waits and increasing I/O stall on data files. CPU sits low to moderate because the bottleneck is not compute. It is the buffer pool being drained, which forces physical reads, which saturate the storage path, which makes every query slower, which piles up more concurrent sessions, which pressures memory further.&lt;/p></description></item><item><title>SQL Server Page Life Expectancy dropping: the buffer pool under memory pressure</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-page-life-expectancy-dropping/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-page-life-expectancy-dropping/</guid><description>&lt;h1 id="sql-server-page-life-expectancy-dropping-the-buffer-pool-under-memory-pressure">SQL Server Page Life Expectancy dropping: the buffer pool under memory pressure&lt;/h1>
&lt;p>Page Life Expectancy (PLE) measures the expected seconds a data page stays in the buffer pool before eviction. A sharp drop means the lazy writer is flushing pages faster than the workload can reuse them, and queries that previously hit cache now trigger physical reads.&lt;/p>
&lt;p>The signature of a real pressure event is a 50%+ drop from baseline coinciding with rising &lt;code>PAGEIOLATCH_*&lt;/code> waits and a falling buffer cache hit ratio. The old &amp;ldquo;300 seconds&amp;rdquo; rule is obsolete: it was calibrated for 32-bit servers with ~4GB buffer pools. On a modern instance with 256GB of memory, PLE above 100,000 seconds is normal, and 300 seconds would be a crisis.&lt;/p></description></item><item><title>SQL Server PAGEIOLATCH waits: the buffer pool waiting on slow storage</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-pageiolatch-waits/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-pageiolatch-waits/</guid><description>&lt;h1 id="sql-server-pageiolatch-waits-the-buffer-pool-waiting-on-slow-storage">SQL Server PAGEIOLATCH waits: the buffer pool waiting on slow storage&lt;/h1>
&lt;p>Your top wait type is &lt;code>PAGEIOLATCH_SH&lt;/code> or &lt;code>PAGEIOLATCH_EX&lt;/code>. Queries that used to be sub-50ms now take seconds. CPU may be low. There are no blocking chains. The buffer pool is waiting on disk.&lt;/p>
&lt;p>PAGEIOLATCH waits are the direct fingerprint of physical I/O. A worker needs an 8KB data page that is not in the buffer pool, takes an in-memory latch on the buffer descriptor, and waits for storage to return the page. When the read completes, the worker continues. Sustained PAGEIOLATCH time means the engine is spending wall-clock time waiting on disk.&lt;/p></description></item><item><title>SQL Server parameter sniffing: a good plan for one value, catastrophic for the next</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-parameter-sniffing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-parameter-sniffing/</guid><description>&lt;h1 id="sql-server-parameter-sniffing-a-good-plan-for-one-value-catastrophic-for-the-next">SQL Server parameter sniffing: a good plan for one value, catastrophic for the next&lt;/h1>
&lt;p>A stored procedure that ran in 30 ms for weeks is now taking 8 seconds per call. Query text unchanged. Indexes unchanged. Statistics look fine. The application is timing out. The same query with literal values returns instantly. With &lt;code>OPTION (RECOMPILE)&lt;/code> appended, it returns instantly. The cached plan is the problem.&lt;/p>
&lt;p>This is parameter sniffing. The optimizer compiled the plan for the parameter values it saw first, cached the result, and every subsequent call reuses a plan that is wrong for the values it is now processing. On a table with skewed data, a plan sized for 12 rows is catastrophic when fed 12 million.&lt;/p></description></item><item><title>SQL Server plan cache bloat: single-use ad-hoc plans wasting memory</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-plan-cache-bloat/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-plan-cache-bloat/</guid><description>&lt;h1 id="sql-server-plan-cache-bloat-single-use-ad-hoc-plans-wasting-memory">SQL Server plan cache bloat: single-use ad-hoc plans wasting memory&lt;/h1>
&lt;p>SQL Server plan cache bloat from single-use ad-hoc plans is a slow degradation. Queries return correct results. The instance stays up. But memory that should cache hot data pages holds thousands of compiled plans that will never execute again. Operators typically discover it when PLE drifts down for no obvious reason, when buffer cache hit ratio slips, or when compilations per second stays elevated relative to batch requests. By the time it surfaces in user-facing latency, the plan cache has been stealing buffer pool memory for weeks.&lt;/p></description></item><item><title>SQL Server RESOURCE_SEMAPHORE waits: queries stuck waiting for a memory grant</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-resource-semaphore-waits/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-resource-semaphore-waits/</guid><description>&lt;h1 id="sql-server-resource_semaphore-waits-queries-stuck-waiting-for-a-memory-grant">SQL Server RESOURCE_SEMAPHORE waits: queries stuck waiting for a memory grant&lt;/h1>
&lt;p>RESOURCE_SEMAPHORE is the wait type SQL Server records when a worker thread cannot get a query memory grant. Before a query runs a sort, hash, or certain joins, the optimizer estimates how much workspace memory it needs and asks the grant pool for it. When the pool is exhausted, parsed-and-optimized queries sit in a queue. To the application they look hung.&lt;/p></description></item><item><title>SQL Server restore readiness: why a backup you never test is not a backup</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-restore-readiness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-restore-readiness/</guid><description>&lt;h1 id="sql-server-restore-readiness-why-a-backup-you-never-test-is-not-a-backup">SQL Server restore readiness: why a backup you never test is not a backup&lt;/h1>
&lt;p>The most common SQL Server backup monitoring answers one question: did the job succeed? A green checkmark means SQL Server wrote bytes to a file. It does not mean those bytes can be read back, decrypted, applied through a recovery sequence, and brought online within your RTO.&lt;/p>
&lt;p>The gap between &amp;ldquo;backup succeeded&amp;rdquo; and &amp;ldquo;we can recover&amp;rdquo; is where most DR failures actually live. Backups fail to restore because of media corruption the backup job never validated, because a TDE or backup-encryption certificate was not backed up alongside the data, because an ad-hoc operation broke the log chain and silently invalidated hours of log backups, or because the restore takes four times longer than anyone measured. None of those surface in backup-completion monitoring.&lt;/p></description></item><item><title>SQL Server runnable tasks backlog: the in-engine CPU queue OS metrics miss</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-runnable-tasks-backlog/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-runnable-tasks-backlog/</guid><description>&lt;h1 id="sql-server-runnable-tasks-backlog-the-in-engine-cpu-queue-os-metrics-miss">SQL Server runnable tasks backlog: the in-engine CPU queue OS metrics miss&lt;/h1>
&lt;p>Your monitoring says the host is at 45% CPU. Users say the database is slow. Both are right, because SQL Server does not use the OS scheduler for query execution. It runs its own cooperative scheduling layer, SQLOS, with one scheduler per logical CPU, its own run queues, and its own worker thread pool. OS CPU percent measures what the host kernel sees. It does not see tasks sitting in SQLOS queues waiting for a scheduler slot, and on virtualized hosts it does not see time the hypervisor stole from the guest.&lt;/p></description></item><item><title>SQL Server sleeping head blocker: the idle session holding a lock and an open transaction</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-sleeping-head-blocker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-sleeping-head-blocker/</guid><description>&lt;h1 id="sql-server-sleeping-head-blocker-the-idle-session-holding-a-lock-and-an-open-transaction">SQL Server sleeping head blocker: the idle session holding a lock and an open transaction&lt;/h1>
&lt;p>The most dangerous blocking shape in SQL Server does not look active. Sessions pile up behind a head blocker, batch requests stall, and transactions per second drop. CPU and I/O are idle. The engine looks healthy on resource metrics, but queries are timing out.&lt;/p>
&lt;p>When you query &lt;code>sys.dm_exec_requests&lt;/code> for the blocker, you find nothing. The &lt;code>session_id&lt;/code> that everyone is waiting on does not appear in the requests DMV because the head blocker has no active request. It is sleeping. It is, however, holding locks under an open transaction that never committed, never rolled back, and never will on its own.&lt;/p></description></item><item><title>SQL Server SOS_SCHEDULER_YIELD waits: CPU scheduler pressure explained</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-sos-scheduler-yield-waits/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-sos-scheduler-yield-waits/</guid><description>&lt;h1 id="sql-server-sos_scheduler_yield-waits-cpu-scheduler-pressure-explained">SQL Server SOS_SCHEDULER_YIELD waits: CPU scheduler pressure explained&lt;/h1>
&lt;p>When SOS_SCHEDULER_YIELD dominates &lt;code>sys.dm_os_wait_stats&lt;/code>, the reflex is to assume CPU pressure and start hunting for bad queries. That reflex is right about half the time. The other half, you are chasing a signal that is doing exactly what it was designed to do: recording every time a worker voluntarily yielded its 4ms quantum because other runnable workers were queued.&lt;/p>
&lt;p>The wait type has existed in SQL Server since the SQLOS era and the 4ms quantum is fixed in every version. It cannot be tuned. What you can tune is your interpretation. A workload doing efficient set-based scans of pages already in memory will yield constantly and rack up enormous SOS_SCHEDULER_YIELD numbers without anything being wrong. A VM on an oversubscribed host reports the same wait type while the hypervisor silently steals CPU cycles SQL Server cannot see.&lt;/p></description></item><item><title>SQL Server suspect_pages: the durable record of storage corruption</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-suspect-pages/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-suspect-pages/</guid><description>&lt;h1 id="sql-server-suspect_pages-the-durable-record-of-storage-corruption">SQL Server suspect_pages: the durable record of storage corruption&lt;/h1>
&lt;p>The SQL Server error log recycles on every service restart, and by default only six archived logs are retained. When a storage fault produces errors 823, 824, or torn-page detection, the entries that document it may be gone before anyone investigates. &lt;code>msdb.dbo.suspect_pages&lt;/code> is where those events also land, and unlike the error log it survives restarts. Treat it as the durable forensic record of page-level I/O corruption on the instance.&lt;/p></description></item><item><title>SQL Server TDE and endpoint certificate expiry: silent AG and backup failures</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tde-certificate-expiry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tde-certificate-expiry/</guid><description>&lt;p>SQL Server does not alert when a certificate is about to expire. There is no performance counter, no error log entry at expiry time, and no DMV flag that flips the moment the date passes. The engine keeps using the certificate silently until something forces a re-evaluation, and at that point the failure mode depends entirely on what the certificate was protecting.&lt;/p>
&lt;p>Three consumers of the same self-signed certificate pattern behave in three different ways:&lt;/p></description></item><item><title>SQL Server TempDB file configuration: one data file per CPU and why it matters</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-file-configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-file-configuration/</guid><description>&lt;h1 id="sql-server-tempdb-file-configuration-one-data-file-per-cpu-and-why-it-matters">SQL Server TempDB file configuration: one data file per CPU and why it matters&lt;/h1>
&lt;p>TempDB is the shared scratchpad every database on a SQL Server instance writes to. Temp tables, table variables, sort and hash spills, row version stores for RCSI and AlwaysOn readable secondaries, and internal worktables all land here. When TempDB serializes, every database on the instance serializes with it. The most common serialization point is not space or I/O. It is logical latch contention on a handful of allocation bitmap pages.&lt;/p></description></item><item><title>SQL Server TempDB full: the shared scratch database that halts every query</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-full/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-full/</guid><description>&lt;h1 id="sql-server-tempdb-full-the-shared-scratch-database-that-halts-every-query">SQL Server TempDB full: the shared scratch database that halts every query&lt;/h1>
&lt;p>Applications start failing with error 1105 (&amp;ldquo;could not allocate space for object in database &amp;rsquo;tempdb&amp;rsquo; because the &amp;lsquo;PRIMARY&amp;rsquo; filegroup is full&amp;rdquo;) or error 3958, and the failures are not limited to one database. Every query on the instance that needs a temp table, a sort or hash spill, a worktable, or a row version touches TempDB. When TempDB cannot allocate space, all of them fail at once.&lt;/p></description></item><item><title>SQL Server TempDB PAGELATCH contention: allocation page latch waits on PFS, GAM, and SGAM</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-pagelatch-contention/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-pagelatch-contention/</guid><description>&lt;h1 id="sql-server-tempdb-pagelatch-contention-allocation-page-latch-waits-on-pfs-gam-and-sgam">SQL Server TempDB PAGELATCH contention: allocation page latch waits on PFS, GAM, and SGAM&lt;/h1>
&lt;p>CPU is moderate, I/O latency is normal, the buffer pool is healthy, and throughput has dropped. Wait statistics show PAGELATCH_UP or PAGELATCH_EX dominating, and &lt;code>sys.dm_os_waiting_tasks&lt;/code> shows sessions waiting on pages like &lt;code>2:1:1&lt;/code>, &lt;code>2:1:2&lt;/code>, or &lt;code>2:1:3&lt;/code>.&lt;/p>
&lt;p>This is TempDB allocation page latch contention. Every temp table, spilled sort, or worktable allocation needs space in TempDB. SQL Server tracks free space and allocation state in bitmap pages: PFS (Page Free Space), GAM (Global Allocation Map), and SGAM (Shared Global Allocation Map). When sessions contend for the same allocation pages, they serialize on in-memory latches. Disk and CPU are not the bottleneck. The problem is logical contention on a fixed set of pages in the buffer pool.&lt;/p></description></item><item><title>SQL Server TempDB version store growth: long transactions under RCSI and snapshot isolation</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-version-store-growth/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-tempdb-version-store-growth/</guid><description>&lt;h1 id="sql-server-tempdb-version-store-growth-long-transactions-under-rcsi-and-snapshot-isolation">SQL Server TempDB version store growth: long transactions under RCSI and snapshot isolation&lt;/h1>
&lt;p>TempDB is filling and the version store is the consumer. You query &lt;code>tempdb.sys.dm_db_file_space_usage&lt;/code> and &lt;code>version_store_reserved_page_count&lt;/code> dominates the page budget, often after enabling Read Committed Snapshot Isolation (RCSI) or snapshot isolation, after turning a secondary replica into a readable one, or during an online index operation. Queries that depend on TempDB (sorts, hashes, temp tables, even row-versioned reads on secondaries) stall or fail when the volume runs out.&lt;/p></description></item><item><title>SQL Server THREADPOOL waits: worker thread exhaustion and refused connections</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-threadpool-waits/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-threadpool-waits/</guid><description>&lt;h1 id="sql-server-threadpool-waits-worker-thread-exhaustion-and-refused-connections">SQL Server THREADPOOL waits: worker thread exhaustion and refused connections&lt;/h1>
&lt;p>Your monitoring says the SQL Server host is fine: CPU at 15%, disk latency normal, memory steady. But the application is timing out, new connections hang, and the instance might as well be down. When you finally get in, the wait stats tell the story: THREADPOOL.&lt;/p>
&lt;p>THREADPOOL means every worker thread in the SQLOS pool is busy, and new requests are queuing for a thread that does not exist. From the client&amp;rsquo;s perspective this is equivalent to connection refusal. The server is not slow. It is not accepting work at all.&lt;/p></description></item><item><title>SQL Server transaction log percent used climbing toward full</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-space-used-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-log-space-used-high/</guid><description>&lt;h1 id="sql-server-transaction-log-percent-used-climbing-toward-full">SQL Server transaction log percent used climbing toward full&lt;/h1>
&lt;p>The &lt;code>Percent Log Used&lt;/code> counter on one of your databases is climbing and it is not coming back down. This is the leading gauge before Error 9002 (&amp;ldquo;The transaction log for database &amp;lsquo;X&amp;rsquo; is full&amp;rdquo;), at which point every write against that database fails. Reads may still work, which makes the outage look strange from the application side: queries succeed, inserts and updates throw errors.&lt;/p></description></item><item><title>SQL Server user connections climbing: connection pool leaks and retry storms</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-connection-count-climbing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-connection-count-climbing/</guid><description>&lt;h1 id="sql-server-user-connections-climbing-connection-pool-leaks-and-retry-storms">SQL Server user connections climbing: connection pool leaks and retry storms&lt;/h1>
&lt;p>A rising &lt;code>User Connections&lt;/code> counter is easy to misread. It does not mean that many queries are running. Most application connections are pooled and idle, so the count can climb for hours while CPU, I/O, and batch rate look almost normal.&lt;/p>
&lt;p>The useful split is shape and correlation. A slow upward trend without a matching rise in &lt;code>Batch Requests/sec&lt;/code> usually points to an application-tier connection pool leak or pool fragmentation. A sudden spike, especially after transient errors, points to a retry storm or a burst of new application instances. The dangerous endpoint is the same: enough concurrent active work consumes worker threads until new requests queue on &lt;code>THREADPOOL&lt;/code>, which is effectively connection refusal.&lt;/p></description></item><item><title>SQL Server wait statistics: reading sys.dm_os_wait_stats to find the real bottleneck</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-wait-statistics-explained/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-wait-statistics-explained/</guid><description>&lt;h1 id="sql-server-wait-statistics-reading-sysdm_os_wait_stats-to-find-the-real-bottleneck">SQL Server wait statistics: reading sys.dm_os_wait_stats to find the real bottleneck&lt;/h1>
&lt;p>Every time a SQL Server worker thread cannot proceed, the engine records what it was waiting for and for how long. The cumulative result lives in &lt;code>sys.dm_os_wait_stats&lt;/code>. When users say &amp;ldquo;the database is slow&amp;rdquo; and CPU, memory, and disk all look acceptable, wait statistics are usually where the answer is.&lt;/p>
&lt;p>The catch: the DMV is a cumulative counter since instance startup, it contains dozens of benign background waits that drown out the signal, and it tells you what the engine waited on, not which query did the waiting. Read it naively and you will chase the wrong bottleneck. Read it correctly and it decomposes performance into exactly which subsystem is contended.&lt;/p></description></item><item><title>SQL Server worker thread exhaustion: when the instance stops accepting work</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-worker-thread-exhaustion/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-worker-thread-exhaustion/</guid><description>&lt;h1 id="sql-server-worker-thread-exhaustion-when-the-instance-stops-accepting-work">SQL Server worker thread exhaustion: when the instance stops accepting work&lt;/h1>
&lt;p>The application reports that the database is down. CPU is low, disk I/O is low, memory looks fine, the sqlservr process is running. A TCP connection to port 1433 even succeeds. But queries hang, logins time out, and nothing completes. The instance is alive and refusing to work.&lt;/p>
&lt;p>This is worker thread exhaustion. Every active request in SQL Server needs a worker thread from a bounded pool. When every worker is occupied, usually suspended waiting on something, new requests cannot be scheduled at all. They queue on the THREADPOOL wait, which from the client&amp;rsquo;s perspective is indistinguishable from the server being down.&lt;/p></description></item><item><title>SQL Server WRITELOG waits: commit latency from a slow transaction log</title><link>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-writelog-waits-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/microsoft-sql-server/microsoft-sql-server-writelog-waits-high/</guid><description>&lt;h1 id="sql-server-writelog-waits-commit-latency-from-a-slow-transaction-log">SQL Server WRITELOG waits: commit latency from a slow transaction log&lt;/h1>
&lt;p>WRITELOG is the wait type SQL Server records when a worker thread blocks on a transaction log flush. Write-ahead logging requires the log block to be hardened to disk before the engine acknowledges a commit, so WRITELOG directly bounds write throughput. When it dominates your top-waits list, every write transaction is paying a latency tax at commit.&lt;/p>
&lt;p>The reported symptom is rarely &amp;ldquo;WRITELOG is high.&amp;rdquo; It is commit latency, write transaction timeouts, application retry storms, Availability Group replication lag, or batch requests/sec collapsing while CPU sits low. WRITELOG is the in-engine signature you find in &lt;code>sys.dm_os_wait_stats&lt;/code> or &lt;code>sys.dm_exec_session_wait_stats&lt;/code>. It tells you the bottleneck is in the log write path: the storage below the log file, the I/O stack between SQL Server and that storage, or the commit rate the Log Writer is being asked to service. Tuning queries will not fix it.&lt;/p></description></item></channel></rss>