Memory Pressure

Overview

The Memory report shows where SQL Server’s memory is right now, and page life expectancy as one figure for the whole instance. That misses two things: when memory ran short, and a NUMA node that is starved while the instance average looks fine.

The Memory Pressure report answers both:

  • state cards for the memory state right now: what Windows says about physical memory, SQL Server’s own low memory flags, memory grants pending, SQL Server’s memory against its target, and available physical memory,
  • a timeline of every low memory notification from the resource monitor, colored by whether the pressure was internal (SQL Server’s own limit), external (Windows) or both, with the memory broker’s shrink decisions in a second lane,
  • guidance on what the pressure points at,
  • one bar per NUMA node with its memory against its target, foreign memory and page life expectancy, with a node under half the best node’s page life expectancy flagged,
  • a Last 7 days view when Historic Monitoring collects memory pressure on the instance.

The ring buffers only reach back as far as they last wrapped, usually hours. The Last 7 days view is what covers the week.


Where to find it

Route How
Server tree Right-click the server → Instance Level Reports → Memory Pressure
Instance reports navigator Performance group
Related Links bar From Memory, Windows Event Log, Host and Hardware and In-Memory OLTP by Database
Report arrows Previous is Memory Grants and Spills, next is Migration Planner

The page title reads Memory Pressure for <server name>.


The toolbar

Control What it does
Refresh Reads the instance again (or, on Last 7 days, reads the history again)
Pressure events / Memory broker / NUMA nodes Which grid is shown below the chart. The chart stays the same
Last 7 days The history view. Only offered when DBHealthHistory on the instance holds the memory pressure collection and your login can open it. Read the first time you pick it
Cancel Shown while a read runs. Stops it and keeps what was on the page

The read runs in the background with the progress bar, and the toolbar says “Reading the ring buffers and memory counters…” or “Reading the last 7 days from DBHealthHistory…”. Moving to another page cancels it.


Reading the page

The heading gives the number of memory pressure events and how far back the ring buffer reaches, how many NUMA nodes have low page life expectancy, and when it was read in server time. For example: “2 memory pressure events in the last 5 hours (as far back as the ring buffer reaches); 1 NUMA node has low page life expectancy. Read at 2026-09-27 10:15:00 server time.”

The cards. A card with an orange stripe down its left side, and its value in orange, is a warning.

Card What it shows Warning when
SYSTEM MEMORY STATE system_memory_state_desc from sys.dm_os_sys_memory, shortened (“Available physical memory is high” reads as “High”) The state says low
PROCESS MEMORY LOW No, or which of SQL Server’s process_physical_memory_low and process_virtual_memory_low flags are set Either flag is set
MEMORY GRANTS PENDING Queries waiting for workspace memory right now More than 0
SQL SERVER MEMORY, TOTAL OF TARGET Total Server Memory of Target Server Memory, with max server memory underneath (“not set” when it is the default) Never
AVAILABLE PHYSICAL MEMORY Free physical memory, of the total, with the percent The system memory state says low

The timeline spans the ring buffer window, from its oldest record to the moment of the read, and has two lanes:

  • Resource monitor. Each low memory notification (RESOURCE_MEMPHYSICAL_LOW or RESOURCE_MEMVIRTUAL_LOW) is a tall mark: red for external (Windows), orange for internal (SQL Server), purple for both. Steady and high notifications are short gray ticks between them.
  • Broker shrinks. Each time a memory broker told a pool to shrink is a blue mark.

Hover a mark for its time, notification, meaning, NUMA nodes and available physical memory, or for a broker shrink its broker, pool, new target and allocation. Click a mark to pick its row in the grid, switching the grid to Pressure events or Memory broker when needed.

The guidance under the timeline says what the pressure points at:

  • External pressure (Windows reported low memory): another process on the server is using memory, or max server memory is set too high. When max server memory is at or above the server’s physical memory (including the unlimited default), it says nothing stops SQL Server taking memory the OS needs; otherwise it gives max server memory against physical memory.
  • Internal pressure (SQL Server ran short inside its own limit): look at large memory grants, plan cache bloat, and columnstore or In-Memory OLTP use.
  • A starved NUMA node: its page life expectancy is under half the best node’s, so queries running there are reading from disk far more than on the other nodes.
  • Memory grants pending right now, with a pointer to Memory Grants.

With no low memory notifications it says “No pressure events recorded since the ring buffer last wrapped.”

The NUMA nodes panel draws one bar per node: its total memory in blue, the foreign part of it (memory on another node) in green, and its target as an outline, with the total, target and page life expectancy printed beside it. A node whose page life expectancy is under half the best node’s is drawn in orange. With a single node nothing is compared, so nothing is flagged. Click a node to pick it in the NUMA nodes grid.


How events are counted

  • Pressure is a notification ending in _LOW. Steady and high notifications are listed, but are not pressure.
  • Internal means the record’s SQL Server indicators (IndicatorsProcess) are set; external means the Windows indicators (IndicatorsSystem) are set; both when both are.
  • A record’s time is the server clock at the read less the record’s age, so times are server time.
  • Identical notifications (the same notification and the same indicators) no more than one second apart are merged into one event, with their NUMA nodes combined, so a notice raised on every node at once is one event. The row’s tooltip says how many were merged.
  • A ring buffer record that cannot be parsed is counted rather than raised. If none can be read, the timeline says how many were unreadable.

The grids

Pressure events lists every resource monitor notification, newest first. Pressure rows have their notification, pressure and source in orange.

Column What it shows
Time Server time of the notification
Notification RESOURCE_MEMPHYSICAL_LOW, RESOURCE_MEMVIRTUAL_LOW, RESOURCE_MEMPHYSICAL_HIGH, RESOURCE_MEM_STEADY
Pressure Yes for a low memory notification
Source Internal, External, or Internal and external (pressure rows only)
SQL Server Indicators The process indicators: high, low physical, low virtual, or none
Windows Indicators The system indicators, in the same words
Nodes The NUMA nodes that raised it
Available Physical MB From the record’s memory section
Memory Utilization % From the record’s memory section
What It Means For example “Physical memory is low; SQL Server is releasing memory from its caches.”

Memory broker lists every broker decision, newest first. SHRINK notifications are in orange; picking one marks it on the timeline.

Column What it shows
Time Server time of the decision
Pool The pool id
Broker The broker, without its MEMORYBROKER_FOR_ prefix
Notification The broker’s notification, such as SHRINK
New Target (pages) The target the broker set
Allocated (pages) Currently allocated
Previously Allocated (pages) Allocated at the previous decision
Overall (pages) The overall figure in the record
Memory Ratio The memory ratio in the record

NUMA nodes lists one row per node from the Buffer Node and Memory Node counters, with locked pages (and anything the counters did not give) from sys.dm_os_memory_nodes. The dedicated admin connection’s node 64 is never listed.

Column What it shows
Node The node id
Total MB / Target MB Total and target node memory
Total of Target Total as a percent of target
Foreign MB Memory this node uses on another node
Free MB / Database MB / Stolen MB Free, database and stolen node memory
Locked Pages MB Locked page allocations on the node
Page Life Expectancy (s) The node’s page life expectancy
Database Pages Database pages cached on the node
Status “Page life expectancy under half the best node’s”, “Single node”, “Over a tenth of its memory is foreign”, or “OK”

A starved node has its page life expectancy and status in orange. Every grid exports to CSV and Excel like every other grid.


Last 7 days

When Historic Monitoring runs on the instance, the procedure trackMemoryPressure (added in DBHealthHistory version 1612) collects a sample from DatabaseHealthRunEvery2Minutes and trackEvery15Minutes, at most every four minutes:

Table What it keeps
MemoryPressureSample The system memory state, the process low flags, grants pending, total and target server memory, available and total physical memory
MemoryPressureNodeHistory Page life expectancy and total and target memory per NUMA node
MemoryClerkHistory The largest memory clerk types (at least 1 MB, top 20)
MemoryPressureEvent The low memory notifications, merged the same way the live page merges them

The history is kept for HistoricRetentionDays (45 days when it is not set, 0 keeps everything), but never less than 8 days. Rows are read for this server only.

The view shows:

  • cards: LOW MEMORY EVENTS (with how many were internal and external), LOWEST PAGE LIFE EXPECTANCY (the node and when), LOW MEMORY SAMPLES (samples where Windows said memory was low or a process low flag was set, of all samples), MOST GRANTS PENDING (and when), and COLLECTED (samples, and since when),
  • page life expectancy per NUMA node over the week, one line per node, with each low memory event as a vertical mark in the timeline’s colors and each low memory sample shaded along the top edge. A gap of more than 40 minutes between samples breaks the line rather than joining points nobody measured,
  • the guidance for the week, including the share of low memory samples and how many samples had a starved node,
  • the largest memory clerks (the six largest clerk types by average, in MB, hourly average),
  • the stored events in the grid, with the same columns as Pressure events.

Hover a line point for its value; click an event mark to pick it in the grid.

When the view has nothing to show, it says why: there is no DBHealthHistory database, this login cannot open it, DBHealthHistory is older than the memory pressure collection (connect with Historic Monitoring set up to upgrade it), or nothing has been collected yet.


Copying

Right-click the grid for Copy the findings as text, which copies the heading, the cards, the guidance, the pressure events newest first and each NUMA node’s memory and page life expectancy (on Last 7 days: the week’s cards, guidance, events and each node’s lowest page life expectancy). Right-click the chart, or use the grid’s menu, to copy the chart as a picture.


Permissions and versions

  • The report reads sys.dm_os_ring_buffers, sys.dm_os_memory_nodes, sys.dm_os_sys_memory, sys.dm_os_process_memory, sys.dm_os_sys_info and sys.dm_os_performance_counters, which need VIEW SERVER STATE (VIEW SERVER PERFORMANCE STATE on SQL Server 2022 and later). Without it the page says “The memory pressure information could not be read from this instance.” with the permission it needs and what the server said. When the connection check already knows the login lacks it, the menu item is shown muted and says what it needs when clicked.
  • There is no version gate: every view in the main read exists on SQL Server 2008 and later. The newer sys.dm_os_memory_nodes columns are checked first, and if that view cannot be read the NUMA panel says so while the rest of the page still shows.
  • The Last 7 days view needs DBHealthHistory version 1612 or later on the instance and access to it.
  • Each read has a 60 second timeout.

  • Memory for how memory is split right now.
  • Memory Grants and Spills for the grants behind internal pressure and grants pending.
  • Plan Cache for plan cache bloat.
  • Buffer Pool by Object for what is in the buffer pool behind a low page life expectancy.
  • Configuration Values for max server memory behind external pressure.
  • Waits for what queries are waiting on while memory is short.