giip
SES Proposal
SQL ServerMediumパラメータ性能RDS

How to Check and Change MAXDOP and Cost Threshold for Parallelism in SQL Server

Published 2026-08-13 · Updated 2026-08-13 · Last Verified 2026-08-13

Answer

You can check the current values read-only by filtering `sys.configurations` to the two relevant settings. To change them, use `sp_configure` and `RECONFIGURE` for the whole server, `ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP` (SQL Server 2016 and later) for a single database, or `OPTION (MAXDOP n)` for a single query. The first two take effect without a restart, but they are broad-impact changes that alter execution plan selection across the entire server.

Applicability of This Document

ProductSQL Server / Amazon RDS for SQL Server / Azure SQL Managed Instance
Verified VersionsSQL Server 2008 and later (database-scoped MAXDOP requires SQL Server 2016 or later)
EnvironmentOn-premises, EC2, Amazon RDS, Azure
Required PermissionsReading requires VIEW SERVER STATE or VIEW ANY DEFINITION. Changing via `sp_configure` requires ALTER SETTINGS (effectively sysadmin / serveradmin). Database-scoped configuration requires ALTER ANY DATABASE SCOPED CONFIGURATION
Execution ImpactReading makes no changes. Changing the settings affects execution plan selection server-wide or database-wide
RestartNot required (both settings take effect immediately via `RECONFIGURE`)
Last Verified2026-08-13

Ready-to-Run Commands

Check current values (read-only, sys.configurations)Read-only
対象
SQL Server 2008 and later / Amazon RDS for SQL Server
権限
VIEW SERVER STATE or VIEW ANY DEFINITION
変更作業
None (read-only)
Production実行
Safe to run
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: VIEW SERVER STATE または VIEW ANY DEFINITION
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
SELECT
    c.configuration_id,
    c.name,
    c.value           AS configured_value,   -- 構成された値
    c.value_in_use    AS running_value,      -- 実際に使われている値
    c.minimum,
    c.maximum,
    c.is_dynamic,     -- 1: 再起動なしで反映される
    c.is_advanced,    -- 1: show advanced options が必要
    c.description
FROM sys.configurations AS c
WHERE c.name IN ('max degree of parallelism', 'cost threshold for parallelism')
ORDER BY c.name;

Unlike `sp_configure`, this does not require enabling `show advanced options`, so use this for checking only. If `configured_value` and `running_value` differ, `RECONFIGURE` has not been run.

Check logical CPU count and NUMA node layout (background needed to decide the setting)Read-only
対象
SQL Server 2008 and later / Amazon RDS for SQL Server
権限
VIEW SERVER STATE
変更作業
None (read-only)
Production実行
Safe to run
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: VIEW SERVER STATE
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
SELECT
    cpu_count                       AS logical_cpu_count,
    hyperthread_ratio,
    scheduler_count,
    softnuma_configuration_desc     -- SQL Server 2016 以降。それ以前の版では列を外すこと
FROM sys.dm_os_sys_info;

-- NUMA ノードごとのスケジューラ配置
SELECT
    parent_node_id                  AS numa_node_id,
    COUNT(*)                        AS scheduler_count
FROM sys.dm_os_schedulers
WHERE status = 'VISIBLE ONLINE'
GROUP BY parent_node_id
ORDER BY parent_node_id;

To decide on a MAXDOP value, you first need to know the logical CPU count and the number of cores per NUMA node. `softnuma_configuration_desc` is a column available on SQL Server 2016 and later.

Check via sp_configure (requires enabling show advanced options)Medium
対象
SQL Server 2008 and later
権限
ALTER SETTINGS (equivalent to sysadmin / serveradmin)
変更作業
Yes (toggling `show advanced options` itself is a server configuration change)
Production実行
Possible, but use `sys.configurations` if you only need to check
-- 対象: SQL Server 2008 以降
-- 権限: ALTER SETTINGS(sysadmin / serveradmin 相当)
-- 変更作業: あり(show advanced options の切り替えはサーバー構成の変更)
-- Production 実行: 可能。ただし確認目的なら sys.configurations を推奨
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
GO

EXEC sp_configure 'max degree of parallelism';
EXEC sp_configure 'cost threshold for parallelism';

Setting `show advanced options` to 1 is itself a server configuration change. If you only want to read the values, use `sys.configurations` as shown above instead.

Change the setting server-wide (broadest scope of impact)Medium
対象
SQL Server 2008 and later (use a parameter group on Amazon RDS)
権限
ALTER SETTINGS (equivalent to sysadmin / serveradmin)
変更作業
Yes (changes execution plan selection server-wide)
Production実行
Can be run, but prepare before/after measurements and a rollback procedure
-- 対象: SQL Server 2008 以降(Amazon RDS ではパラメータグループ経由)
-- 権限: ALTER SETTINGS(sysadmin / serveradmin 相当)
-- 変更作業: あり(サーバー全体の実行プラン選択に影響)
-- Production 実行: 可能。ただし変更前後の測定と切り戻し手順が前提
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
GO

-- 下の値は「例示」であり推奨値ではない。必ず自環境の測定結果に置き換えること
DECLARE @maxdop         int = 4;
DECLARE @cost_threshold int = 50;

EXEC sp_configure 'max degree of parallelism', @maxdop;
RECONFIGURE;

EXEC sp_configure 'cost threshold for parallelism', @cost_threshold;
RECONFIGURE;
GO

-- 反映結果の確認
SELECT name, value, value_in_use
FROM sys.configurations
WHERE name IN ('max degree of parallelism', 'cost threshold for parallelism');

The values 4 and 50 in the code are example values to illustrate the syntax, not recommendations. The right value depends on the logical CPU count, NUMA configuration, and the nature of the workload (OLTP-leaning vs. analytics-leaning), so do not apply this without measuring your own environment. Both settings are `is_dynamic = 1` and take effect via `RECONFIGURE` without a service restart.

Set MAXDOP at the database level (SQL Server 2016 and later)Medium
対象
SQL Server 2016 and later / Azure SQL Database
権限
ALTER ANY DATABASE SCOPED CONFIGURATION
変更作業
Yes (changes execution plan selection for the target database)
Production実行
Can be run, but affects the entire target database
-- 対象: SQL Server 2016 以降 / Azure SQL Database
-- 権限: ALTER ANY DATABASE SCOPED CONFIGURATION
-- 変更作業: あり(対象データベース全体の実行プラン選択に影響)
-- Production 実行: 可能。対象DB全体に効くため影響範囲を確認すること
USE [SampleDB];
GO

-- 現在値の確認(参照のみ)
SELECT configuration_id, name, value, value_for_secondary
FROM sys.database_scoped_configurations
WHERE name = 'MAXDOP';

-- 変更(0 はサーバー設定に従う)
ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 4;

Database-scoped MAXDOP takes priority over the server setting. This is useful when multiple business databases coexist on the same instance and you want to change the degree of parallelism for only one of them. `cost threshold for parallelism` has no database-scoped setting — only a server-wide one.

Control the degree of parallelism for a single query only (narrowest scope of impact)Low
対象
SQL Server 2008 and later / Amazon RDS for SQL Server
権限
Read permission on the target object
変更作業
Yes (changes the execution plan of that query only)
Production実行
Safe to run — impact is limited to that query
-- 対象: SQL Server 2008 以降 / Amazon RDS for SQL Server
-- 権限: 対象オブジェクトへの参照権限
-- 変更作業: あり(このクエリの実行プランのみ変わる)
-- Production 実行: 可能(影響はこのクエリに限定)
SELECT col1, col2
FROM dbo.SampleTable
WHERE col1 > 0
OPTION (MAXDOP 1);

If the problem is limited to a specific query, this approach keeps the scope of impact the smallest. Before changing a server setting, first confirm whether this helps at the query level.

How to Read the Results

ColumnMeaningWhat to Check
nameName of the configuration optionWhether both `max degree of parallelism` and `cost threshold for parallelism` are returned
configured_valueThe configured valueWhether the intended value is set
running_valueThe value actually in useIf different from `configured_value`, `RECONFIGURE` has not been run
is_dynamicWhether it takes effect without a restartBoth of these settings are 1 (no restart needed)
is_advancedWhether `show advanced options` is requiredIf 1, changing it via `sp_configure` requires enabling that option first
logical_cpu_countNumber of logical CPUsThe basis for judging an upper bound on MAXDOP
numa_node_id / scheduler_countNumber of schedulers per NUMA nodeLearn the number of cores per node — informs whether to keep MAXDOP within a single node
value_for_secondaryValue used for the secondary replicaIn an availability group configuration, also check the secondary-side setting

When to Use This

  • CXPACKET / CXCONSUMER dominate the top of the wait statistics
  • Even small queries end up with parallel plans, and only CPU usage goes up
  • Overall throughput drops during periods of high concurrency
  • The same query has a different execution plan in the test environment versus production

Possible Causes (Most Likely First)

  1. 01

    cost threshold for parallelism is still at its default

    The default value of 5 assumes hardware from a very different, much older era. In modern environments, this makes it easy for queries that gain little from parallelism to become candidates for a parallel plan anyway. That said, there is no universal "right" value — it depends on the environment. Decide only after measuring the actual distribution of query costs.

  2. 02

    MAXDOP has been left at 0 (unlimited)

    0 means "use every available logical CPU." On a server with many cores, a single query can occupy a large number of threads, squeezing out other work when multiple queries run concurrently.

  3. 03

    The server setting does not match the workload's nature

    OLTP-centric processing and analytics-centric processing call for different degrees of parallelism. When both coexist on the same instance, a single server-wide value cannot be fully optimized for either.

  4. 04

    Outdated statistics cause the cost estimate to diverge from reality

    If the estimated row count is too high, the estimated cost comes out high enough to cross the threshold and trigger a parallel plan. The fix here is updating statistics, not changing the degree-of-parallelism setting.

Diagnostic Steps

  1. 1

    Check the current values

    Read-only

    Check the `value` and `value_in_use` of both settings in `sys.configurations`. Read-only.

  2. 2

    Check the hardware configuration

    Read-only

    Check the logical CPU count and the number of schedulers per NUMA node — this is the background needed to decide on a setting.

  3. 3

    Measure the weight of parallel waits from wait statistics

    Read-only

    Use a delta for the relevant time window to check the weight of CXPACKET / CXCONSUMER. A cumulative total alone cannot be judged.

  4. 4

    Capture the execution plan of an actually slow query

    Low

    Check whether it has a parallel operator and whether row counts are unevenly distributed across threads.

  5. 5

    Verify the effect at the query level

    Low

    Run the query with `OPTION (MAXDOP n)` added and check whether response time improves. If it does not improve, changing the server setting will not help either.

  6. 6

    Check the freshness of statistics

    Read-only

    Confirm that a gap in the cost estimate is not the cause before proceeding to a setting change.

Solutions

Low-risk action that can be done immediately

  • Verify with a query hint limited to the target query

    Low

    Control only the problem query with `OPTION (MAXDOP n)`. The scope of impact is limited and easy to roll back.

  • Check and update the freshness of statistics

    Medium

    If a row-count estimation gap is the cause, updating statistics is the correct fix, not a setting change.

Change requiring advance review

  • Review cost threshold for parallelism

    Medium

    Measure the distribution of estimated costs for queries currently getting parallel plans, and consider a level that excludes queries gaining no benefit from parallelism. Decide the value from measurements, then re-measure response time after the change.

  • Review MAXDOP

    Medium

    Set an upper bound based on logical CPU count and NUMA configuration. Apply it gradually and compare response times of key queries at each step.

  • Switch to a database-level setting

    Medium

    If workloads with different natures coexist on the same instance, `ALTER DATABASE SCOPED CONFIGURATION` (SQL Server 2016 and later) lets you split the setting per database.

  • Update the parameter group on Amazon RDS

    Medium

    Server-wide settings are managed through a DB parameter group. Whether a change takes effect immediately or after a restart depends on the parameter's apply type.

Change involving a restart or service impact

  • Control per workload with Resource Governor

    Expert Review Required

    You can control the degree of parallelism per workload group, but a poorly designed classifier function can make a specific workload extremely slow. This also has edition restrictions, so it assumes a design review.

  • Consider splitting into separate instances

    Expert Review Required

    This approach separates OLTP and analytics workloads onto different instances. It is the most reliable form of optimization, but involves configuration changes and a migration effort.

!Warnings

  • The values `4` and `50` in the code examples are illustrative syntax examples, not recommendations. The right value depends on the logical CPU count, NUMA configuration, and the nature of the workload, so decide only after measuring your own environment.
  • The default value of 5 for `cost threshold for parallelism` is an old benchmark, and in practice it is often raised. However, what value is "correct" depends on the environment, so do not change it to a specific value unconditionally.
  • Both settings take effect without a service restart, but the moment they do, execution plan selection changes server-wide. Recompiling existing plans can cause a temporary spike in load.
  • On Amazon RDS for SQL Server, server-wide configuration is managed through a DB parameter group. Changes via `sp_configure` may not be permitted, so check in advance whether the target parameter can be changed.
  • Database-scoped MAXDOP takes priority over the server setting. If changing the server setting has no effect, check the database-level setting.
  • The `value_in_use` does not change unless `RECONFIGURE` is run. Always verify that the change took effect after applying it.

Differences by Version and Environment

SQL Server 2016 and laterYou can set MAXDOP per database with `ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = n`. Check the current value with `sys.database_scoped_configurations`.
SQL Server 2019 and laterSetup now suggests an initial MAXDOP value based on the hardware configuration. The default is not necessarily 0, so always check the current value.
Amazon RDS for SQL ServerServer-level configuration is changed via a DB parameter group. Check the target environment for whether `sp_configure` can be run and whether parameter changes apply immediately or after a restart (verify before relying on this).
Azure SQL DatabaseServer-level `sp_configure` is not available. Set MAXDOP via database-scoped configuration instead.

If This Doesn't Resolve It

  • Cost distribution of queries getting parallel plans

    Aggregate estimated costs from the plan cache to see how many queries sit near the threshold.

  • Per-thread row counts in execution plans

    Check whether row counts are unevenly distributed across parallel threads. If they are, raising the degree of parallelism will have limited effect.

  • Memory grant status

    Parallel queries request larger memory grants. Check whether `RESOURCE_SEMAPHORE` waits co-occur.

  • Availability group secondary settings

    Check whether `value_for_secondary` in the database-scoped configuration differs from the primary's setting.

Basis and Limitations of This Document

Explanation based on official product documentation

Based on the public specifications of SQL Server's `sp_configure` (`max degree of parallelism` / `cost threshold for parallelism`), `sys.configurations`, `ALTER DATABASE SCOPED CONFIGURATION`, `sys.database_scoped_configurations`, and the `MAXDOP` query hint. Because the right setting value depends on the environment, specific numbers here are illustrative only, and the article focuses on the decision criteria. Verify on the target environment whether and when parameter changes take effect on Amazon RDS.

FAQ

What should MAXDOP be set to?

There is no universal answer. The right value depends on the logical CPU count, the number of cores per NUMA node, and whether the workload leans OLTP or analytics. First check the current value and the hardware configuration, measure the effect at the query level with `OPTION (MAXDOP n)`, and only then consider changing the server setting.

Is it a problem to leave cost threshold for parallelism at its default of 5?

The default of 5 is a benchmark from a very old era, and on modern hardware it makes even queries that gain little from parallelism likely to get parallel plans. In practice this setting is often raised, but the right value depends on the environment, so measure the distribution of estimated query costs before deciding.

Does changing this require a service restart?

No. Both settings are `is_dynamic = 1` and take effect immediately via `RECONFIGURE`. However, the moment they do, execution plan selection changes server-wide, so a temporary spike in load can occur from recompilation.

Does this work on AWS RDS?

The read-only `sys.configurations` check works as-is. Changing the server-wide setting goes through a DB parameter group, so procedures that assume `sp_configure` cannot be applied as written. Check in advance whether the target parameter can be changed and what the apply timing is.

What permissions are required?

Reading requires VIEW SERVER STATE or VIEW ANY DEFINITION. Changing via `sp_configure` requires ALTER SETTINGS (effectively sysadmin / serveradmin); changing database-scoped configuration requires ALTER ANY DATABASE SCOPED CONFIGURATION.

How should I interpret the results?

First confirm that `value` and `value_in_use` match. Then compare wait statistics and the response time of key queries for the relevant time window before and after the change, and keep the new setting only if an improvement is actually measured.

Questions This Document Covers

  • I want to check the current value of MAXDOP
  • I want to change the degree of parallelism per database
  • I want to know how to change MAXDOP on RDS

What the Risk Labels Mean

  • Read-onlyDoes not change data or settings.
  • LowImpact is limited, but permissions and load should be checked.
  • MediumMay affect performance, locking, or cost.
  • HighMay cause an outage, data loss, or require recovery work.
  • Expert Review RequiredRequires a separate review before applying to production.

GIIP's Scope of Support

A degree-of-parallelism setting is not something you decide once and forget. As data volume grows, queries get added, and instance sizes change, the right value shifts too. At GIIP, we keep the setting value itself alongside the wait events and response times observed under that setting, on the same timeline, so we can trace exactly what changed before and after a change. Broad-impact operations like changing a setting are never run automatically by an AI agent — measurement and proposals are automated, but the decision to apply and the approval remain a human responsibility.

Author & Technical Review

GIIP Production Operations Team

About 30 years of experience in designing, migrating, and operating large-scale web services, SQL Server, Oracle, AWS, and Azure. Experience includes 12 sets of x12large-class AWS RDS for SQL Server environments, an Oracle environment with roughly 120,000 tables, and migrating roughly 3TB from TiDB to Aurora MySQL. AI agents and human experts currently continue to monitor and operate multiple cloud databases and about 30 web services.

Related Knowledge

Related Services

Get a diagnosis of your degree-of-parallelism settings

If you need to repeat the same checks across multiple environments, we can discuss your entire operations setup.

Get a diagnosis of your degree-of-parallelism settings

← Back to Knowledge Base