TABLE OF CONTENTS
- •Are you using all the cores you pay for?
- •How SQL Server Uses Processors
- •Compute Limits by Edition in SQL Server 2025
- •Check Whether SQL Server Uses All Your Processors
- •Case 1: The Edition Limit
- •From the field: 8% CPU on a 192-core server
- •The Enterprise Server + CAL trap
- •Case 2: The Virtual Machine Socket Trap
- •Case 3: Unbalanced NUMA Nodes
- •Case 4: More Than 64 Logical Processors per NUMA Node
- •Planning Cores for a New Installation
- •Licensing Is Per Core, Use Is Per Edition
- •After the Processors Are Online
- •CPU Checklist
- •Make every licensed core count
You pay for every core in a SQL Server license, but that doesn’t mean SQL Server uses every core in the machine. Edition limits, the way a virtual machine presents its processors, the old Enterprise Server + CAL licensing, NUMA layout and affinity settings can all leave some of your processors idle while the rest run at 100%. It happens more often than you’d think, and the only symptom is a server that never seems to scale.
This guide shows how SQL Server maps processors to schedulers, the per-edition limits in SQL Server 2025, how to detect offline schedulers, the virtual machine socket trap, the 64-logical-processors-per-NUMA-node limit, and how to fix each case.
Are you using all the cores you pay for?
Aryasoft checks schedulers, NUMA layout, VM topology and edition limits, so licensing cost and performance are right-sized together.
How SQL Server Uses Processors
SQL Server doesn’t hand its work directly to Windows threads. It runs its own scheduling layer, SQLOS:
- A request (a query or batch) is split into one or more tasks; a parallel query has several.
- Each task is bound to a worker thread.
- Workers run on schedulers. There’s one scheduler per logical processor that SQL Server is allowed to use, and only one worker runs on a scheduler at a time.
A scheduler can be VISIBLE ONLINE (SQL Server uses that processor) or VISIBLE OFFLINE (the processor exists but SQL Server isn’t allowed to use it). Offline schedulers are the clearest sign that you’re paying for processors that do nothing for the database.
Compute Limits by Edition in SQL Server 2025
Each edition limits both the number of sockets and the number of cores a single instance can use:
| Edition | Database engine limit per instance |
|---|---|
| Enterprise (core-based licensing) | Operating system maximum |
| Enterprise (Server + CAL, legacy agreements only) | 20 cores |
| Standard (SQL Server 2025) | Lesser of 4 sockets or 32 cores |
| Standard (SQL Server 2016–2022) | Lesser of 4 sockets or 24 cores |
| Standard (SQL Server 2014) | Lesser of 4 sockets or 16 cores |
| Express | Lesser of 1 socket or 4 cores |
| Enterprise Developer / Standard Developer | Same as the edition they mirror; not for production |
Two details change how these limits apply:
- On a physical server, the limit counts cores. With hyper-threading on, a Standard instance limited to 32 cores can use up to 64 logical processors.
- In a virtual machine, the limit counts logical processors (vCPUs), because the guest can’t see the physical core layout. A Standard VM can use up to 32 vCPUs.
The limits are per instance, not per server. Several instances on a large host can each use up to their own limit, but each instance needs to be licensed.
Check Whether SQL Server Uses All Your Processors
The quickest check is the error log. At every startup SQL Server writes what it found and how much it uses:
SQL Server detected 2 sockets with 24 cores per socket and 48 logical processors per socket, 96 total logical processors; using 40 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
“Informational” is misleading here: in this example 56 logical processors are idle. Confirm with the scheduler DMVs:
-- Processor topology as SQL Server sees it
SELECT cpu_count, hyperthread_ratio, socket_count, cores_per_socket,
numa_node_count, scheduler_count, virtual_machine_type_desc
FROM sys.dm_os_sys_info;
-- Online vs offline schedulers per NUMA node
SELECT parent_node_id AS numa_node,
status,
COUNT(*) AS schedulers,
SUM(current_tasks_count) AS current_tasks,
SUM(runnable_tasks_count) AS runnable_tasks
FROM sys.dm_os_schedulers
WHERE status IN (N'VISIBLE ONLINE', N'VISIBLE OFFLINE')
GROUP BY parent_node_id, status
ORDER BY numa_node, status;
Any VISIBLE OFFLINE row means processors are excluded. A constantly non-zero runnable_tasks count on the online schedulers means work is queuing for CPU, which you’ll also see as high SOS_SCHEDULER_YIELD waits and signal wait time.
Case 1: The Edition Limit
The most common cause is simply an edition smaller than the machine: Standard edition on a 48-core host, or Express on anything bigger than four cores. Either reduce the processors given to the instance to what the edition can use, so you stop paying for idle capacity, or move to an edition that matches the hardware. An edition upgrade can unlock far more capacity than new hardware would.
From the field: 8% CPU on a 192-core server
One of the clearest examples we’ve seen was a critical public-sector system used by thousands of employees at once. Screens stopped responding and daily work came to a halt, yet total CPU usage on the server sat at about 8%. The server had 192 cores; the database engine was SQL Server 2014 Standard.
The schedulers told the real story. Because of the Standard edition limit, SQL Server could use only 16 cores, and all 16 were at 100%. The other 176 cores didn’t exist as far as the database was concerned. The 8% total was exactly 16 out of 192.
A controlled edition upgrade to Enterprise made all 192 cores available without interrupting public services, and response times returned to normal. The full story is in unlocking 192 cores with a SQL Server 2014 Standard-to-Enterprise upgrade.
Warning
Total CPU percentage for the server doesn’t tell you whether SQL Server is under pressure. With an edition limit or offline schedulers, the total can look low while every core SQL Server is allowed to use is saturated. Monitor CPU per scheduler and watch runnable_tasks_count.
The Enterprise Server + CAL trap
Enterprise edition licensed with Server + CAL (only available under older agreements) is limited to 20 cores per instance, which is 40 logical processors with hyper-threading. Organizations that moved such an instance to new hardware with more cores often find the extra cores offline. The fix is a move to core-based licensing; adding hardware alone doesn’t help.
Case 2: The Virtual Machine Socket Trap
Standard edition is limited to four sockets. When a VM is created with 8 vCPUs configured as 8 sockets with 1 core each, which is a common hypervisor default, SQL Server Standard sees 8 sockets and uses only 4 of them. Half the VM’s processors stay offline.
The fix is a configuration change in the hypervisor, not in SQL Server: present the same vCPUs as fewer sockets with more cores per socket, for example 1 socket × 8 cores or 2 sockets × 4 cores, ideally matching the host’s physical NUMA layout. It requires a VM restart.
Tip
When you size a VM for SQL Server Standard, set the sockets and cores-per-socket deliberately at creation time. A VM with 16 vCPUs as 16 sockets × 1 core runs Standard on 4 vCPUs; the same VM as 2 sockets × 8 cores runs it on all 16.
Case 3: Unbalanced NUMA Nodes
When SQL Server can only use part of the processors, it doesn’t spread the allowed ones evenly across NUMA nodes by default. The result can be one node with all schedulers online and another with almost none, so memory and work are skewed toward one side of the machine.
If you can’t change the edition or the processor count, you can bring schedulers online evenly with process affinity, choosing processors from each NUMA node:
-- Example: use 20 logical processors from each of two NUMA nodes
ALTER SERVER CONFIGURATION
SET PROCESS AFFINITY CPU = 0 TO 19, 48 TO 67;
-- Return to the default (SQL Server decides)
ALTER SERVER CONFIGURATION SET PROCESS AFFINITY CPU = AUTO;
Warning
Check how your server numbers processors per NUMA node in sys.dm_os_schedulers before setting affinity, and don’t combine SQL Server affinity with Windows-level processor affinity or hypervisor pinning for the same purpose. The older sp_configure ‘affinity mask’ options are deprecated; use ALTER SERVER CONFIGURATION instead.
Case 4: More Than 64 Logical Processors per NUMA Node
SQL Server supports at most 64 logical processors per NUMA node. Modern high-core-count CPUs can exceed this when a whole socket is presented as one NUMA node with SMT enabled. Beyond the limit you can see stack dumps and reliability issues, and starting with SQL Server 2022 CU11 the database engine refuses to start on such a configuration.
The fix is in the firmware: enable sub-NUMA clustering (SNC) on Intel Xeon or a Nodes-per-Socket setting such as NPS2 or NPS4 on AMD, so each socket is presented as several smaller NUMA nodes. On some Azure VM sizes, disabling SMT achieves the same.
Planning Cores for a New Installation
Most of these problems never happen if a few decisions are made before installation. When you plan a new SQL Server machine or VM:
- Choose the edition for the hardware, or size the hardware for the edition. Every processor above 32 cores for Standard, or 4 for Express, sits idle but still needs a license.
- Set the VM topology at creation time: few sockets, several cores per socket, matching the host’s NUMA layout.
- Check firmware settings: the 64-logical-processors-per-NUMA-node limit, the power profile and C-states.
- Read the startup message in the error log right after installation and confirm there are no offline schedulers.
- Set MAXDOP, cost threshold and the number of tempdb files for the real processor count.
The other installation steps are collected in our SQL Server installation checklist. If you’d like to plan server sizing, edition and licensing, installation and initial configuration together, see our SQL Server installation and configuration services.
Licensing Is Per Core, Use Is Per Edition
Licensing and usable capacity are separate questions. With core-based licensing you license every core visible to the operating system or VM, with a minimum of four per VM or processor, even if the edition can’t use all of them. Giving a Standard VM 48 vCPUs means paying for 48 cores while SQL Server uses 32.
Right-sizing goes in both directions: remove processors that an edition can’t use, and make sure the processors you keep are online and balanced. Our SQL Server 2025 licensing guide covers the counting rules.
After the Processors Are Online
Once SQL Server sees the right number of schedulers, review the settings that depend on them:
- MAXDOP: the recommended value depends on the number of logical processors per NUMA node. See our MAXDOP guide.
- Cost threshold for parallelism: the default of 5 is far too low for most modern workloads.
- tempdb data files: usually one per logical processor up to eight, then more only if contention remains.
- Max worker threads: leave at 0 (automatic) unless there’s a specific reason; the automatic value scales with processor count.
- Power plan: set Windows to High performance and check the BIOS power profile. A balanced plan can keep cores at low clock speeds during short bursts.
CPU Checklist
- The startup message in the error log shows SQL Server using all intended logical processors.
- No VISIBLE OFFLINE schedulers, or offline ones are a deliberate choice.
- Online schedulers are balanced across NUMA nodes.
- VMs use few sockets with several cores per socket.
- No NUMA node exposes more than 64 logical processors.
- Licensed cores match the cores the edition can use.
- MAXDOP, cost threshold and tempdb files reflect the actual processor count.
- Windows and BIOS power settings favor performance.
Related Reading
SQL Server Performance Consulting
Make every licensed core count
Aryasoft’s senior DBA team checks scheduler status, NUMA balance, VM topology and edition limits, then right-sizes processors and licensing together so you stop paying for idle cores.