SQL Server Max Server Memory Calculator Script
Every SQL Server installation ships with max server memory set to its default value of 2,147,483,647 MB — effectively unlimited — which allows the Buffer Pool to consume all available RAM and starve the operating system of the memory it needs for network stack, disk I/O, and other critical processes. This script reads total physical RAM from sys.dm_os_sys_info, applies Jonathan Kehayias's widely-adopted OS reservation formula, and compares the recommended cap to the current sp_configure setting so DBAs can see at a glance whether action is needed.
Purpose and Overview
SQL Server's Buffer Pool is its primary memory consumer. When max server memory is left at the default unlimited value, the Buffer Pool expands to fill available RAM as query workloads grow — and it does not release that memory on demand. The operating system begins paging other processes to disk, causing latency spikes that affect not just other applications on the server but SQL Server itself, because its own threads and network buffers compete with the Buffer Pool for physical pages. On servers running SSRS, SSIS, or IIS alongside SQL Server, the problem is more acute.
Jonathan Kehayias of SQLskills.com published the industry-standard formula for calculating how much memory to reserve for the OS: 1 GB base plus 1 GB for every 4 GB of RAM above the first 4 GB, capped at 4 GB total OS reserve. This formula is adapted and distributed in the ktaranov/sqlserver-kit community repository. This script implements the Kehayias formula against the current server's physical RAM, reads the current max server memory configuration, and produces an Assessment column and a ready-to-run sp_configure command for applying the recommended setting.
Output columns:
- TotalPhysicalRAM_MB — total RAM detected by SQL Server via the OS
- RecommendedOSReserve_MB — how much to leave for the OS per the Kehayias formula
- RecommendedMaxServerMemory_MB — recommended
max server memoryvalue - CurrentMaxServerMemory_MB — the currently configured value from
sys.configurations - Assessment — one of four states: unlimited default, over-configured, under-configured, or OK
- ApplyScript — a generated
sp_configure+RECONFIGUREstatement to copy and run
Code Breakdown
The script reads physical RAM, calculates the OS reserve, reads the current configuration, and produces both an assessment and a ready-to-apply command.
1-- SQL Server Max Server Memory Calculator
2-- Source: adapted from ktaranov/sqlserver-kit and Jonathan Kehayias formula (sqlskills.com)
3-- Calculates recommended max server memory and compares to current setting
4-- Requires: VIEW SERVER STATE
5
6SET NOCOUNT ON;
7
8DECLARE @TotalRAM_MB BIGINT;
9DECLARE @OSReserve_MB BIGINT;
10DECLARE @RecommendedMax_MB BIGINT;
11DECLARE @CurrentMax_MB BIGINT;
12
13-- Read total physical RAM from the OS
14SELECT @TotalRAM_MB = physical_memory_kb / 1024
15FROM sys.dm_os_sys_info;
16
17-- Jonathan Kehayias formula: reserve OS memory based on total RAM
18-- Base: 1 GB for the OS + 1 GB for every 4 GB of RAM above 4 GB
19SET @OSReserve_MB =
20 1024 -- 1 GB base for OS
21 + (
22 CASE
23 WHEN @TotalRAM_MB > 4096
24 THEN ((@TotalRAM_MB - 4096) / 4096) * 1024
25 ELSE 0
26 END
27 );
28
29-- Cap OS reserve at 4 GB for very large RAM servers
30IF @OSReserve_MB > 4096
31 SET @OSReserve_MB = 4096;
32
33SET @RecommendedMax_MB = @TotalRAM_MB - @OSReserve_MB;
34
35-- Read current setting
36SELECT @CurrentMax_MB = CAST(value_in_use AS BIGINT)
37FROM sys.configurations
38WHERE name = 'max server memory (MB)';
39
40SELECT
41 @TotalRAM_MB AS TotalPhysicalRAM_MB,
42 @OSReserve_MB AS RecommendedOSReserve_MB,
43 @RecommendedMax_MB AS RecommendedMaxServerMemory_MB,
44 @CurrentMax_MB AS CurrentMaxServerMemory_MB,
45 CASE
46 WHEN @CurrentMax_MB >= 2147483647
47 THEN 'WARNING: max server memory is at default (unlimited) — set it explicitly'
48 WHEN @CurrentMax_MB > @RecommendedMax_MB
49 THEN 'WARNING: current setting exceeds recommended maximum'
50 WHEN @CurrentMax_MB < @RecommendedMax_MB * 0.75
51 THEN 'UNDER-CONFIGURED: current setting is less than 75% of recommended'
52 ELSE 'OK: current setting is within recommended range'
53 END AS Assessment;
54
55-- Show how to apply the recommended setting (copy and run separately)
56SELECT
57 'EXEC sp_configure ''max server memory (MB)'', '
58 + CAST(@RecommendedMax_MB AS NVARCHAR(20))
59 + '; RECONFIGURE;' AS ApplyScript;
Reading Total RAM from sys.dm_os_sys_info
sys.dm_os_sys_info is a single-row DMV that exposes OS-level information visible to SQL Server, including total physical memory. The physical_memory_kb column returns total RAM in kilobytes; dividing by 1,024 converts to megabytes. This value reflects the physical RAM installed in the server as reported by the OS — it does not change with workload and does not require VIEW SERVER STATE on SQL Server 2019 and later (the permission requirement was relaxed). On older versions, VIEW SERVER STATE is required.
Jonathan Kehayias OS Reserve Formula
The formula reserves 1 GB as a base for OS overhead, then adds 1 GB for every 4 GB of RAM above the first 4 GB. The integer division ((@TotalRAM_MB - 4096) / 4096) * 1024 implements this in steps of 4 GB using T-SQL integer arithmetic, which truncates the remainder rather than rounding. The result is capped at 4 GB total OS reserve: on servers with 256 GB or more of RAM, dedicating more than 4 GB to the OS is generally unnecessary for a dedicated SQL Server host. For servers running multiple workloads alongside SQL Server (SSRS, IIS, custom services), increase the OS reserve manually by subtracting additional memory from @RecommendedMax_MB before applying.
sys.configurations — Reading the Current Setting
sys.configurations contains one row per SQL Server configuration option. The value column stores the persisted setting (saved to disk), while value_in_use reflects what is currently active in the running instance. When max server memory has been changed but RECONFIGURE has not been run, value and value_in_use will differ — value_in_use is the correct column for the running state. The default value of 2,147,483,647 maps to INT max value and means unlimited; any result at or above this threshold triggers the unlimited-default warning.
Assessment and ApplyScript
The Assessment CASE covers four states in priority order: the unlimited default (highest priority — always warn regardless of RAM), over-configured (current > recommended, meaning SQL Server may be taking more than it should), under-configured (current < 75% of recommended, meaning SQL Server is unnecessarily constrained and may spill to disk prematurely), and OK (within range). The ApplyScript column generates the exact sp_configure command with the recommended value. It is output as a separate SELECT so the DBA must consciously copy and execute it — the script does not auto-apply any changes.
Key Benefits and Use Cases
- Detects the unlimited-default anti-pattern — the single most common SQL Server memory misconfiguration is leaving
max server memoryat the factory default; this script flags it immediately - Formula-based recommendation — removes guesswork by applying the Kehayias formula to the server's actual RAM rather than relying on memory of the correct values
- Current vs recommended comparison — shows both numbers in context so over-constrained and over-allocated servers are immediately visible
- Ready-to-apply command — the ApplyScript output eliminates transcription errors when applying the setting
- Repeatable audit — run after hardware changes, VM resizing, or memory additions to verify the setting is still appropriate
- Multi-workload adjustment baseline — the OS reserve cap is a starting point; the script makes it easy to recalculate with a higher reserve for shared hosts
Performance Considerations
- sys.dm_os_sys_info is a single lightweight DMV call — the query executes in milliseconds regardless of instance size or workload
- max server memory does not govern all SQL Server memory — thread stacks, linked server memory, CLR, and extended stored procedures consume memory outside the Buffer Pool and outside this cap; on instances using these features, the effective memory ceiling is lower than
max server memoryalone - RECONFIGURE is online — changing
max server memoryviasp_configure+RECONFIGUREtakes effect immediately without a service restart; the Buffer Pool shrinks or expands dynamically - RECONFIGURE WITH OVERRIDE is not required —
max server memoryis not an advanced option requiring override; standardRECONFIGUREis sufficient - The 75% under-configured threshold is conservative — some workloads intentionally cap SQL Server well below the formula recommendation to reserve memory for in-memory OLAP tools or OS disk cache; treat the UNDER-CONFIGURED assessment as a conversation starter, not an absolute directive
Practical Tips
- Always set max server memory explicitly on every SQL Server instance — there is no scenario where leaving it at the unlimited default is correct on a production server
- On shared hosts, increase OS reserve — add the memory requirements of each co-resident service to
@OSReserve_MBbefore calculating@RecommendedMax_MB; for example, add 2 GB if SSRS runs on the same host - Monitor Memory Grants Pending after adjusting — query
sys.dm_os_performance_counters WHERE counter_name = 'Memory Grants Pending'before and after the change; a spike indicates the new cap is too low for the current query workload - Use sys.dm_os_memory_clerks to understand Buffer Pool consumption — if SQL Server is not consuming its allowed maximum, the constraint may be elsewhere;
SELECT type, SUM(pages_kb)/1024 AS MB FROM sys.dm_os_memory_clerks GROUP BY type ORDER BY MB DESCshows the breakdown - For Always On Availability Groups, size memory on all replicas — the secondary replica runs the same workload during failover; under-sizing memory on the secondary causes a performance cliff immediately after failover
Conclusion
This script from the ktaranov/sqlserver-kit community repository implements Jonathan Kehayias's OS reservation formula against the current server's physical RAM to produce an actionable max server memory recommendation. Combined with the current configuration value from sys.configurations, it gives DBAs a one-query answer to whether the most common SQL Server memory misconfiguration — the unlimited default — is present on their instance, and a ready-to-run command to correct it.
References
- sqlserver-kit on GitHub by Konstantin Taranov — Community collection of SQL Server scripts including memory configuration and server health utilities
- How Much Memory Does My SQL Server Actually Need? by Jonathan Kehayias — Original formula and rationale for OS memory reservation on SQL Server hosts
- Microsoft Docs: sys.dm_os_sys_info — Reference for the single-row DMV that exposes OS-level server statistics including physical memory
- Microsoft Docs: Server Memory Configuration Options — Reference for max server memory behavior, defaults, and guidance
- Microsoft Docs: sys.configurations — Reference for the configuration catalog view including value vs value_in_use semantics