MAXDOP and DOP Feedback in SQL Server 2022: The Complete Guide
Every fact in this article is sourced directly from Microsoft Learn documentation. Nothing is guessed, inferred from community posts, or carried over from older SQL Server versions without verification. Where behavior changed between versions, the change is called out explicitly with the version where it changed.
The parallelism story in SQL Server 2022 is meaningfully different from earlier versions. MAXDOP at the server level is still the starting point, but SQL Server 2022 added Degree of Parallelism (DOP) Feedback: an intelligent query processing feature that automatically adjusts parallelism per-query based on observed performance. It is disabled by default, must be enabled per-database, requires Query Store in read-write mode, and stores its decisions in Query Store so they survive SQL Server restarts. Understanding how these three layers interact is the topic of this guide.
- What MAXDOP Controls and Why the Default Is Wrong
- The Three Layers of Parallelism Control in SQL Server 2022
- Cost Threshold for Parallelism: The Setting That Works with MAXDOP
- What DOP Feedback Is and What It Is Not
- How DOP Feedback Makes Decisions: The Step-by-Step Process
- Why DOP Feedback Survives Restarts When Wait Stats Do Not
- DOP Feedback Limitations: What It Cannot Do
- Enabling DOP Feedback Per Database
- Checking DOP Feedback Decisions in sys.query_store_plan_feedback
- Extended Events for DOP Feedback
- Disabling DOP Feedback for a Specific Query
- DOP Feedback and Always On Availability Groups
1 What MAXDOP Controls and Why the Default Is Wrong Beginner
MAXDOP, Max Degree of Parallelism, is a SQL Server configuration option that sets the maximum number of processor threads that a single query can use when executing in parallel. When MAXDOP is 8, a single query can use up to 8 threads simultaneously. When MAXDOP is 1, no query can run in parallel at all. When MAXDOP is 0, SQL Server uses all available logical processors for a parallel query.
The default value after a fresh SQL Server installation is 0. According to Microsoft Learn, MAXDOP 0 allows SQL Server to use all available logical processors. On a server with 32 logical processors, a single parallel query can consume all 32 threads. If multiple parallel queries run simultaneously, the scheduler fills rapidly. This is the default that should be changed immediately after installation on any production server.
MAXDOP 0 is the installation default and is wrong for almost every production workload. According to Microsoft Learn documentation on the max degree of parallelism server configuration option, Microsoft recommends setting MAXDOP to a value appropriate for the server hardware. Leave MAXDOP at 0 only as a deliberate decision, not by omission.
What Microsoft recommends for MAXDOP
Microsoft Learn provides explicit MAXDOP recommendations based on NUMA node and logical processor count. The following is sourced directly from the official Microsoft documentation:
| Server Configuration | Microsoft Recommended MAXDOP |
|---|---|
| Single NUMA node, fewer than 8 logical processors | Set MAXDOP to the number of logical processors |
| Single NUMA node, 8 or more logical processors | Set MAXDOP to 8 |
| Multiple NUMA nodes, fewer than 8 logical processors per NUMA node | Set MAXDOP to the number of logical processors per NUMA node |
| Multiple NUMA nodes, 8 or more logical processors per NUMA node | Set MAXDOP to 8 |
The community production standard of half the logical CPU count up to 8 is consistent with Microsoft guidance for OLTP workloads. For mixed OLTP and analytical workloads, a higher MAXDOP may be appropriate. For pure OLTP where most queries are short, MAXDOP 4 or lower is common. DOP Feedback, introduced in SQL Server 2022, then adjusts downward from this ceiling per-query as needed.
2 The Three Layers of Parallelism Control in SQL Server 2022 Beginner
SQL Server 2022 has three distinct layers where parallelism can be controlled. Understanding all three and how they interact is essential before enabling DOP Feedback.
Layer 1: Server-level MAXDOP
Set with sp_configure 'max degree of parallelism'. This is the hard ceiling for all databases on the instance. No query on any database can exceed this value regardless of any other setting.
Layer 2: Database-level MAXDOP
Set with ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = N. According to Microsoft Learn, this overrides the server-level MAXDOP for queries running in that specific database. A database-level MAXDOP of 4 on a server where server-level MAXDOP is 8 means queries in that database are limited to 4 threads, while queries in other databases can still use up to 8. If set to 0 at the database level, the server-level value is used.
Layer 3: DOP Feedback (SQL Server 2022 only)
An intelligent query processing feature that automatically adjusts parallelism downward per-query based on observed performance. Operates within the ceiling set by Layers 1 and 2. Cannot increase DOP above the effective MAXDOP. Requires Query Store to be enabled and in READ_WRITE mode. Disabled by default and must be enabled per-database.
-- Check all three layers currently active on this instance
-- Run on the SQL Server instance
-- Layer 1: Server-level MAXDOP
SELECT name, value_in_use AS ServerMaxDOP
FROM sys.configurations
WHERE name = 'max degree of parallelism';
-- Layer 2: Database-level MAXDOP for all user databases
SELECT
d.name AS DatabaseName,
sc.value AS DatabaseMaxDOP,
CASE sc.value
WHEN 0 THEN 'Inherits server-level MAXDOP'
ELSE 'Database override: MAXDOP ' + CAST(sc.value AS VARCHAR)
END AS Interpretation
FROM sys.databases d
JOIN sys.database_scoped_configurations sc
ON d.database_id = CAST(sc.database_id AS INT)
WHERE d.database_id > 4
AND sc.name = 'MAXDOP'
ORDER BY d.name;
-- Layer 3: DOP Feedback status per database
SELECT
d.name AS DatabaseName,
sc.value AS DopFeedbackEnabled,
CASE sc.value
WHEN 1 THEN 'DOP Feedback: ENABLED'
WHEN 0 THEN 'DOP Feedback: DISABLED (default)'
ELSE 'Unknown'
END AS DopFeedbackStatus
FROM sys.databases d
JOIN sys.database_scoped_configurations sc
ON d.database_id = CAST(sc.database_id AS INT)
WHERE d.database_id > 4
AND sc.name = 'DOP_FEEDBACK'
ORDER BY d.name;
3 Cost Threshold for Parallelism: The Setting That Works with MAXDOP Beginner
MAXDOP controls the maximum threads per parallel query. Cost Threshold for Parallelism (CTFP) controls which queries are eligible for a parallel plan at all. These two settings work together and both must be correct before enabling DOP Feedback.
When the query optimizer estimates that a query’s cost exceeds the CTFP value, it considers generating a parallel execution plan. The default CTFP is 5. According to SQLYARD’s existing CTFP guide and the production community standard, a CTFP of 5 is nearly always wrong for production OLTP environments because the optimizer assigns an estimated cost of 5 or more to most joins against non-trivial tables, meaning almost every query becomes a candidate for a parallel plan.
Set CTFP before enabling DOP Feedback. If CTFP is left at the default of 5, queries that should run serially are going parallel unnecessarily. DOP Feedback then has to discover and correct these unnecessary parallel executions one query at a time. Setting CTFP to 35 or 50 for OLTP workloads first eliminates the unnecessary parallelism at the threshold level, giving DOP Feedback a cleaner baseline to work from.
-- Check and set Cost Threshold for Parallelism
-- Verified from Microsoft Learn sp_configure documentation
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- Check current value
EXEC sp_configure 'cost threshold for parallelism';
-- Default is 5. Community production standard for OLTP is 35-50.
-- Set to production recommendation
EXEC sp_configure 'cost threshold for parallelism', 50;
RECONFIGURE;
-- Verify
SELECT name, value_in_use
FROM sys.configurations
WHERE name = 'cost threshold for parallelism';
4 What DOP Feedback Is and What It Is Not Beginner
DOP Feedback is an Intelligent Query Processing feature introduced in SQL Server 2022. According to Microsoft Learn, it identifies parallelism inefficiencies for repeating queries based on elapsed time and waits, and lowers the degree of parallelism for those queries to improve performance.
The key word is repeating. DOP Feedback only activates on queries that run more than once. It observes multiple executions of the same query, determines whether the parallel plan is actually helping or hurting performance, and adjusts the DOP downward if parallelism is inefficient. A query that runs once never receives DOP Feedback adjustment.
What DOP Feedback is not
- DOP Feedback is not a replacement for setting MAXDOP correctly. It is an automatic fine-tuning layer on top of a properly configured MAXDOP.
- DOP Feedback does not increase DOP above the MAXDOP setting. It only adjusts downward. According to Microsoft Learn: “Stable feedback is reverified upon plan recompilation and might readjust up or down, but never higher than the MAXDOP setting including a MAXDOP hint.”
- DOP Feedback is not enabled by default. According to Microsoft Learn: “DOP Feedback is not enabled by default in SQL Server 2022 (16.x).”
- DOP Feedback is not a server-level feature. It is configured per-database.
- DOP Feedback does not work on serial queries. According to Microsoft Learn: “Minimum DOP for any query adjusted with DOP Feedback is 2. Serial executions are out of scope for DOP Feedback.”
5 How DOP Feedback Makes Decisions: The Step-by-Step Process Intermediate
The following describes exactly how DOP Feedback operates, sourced from Microsoft Learn documentation on the feature.
- A repeating query executes with a parallel plan. DOP Feedback observes the query’s elapsed time and wait statistics during execution.
- DOP Feedback identifies inefficiency. If parallelism does not appear to be helping based on elapsed time and waits, DOP Feedback marks the query as eligible for adjustment. The XEvent
dop_feedback_eligible_queryfires at this point. - DOP Feedback lowers the DOP for the next execution. The adjustment is not a recompile. The plan is not changed. The DOP for the next execution is reduced. The query runs with the lower DOP.
- DOP Feedback verifies the adjustment. If the lower DOP improves performance, the adjustment moves toward “verified” status. If it causes a regression, DOP Feedback reverts to the last known good DOP. A user-canceled query is also treated as a regression.
- Verified feedback is persisted in Query Store. Once a DOP adjustment is verified as beneficial, it is written to
sys.query_store_plan_feedbackon disk. This persistence means the adjustment survives SQL Server restarts. - Feedback is reverified on plan recompilation. If the query plan is recompiled, DOP Feedback reverifies the previous adjustment. The new DOP may adjust up or down, but never above the effective MAXDOP setting.
Verified feedback in Query Store is the critical design decision. Before SQL Server 2022, any in-memory performance adjustments were wiped on restart. DOP Feedback decisions are written to disk through Query Store. When SQL Server restarts and begins executing repeating queries, the verified DOP adjustments are already available in sys.query_store_plan_feedback and apply immediately without needing to rediscover the optimal DOP from scratch.
6 Why DOP Feedback Survives Restarts When Wait Stats Do Not Beginner
This is the question that prompted this article and the answer is precise. Understanding it requires knowing where each piece of data lives.
Wait statistics live in sys.dm_os_wait_stats. This is a Dynamic Management View backed by in-memory counters. The counters reset to zero every time SQL Server restarts. Wait statistics accumulated over weeks of production runtime are gone on the next restart. This is by design and well-documented. Wait statistics can also be manually reset with DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR).
DOP Feedback decisions live in sys.query_store_plan_feedback. This is a catalog view backed by data stored on disk as part of the Query Store. Query Store is a database-level feature that persists its data to the database files. The data in sys.query_store_plan_feedback survives SQL Server restarts because the database files it is stored in survive restarts.
The relationship is not DOP Feedback uses wait stats to make decisions and therefore is wiped on restart. DOP Feedback observes wait statistics during query execution to determine whether a DOP adjustment is beneficial, but the verified outcome of those observations is stored in Query Store, not in wait stats. The observation mechanism (wait stats) resets on restart. The outcome of the observations (verified feedback in Query Store) does not.
| Data | Where It Lives | Survives Restart? | Reset With |
|---|---|---|---|
| Wait statistics | sys.dm_os_wait_stats |
No. In-memory only. | DBCC SQLPERF or SQL Server restart |
| DOP Feedback decisions (verified) | sys.query_store_plan_feedback |
Yes. Stored in Query Store on disk. | Only if Query Store is cleared or feedback is manually removed |
| Query Store plan and runtime data | Database files | Yes. Survives restart. | ALTER DATABASE SET QUERY_STORE CLEAR or retention policy |
7 DOP Feedback Limitations: What It Cannot Do Intermediate
Every limitation listed here is confirmed from Microsoft Learn documentation as of July 2026.
- DOP Feedback is not enabled by default in SQL Server 2022. Must be explicitly enabled per-database.
- DOP Feedback requires Query Store in READ_WRITE mode. If Query Store is disabled or in READ_ONLY mode, DOP Feedback has no effect even if the database scoped configuration is set to ON.
- DOP Feedback only adjusts downward. The maximum DOP after DOP Feedback adjustment is the effective MAXDOP. DOP Feedback cannot raise a query’s DOP above that ceiling.
- DOP Feedback minimum is DOP 2. DOP Feedback will not push a query to serial execution (DOP 1). Serial execution is out of scope.
- DOP Feedback does not recompile plans. The existing plan is used. Only the DOP for the next execution changes.
- DOP Feedback is not compatible with query hints. If a query uses a MAXDOP hint (OPTION (MAXDOP N)) or other query hints, DOP Feedback does not apply to that query.
- DOP Feedback is not persisted on secondary replicas in Always On availability groups. On failover, feedback applied on the old primary is lost. Covered in detail in Section 12.
- When DOP Feedback data is cleaned up by Query Store retention policy, the feedback is also cleaned up. If Query Store auto-purges old query data, the associated DOP Feedback entries are removed with it.
8 Enabling DOP Feedback Per Database Beginner
DOP Feedback is a database-scoped configuration. It must be enabled individually for each database where it should be active. This is the section most DBAs miss: there is no server-level switch to enable DOP Feedback across all databases at once.
Prerequisites before enabling
- SQL Server 2022 (16.x) or later. DOP Feedback does not exist in earlier versions.
- Query Store must be enabled on the database and in READ_WRITE mode. According to Microsoft Learn: “Query Store must be enabled for every database where DOP Feedback is used, and in the Read write state.”
- Database compatibility level should be 160 (SQL Server 2022) for the full IQP feature set. DOP Feedback is part of Intelligent Query Processing which targets the compatibility level 160 feature set.
-- Step 1: Check Query Store status on the target database
-- DOP Feedback requires OPERATION_MODE = READ_WRITE
SELECT
name AS DatabaseName,
is_query_store_on,
actual_state_desc AS QueryStoreState
FROM sys.databases
WHERE name = 'YourDatabaseName';
-- Step 2: Enable Query Store if not already enabled
-- In SQL Server 2022, Query Store is ON by default for NEW databases
-- Databases upgraded from earlier versions may still have it OFF
ALTER DATABASE YourDatabaseName
SET QUERY_STORE = ON (
OPERATION_MODE = READ_WRITE,
QUERY_CAPTURE_MODE = AUTO,
MAX_STORAGE_SIZE_MB = 1024,
INTERVAL_LENGTH_MINUTES = 60
);
-- Step 3: Verify Query Store is in READ_WRITE mode
SELECT
name,
actual_state_desc AS QueryStoreState
FROM sys.databases
WHERE name = 'YourDatabaseName';
-- Must show READ_WRITE before proceeding
-- Step 4: Check database compatibility level
-- DOP Feedback targets SQL Server 2022 IQP feature set at level 160
SELECT name, compatibility_level
FROM sys.databases
WHERE name = 'YourDatabaseName';
-- Step 5: Enable DOP Feedback on the database
-- This is the line most DBAs do not know exists
-- Must be run in the context of the target database
USE YourDatabaseName;
ALTER DATABASE SCOPED CONFIGURATION SET DOP_FEEDBACK = ON;
-- Step 6: Verify DOP Feedback is now enabled
SELECT
name,
value AS DopFeedbackEnabled
FROM sys.database_scoped_configurations
WHERE name = 'DOP_FEEDBACK';
-- value = 1 means ON, value = 0 means OFF
-- Enable Query Store and DOP Feedback on ALL user databases at once
-- Review output carefully before executing
-- Do not enable on system databases
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
USE [' + name + N'];
ALTER DATABASE [' + name + N'] SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE, QUERY_CAPTURE_MODE = AUTO);
ALTER DATABASE SCOPED CONFIGURATION SET DOP_FEEDBACK = ON;
PRINT ''DOP Feedback enabled on: ' + name + N''';'
FROM sys.databases
WHERE database_id > 4 -- user databases only
AND state_desc = 'ONLINE'
AND is_read_only = 0;
-- Review the generated script first:
PRINT @sql;
-- Then execute when ready:
-- EXEC sp_executesql @sql;
Query Store enabled by default only for NEW databases in SQL Server 2022. According to Microsoft Learn: “Starting with SQL Server 2022 (16.x), Query Store is now enabled by default for all newly created databases.” Databases created on earlier versions and then upgraded to SQL Server 2022, or databases restored from backups created on earlier versions, do not automatically have Query Store enabled. Always verify Query Store state before relying on DOP Feedback.
9 Checking DOP Feedback Decisions in sys.query_store_plan_feedback Intermediate
According to Microsoft Learn, DOP Feedback information is tracked using the sys.query_store_plan_feedback catalog view. This view contains information about Query Store tuning via memory grant, CE, and DOP feedback combined. The feedback_type column identifies which type of feedback each row represents. DOP Feedback has feature_id = 3.
-- View all DOP Feedback decisions stored in Query Store
-- Run in the target database
SELECT
qspf.plan_id,
qspf.feature_id,
CASE qspf.feature_id
WHEN 1 THEN 'Memory Grant Feedback'
WHEN 2 THEN 'CE Feedback'
WHEN 3 THEN 'DOP Feedback'
WHEN 4 THEN 'Lock After Qualification (LAQ)'
ELSE 'Unknown'
END AS FeedbackType,
qspf.feedback_data, -- JSON containing the adjusted DOP value
qspf.state_desc, -- Tracking, Verifying, Verified, Regressed
qspf.create_time,
qspf.last_updated_time
FROM sys.query_store_plan_feedback qspf
WHERE qspf.feature_id = 3 -- DOP Feedback only
ORDER BY qspf.last_updated_time DESC;
-- Join with query text to see which queries DOP Feedback has adjusted
SELECT
qt.query_sql_text,
qspf.feedback_data,
qspf.state_desc,
qspf.last_updated_time,
-- Parse the adjusted DOP from the JSON feedback_data
JSON_VALUE(qspf.feedback_data, '$.adjustedDop') AS AdjustedDOP
FROM sys.query_store_plan_feedback qspf
JOIN sys.query_store_plan qsp ON qspf.plan_id = qsp.plan_id
JOIN sys.query_store_query qsq ON qsp.query_id = qsq.query_id
JOIN sys.query_store_query_text qt ON qsq.query_text_id = qt.query_text_id
WHERE qspf.feature_id = 3
ORDER BY qspf.last_updated_time DESC;
-- Summary: count of DOP Feedback decisions by state
SELECT
state_desc,
COUNT(*) AS FeedbackCount
FROM sys.query_store_plan_feedback
WHERE feature_id = 3
GROUP BY state_desc
ORDER BY FeedbackCount DESC;
-- State values: Tracking (observing), Verifying (testing adjustment),
-- Verified (persisted as beneficial), Regressed (reverted)
10 Extended Events for DOP Feedback Intermediate
According to Microsoft Learn, the following Extended Events are available for monitoring DOP Feedback activity:
dop_feedback_eligible_query: Fires when a query plan becomes eligible for DOP Feedback consideration.dop_feedback_provided: Fires when DOP Feedback provides a DOP adjustment to a query.dop_feedback_reverted: Fires when DOP Feedback reverts an adjustment due to a regression.dop_feedback_stabilized: Fires when DOP Feedback reaches a stable verified state for a query.dop_feedback_validation: Fires during the validation phase when DOP Feedback is testing an adjustment.
-- Extended Events session to monitor DOP Feedback activity
-- Creates a lightweight session capturing all DOP Feedback events
-- Run on the SQL Server instance (not database-specific)
CREATE EVENT SESSION [Monitor_DOP_Feedback] ON SERVER
ADD EVENT sqlserver.dop_feedback_eligible_query,
ADD EVENT sqlserver.dop_feedback_provided,
ADD EVENT sqlserver.dop_feedback_reverted,
ADD EVENT sqlserver.dop_feedback_stabilized,
ADD EVENT sqlserver.dop_feedback_validation
ADD TARGET package0.ring_buffer
(
SET max_memory = 10240 -- 10 MB ring buffer
)
WITH
(
MAX_DISPATCH_LATENCY = 5 SECONDS,
TRACK_CAUSALITY = OFF
);
-- Start the session
ALTER EVENT SESSION [Monitor_DOP_Feedback] ON SERVER STATE = START;
-- Query the ring buffer for DOP Feedback events
SELECT
event_data.value('(event/@name)[1]', 'NVARCHAR(128)') AS EventName,
event_data.value('(event/@timestamp)[1]', 'DATETIME2') AS EventTime,
event_data.value('(event/data[@name="database_id"]/value)[1]', 'INT') AS DatabaseID,
event_data.value('(event/data[@name="query_id"]/value)[1]', 'BIGINT') AS QueryID,
event_data.value('(event/data[@name="plan_id"]/value)[1]', 'BIGINT') AS PlanID
FROM
(
SELECT CAST(target_data AS XML) AS rb
FROM sys.dm_xe_sessions s
JOIN sys.dm_xe_session_targets t ON s.address = t.event_session_address
WHERE s.name = 'Monitor_DOP_Feedback'
AND t.target_name = 'ring_buffer'
) AS x
CROSS APPLY rb.nodes('//RingBufferTarget/event') AS ev(event_data)
ORDER BY EventTime DESC;
-- Stop and drop when monitoring is complete
-- ALTER EVENT SESSION [Monitor_DOP_Feedback] ON SERVER STATE = STOP;
-- DROP EVENT SESSION [Monitor_DOP_Feedback] ON SERVER;
11 Disabling DOP Feedback for a Specific Query Intermediate
According to Microsoft Learn, DOP Feedback can be disabled at the query level using the DISABLE_DOP_FEEDBACK query hint. This is useful when a specific query should not be subject to automatic DOP adjustment, for example a known analytical query that should always run with the maximum available DOP regardless of what DOP Feedback observes.
-- Disable DOP Feedback for a specific query using OPTION hint
SELECT
CustomerID,
SUM(TotalAmount) AS Revenue,
COUNT(OrderID) AS OrderCount
FROM dbo.Orders
WHERE OrderDate >= '2026-01-01'
GROUP BY CustomerID
ORDER BY Revenue DESC
OPTION (DISABLE_DOP_FEEDBACK); -- DOP Feedback will not adjust this query
-- Disable DOP Feedback at the database level
-- Use this to turn off DOP Feedback on a specific database
-- without affecting other databases on the instance
USE YourDatabaseName;
ALTER DATABASE SCOPED CONFIGURATION SET DOP_FEEDBACK = OFF;
-- Verify the change
SELECT name, value FROM sys.database_scoped_configurations WHERE name = 'DOP_FEEDBACK';
12 DOP Feedback and Always On Availability Groups Advanced
The following behavior is confirmed from Microsoft Learn documentation for SQL Server 2022 with Query Store for secondary replicas enabled.
DOP Feedback is replica-aware when Query Store for secondary replicas is enabled. This means DOP Feedback can apply different DOP adjustments on the primary replica and on secondary replicas, because the same query may execute with different parallelism characteristics on each replica depending on hardware, workload, and resource availability.
DOP Feedback is NOT persisted on secondary replicas. According to Microsoft Learn: “DOP Feedback is not persisted on secondary replicas, and on failover, the DOP feedback from the old primary replica is not applied to the new primary replica. On failover, feedback applied to primary or secondary replicas is lost.” This means after a failover, the new primary starts with no DOP Feedback history and must rediscover optimal DOP adjustments for all repeating queries from scratch.
13 The Complete SQL Server 2022 Parallelism Configuration Checklist Beginner
Apply these steps in order on each SQL Server 2022 instance and database. Each step is required before the next one is effective.
- Set server-level MAXDOP (sp_configure). Start here on every instance. Use Microsoft’s documented guidelines: 8 for servers with 8 or more logical processors per NUMA node. Adjust downward for pure OLTP. This is the ceiling for all parallelism on the instance.
- Set Cost Threshold for Parallelism to 35 or 50 for OLTP. Eliminates unnecessary parallelism at the threshold level before DOP Feedback needs to intervene. The default of 5 is wrong for production OLTP.
- Enable Query Store on each database in READ_WRITE mode. Required for DOP Feedback. New databases in SQL Server 2022 have Query Store ON by default. Upgraded or restored databases may not.
-
Enable DOP Feedback per database.
ALTER DATABASE SCOPED CONFIGURATION SET DOP_FEEDBACK = ON. This is the step most DBAs do not know exists. It is OFF by default and must be set on each database individually. - Monitor via sys.query_store_plan_feedback. After enabling, review which queries DOP Feedback is adjusting. Check for any Regressed states where adjustments were reverted.
- Use DISABLE_DOP_FEEDBACK hint for specific queries that should not be adjusted. Known large analytical queries that should always run at maximum DOP should opt out.
- After an AG failover, expect DOP Feedback to re-learn from scratch on the new primary. This is by design per Microsoft documentation. There is no manual migration of DOP Feedback state between replicas.
14 Workshop: Audit and Configure Parallelism from Scratch Beginner
Run these scripts in order on the target SQL Server 2022 instance to audit the current state and configure parallelism correctly.
-- =====================================================================
-- STEP 1: Current state audit
-- Run on the instance (master database context)
-- =====================================================================
-- Server-level MAXDOP and CTFP
SELECT
name,
value_in_use,
CASE name
WHEN 'max degree of parallelism'
THEN CASE value_in_use
WHEN 0 THEN 'WARNING: Default 0 - all CPUs. Set based on NUMA topology.'
WHEN 1 THEN 'No parallelism. Intentional?'
ELSE 'Current: ' + CAST(value_in_use AS VARCHAR)
END
WHEN 'cost threshold for parallelism'
THEN CASE
WHEN value_in_use <= 5 THEN 'WARNING: Default 5. Raise to 35-50 for OLTP.'
WHEN value_in_use < 35 THEN 'LOW: Consider raising to 35-50 for OLTP.'
ELSE 'OK: ' + CAST(value_in_use AS VARCHAR)
END
END AS Assessment
FROM sys.configurations
WHERE name IN ('max degree of parallelism', 'cost threshold for parallelism');
-- All databases: Query Store state and DOP Feedback state
SELECT
d.name AS DatabaseName,
d.is_query_store_on,
d.actual_state_desc AS QueryStoreState,
qs_cfg.value AS DopFeedbackEnabled,
maxdop_cfg.value AS DatabaseMaxDOP
FROM sys.databases d
LEFT JOIN sys.database_scoped_configurations qs_cfg
ON d.database_id = CAST(qs_cfg.database_id AS INT) AND qs_cfg.name = 'DOP_FEEDBACK'
LEFT JOIN sys.database_scoped_configurations maxdop_cfg
ON d.database_id = CAST(maxdop_cfg.database_id AS INT) AND maxdop_cfg.name = 'MAXDOP'
WHERE d.database_id > 4
ORDER BY d.name;
-- =====================================================================
-- STEP 2: Fix server-level MAXDOP and CTFP if needed
-- Adjust values based on environment
-- =====================================================================
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- Set MAXDOP (adjust 8 to match environment)
EXEC sp_configure 'max degree of parallelism', 8;
RECONFIGURE;
-- Set CTFP for OLTP
EXEC sp_configure 'cost threshold for parallelism', 50;
RECONFIGURE;
-- Verify
SELECT name, value_in_use
FROM sys.configurations
WHERE name IN ('max degree of parallelism', 'cost threshold for parallelism');
-- =====================================================================
-- STEP 3: Enable Query Store and DOP Feedback on target database
-- Run in the context of the database to configure
-- =====================================================================
USE YourDatabaseName;
GO
-- Enable Query Store
ALTER DATABASE YourDatabaseName
SET QUERY_STORE = ON (
OPERATION_MODE = READ_WRITE,
QUERY_CAPTURE_MODE = AUTO,
MAX_STORAGE_SIZE_MB = 1024,
INTERVAL_LENGTH_MINUTES = 60
);
-- Enable DOP Feedback (must be done AFTER Query Store is in READ_WRITE)
ALTER DATABASE SCOPED CONFIGURATION SET DOP_FEEDBACK = ON;
-- Verify both settings
SELECT d.name, d.actual_state_desc AS QueryStoreState, sc.name, sc.value
FROM sys.databases d
JOIN sys.database_scoped_configurations sc ON d.database_id = CAST(sc.database_id AS INT)
WHERE d.name = 'YourDatabaseName'
AND sc.name = 'DOP_FEEDBACK';
-- =====================================================================
-- STEP 4: After running workload, check DOP Feedback results
-- Run in the database where DOP Feedback was enabled
-- =====================================================================
USE YourDatabaseName;
GO
-- DOP Feedback summary
SELECT
state_desc,
COUNT(*) AS QueryCount,
MIN(create_time) AS FirstFeedback,
MAX(last_updated_time) AS LastUpdated
FROM sys.query_store_plan_feedback
WHERE feature_id = 3 -- DOP Feedback
GROUP BY state_desc;
-- Top 10 queries where DOP Feedback made the most impactful adjustment
SELECT TOP 10
LEFT(qt.query_sql_text, 100) AS QueryText,
qspf.state_desc,
JSON_VALUE(qspf.feedback_data, '$.adjustedDop') AS AdjustedDOP,
qspf.last_updated_time
FROM sys.query_store_plan_feedback qspf
JOIN sys.query_store_plan qsp ON qspf.plan_id = qsp.plan_id
JOIN sys.query_store_query qsq ON qsp.query_id = qsq.query_id
JOIN sys.query_store_query_text qt ON qsq.query_text_id = qt.query_text_id
WHERE qspf.feature_id = 3
AND qspf.state_desc = 'Verified'
ORDER BY qspf.last_updated_time DESC;
Healthy DOP Feedback output after the first few days of monitoring shows a mix of Verified and Tracking states. Verified means DOP Feedback found a lower DOP that helps and persisted it. Tracking means the query is being observed. Regressed states mean an adjustment was tried and reverted, which is normal and expected: DOP Feedback tried a lower DOP, it made things worse, so it went back. A high proportion of Regressed states on the same query warrants investigation of why the query performance is unstable.
References
- Microsoft Learn: Degree of Parallelism (DOP) Feedback (primary source for all DOP Feedback facts in this article)
- Microsoft Learn: Configure the max degree of parallelism server configuration option
- Microsoft Learn: ALTER DATABASE SCOPED CONFIGURATION (DOP_FEEDBACK, MAXDOP)
- Microsoft Learn: sys.query_store_plan_feedback (Transact-SQL)
- Microsoft Learn: Memory Grant Feedback (Query Store persistence behavior)
- Microsoft Learn: Monitoring Performance by Using the Query Store
- SQLYARD: SQL Server Cost Threshold for Parallelism: The Right Setting
- SQLYARD: SQL Server Wait Statistics: The Complete Guide
- SQLYARD: SQL Server Query Store: The Complete Guide
Discover more from SQLYARD
Subscribe to get the latest posts sent to your email.


