How to check Transparent HugePages in Linux

Last reviewed: by
How to check Transparent HugePages in Linux

Transparent HugePages (THP) is a Linux memory-management feature that can back anonymous memory with larger pages, commonly 2 MB instead of normal 4 KB pages. Larger pages can reduce Translation Lookaside Buffer (TLB) overhead for workloads that scan or keep large memory regions hot, such as databases, virtual machines, JVMs, analytics jobs, and some high-performance services.

This guide shows how to check whether THP is enabled, how to check static hugepage status, how to read system-wide AnonHugePages, and how to identify per-process Transparent HugePage usage with smaps and smaps_rollup. The sample outputs below were tested on a Linux host, including a practical process that requested THP with madvise.


THP vs static hugepages

Linux has two related but different hugepage mechanisms:

Feature Kernel/user-facing counter How it is allocated Typical use
Transparent HugePages (THP) AnonHugePages, FileHugePages, ShmemHugePages Kernel-managed, transparent or requested with madvise General large anonymous memory mappings
Static HugeTLB pages HugePages_Total, HugePages_Free, vm.nr_hugepages Manually reserved hugepage pool Databases, VMs, DPDK, workloads that explicitly use HugeTLB

Do not treat HugePages_Total: 0 as proof that THP is disabled. It only means no static HugeTLB pages are reserved. THP can still be enabled and used through AnonHugePages.

For background on memory pages and Linux memory accounting, see Linux memory management overview. For CPU support and hugepage sizes, see how to check CPU support for hugepages.


Quick commands

Goal Command
Check THP mode cat /sys/kernel/mm/transparent_hugepage/enabled
Check THP defrag mode cat /sys/kernel/mm/transparent_hugepage/defrag
Check default THP page size cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
Check system-wide hugepage counters grep -i huge /proc/meminfo
Check static HugeTLB setting sysctl vm.nr_hugepages vm.nr_overcommit_hugepages
Check per-process THP usage grep AnonHugePages /proc/PID/smaps_rollup
Sum per-process mappings awk '/^AnonHugePages:/ {sum += $2} END {print sum " kB"}' /proc/PID/smaps

Check Transparent HugePages mode

Read /sys/kernel/mm/transparent_hugepage/enabled:

console
$ cat /sys/kernel/mm/transparent_hugepage/enabled
always [madvise] never

The active mode is shown in square brackets. In this tested output, madvise is active.

Mode Meaning
always Kernel tries to use THP for eligible mappings automatically
madvise THP is used for mappings that request it with madvise(MADV_HUGEPAGE)
never THP is disabled for normal anonymous mappings

Check the THP defrag policy:

console
$ cat /sys/kernel/mm/transparent_hugepage/defrag
always defer defer+madvise [madvise] never

The active defrag mode is also shown in square brackets. In this tested output, madvise is active.

Defrag controls how aggressively the kernel compacts memory to create hugepage-sized contiguous ranges. Aggressive defrag can improve THP allocation success but may add latency for some workloads.


Check THP page size

The PMD-sized THP page size is exposed in bytes:

console
$ cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
2097152

2097152 bytes is 2 MB. That is the common THP size on x86_64 systems.


Check system-wide hugepage counters

Use /proc/meminfo to see both Transparent HugePages and static HugeTLB counters:

console
$ grep -i huge /proc/meminfo
AnonHugePages:      2048 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB

Important fields:

Field Meaning
AnonHugePages Anonymous memory currently backed by THP
ShmemHugePages Shared memory/tmpfs memory backed by huge pages
FileHugePages File-backed memory backed by huge pages
HugePages_Total Number of static HugeTLB pages reserved
HugePages_Free Static HugeTLB pages currently free
HugePages_Rsvd Static HugeTLB pages reserved for future faults
HugePages_Surp Static HugeTLB pages above the configured pool
Hugepagesize Default static hugepage size
Hugetlb Total memory consumed by HugeTLB pages

In the tested output, static hugepages are not reserved because HugePages_Total is 0. THP is still present because AnonHugePages is 2048 kB.


Check static hugepage configuration

Static HugeTLB pages are controlled by vm.nr_hugepages and related settings:

console
$ sysctl vm.nr_hugepages vm.nr_overcommit_hugepages
vm.nr_hugepages = 0
vm.nr_overcommit_hugepages = 0

Here, vm.nr_hugepages = 0 means the kernel has not reserved a static HugeTLB pool. That does not disable THP. Static hugepages and THP are separate mechanisms.

To configure static hugepages, see how to configure HugePages using hugeadm and vm.nr_hugepages.


Check NUMA node hugepage counters

On NUMA systems, node-level memory files show hugepage counters per node:

console
$ grep -i huge /sys/devices/system/node/node*/meminfo
Node 0 AnonHugePages:      2048 kB
Node 0 ShmemHugePages:        0 kB
Node 0 FileHugePages:         0 kB
Node 0 HugePages_Total:     0
Node 0 HugePages_Free:      0
Node 0 HugePages_Surp:      0

This is useful when a multi-socket or NUMA host shows THP usage on one node but not another. The tested host has one visible NUMA node, node0.


Practical test: create THP-backed memory

A passive system may show little or no AnonHugePages at the moment you check. To prove how per-process THP accounting works, start a temporary process that requests THP with madvise(MADV_HUGEPAGE), touches 128 MB of anonymous memory, and sleeps while you inspect it.

console
$ python3 - <<'PY' &
import ctypes, mmap, os, time
size = 128 * 1024 * 1024
mm = mmap.mmap(-1, size, flags=mmap.MAP_PRIVATE | mmap.MAP_ANONYMOUS)
addr = ctypes.addressof(ctypes.c_char.from_buffer(mm))
libc = ctypes.CDLL('libc.so.6', use_errno=True)
ret = libc.madvise(ctypes.c_void_p(addr), ctypes.c_size_t(size), ctypes.c_int(14))
print(os.getpid(), ret, ctypes.get_errno(), flush=True)
for off in range(0, size, 4096):
    mm[off] = 1
time.sleep(90)
PY
62725 0 0
$ PID=$!
$ echo "$PID"
62725

The Python process printed 62725 0 0. The first value is the process ID, the second value is the madvise() return code, and the third value is errno. Return code 0 and errno 0 mean the madvise() call succeeded.

Check basic memory information for the process:

console
$ grep '^VmRSS\|^RssAnon\|^Threads' /proc/$PID/status
VmRSS:    140736 kB
RssAnon:  134252 kB
Threads:       1

The process has one thread and about 134 MB of anonymous resident memory.


Check per-process THP usage with smaps_rollup

For a quick per-process total, use /proc/PID/smaps_rollup:

console
$ grep -E '^(Rss|Pss|AnonHugePages):' /proc/$PID/smaps_rollup
Rss:              140736 kB
Pss:              138266 kB
AnonHugePages:     88064 kB

In this tested output, the process uses 88064 kB of anonymous Transparent HugePages. This value can be lower than the process RSS because not every mapped page must be backed by THP.


Check per-process THP usage with smaps

You can also sum every AnonHugePages line in /proc/PID/smaps:

console
$ awk '/^AnonHugePages:/ {sum += $2} END {print sum " kB"}' /proc/$PID/smaps
88064 kB

The summed value matches smaps_rollup for the tested process.

To see which mapping uses THP:

console
$ awk '/^[0-9a-f].*-/{map=$0} /^AnonHugePages:/ && $2>0 {print $0; print map; print ""}' /proc/$PID/smaps | head -n 10
AnonHugePages:     88064 kB
787fe9c00000-787ff1c00000 rw-p 00000000 00:00 0 

This shows the mapping that has non-zero AnonHugePages.


Check system-wide THP after the test

While the test process is running, system-wide AnonHugePages increases:

console
$ grep -i '^AnonHugePages' /proc/meminfo
AnonHugePages:     90112 kB

This is system-wide THP usage. It includes the test process and any other process using anonymous THP at that moment.


Find all processes using Transparent HugePages

Use this loop to scan processes with readable smaps_rollup and print only processes with non-zero AnonHugePages:

console
$ for f in /proc/[0-9]*/smaps_rollup; do
>   pid=${f#/proc/}; pid=${pid%/smaps_rollup}
>   kb=$(awk '/^AnonHugePages:/ {print $2}' "$f" 2>/dev/null || true)
>   if [ -n "$kb" ] && [ "$kb" -gt 0 ]; then
>     comm=$(ps -p "$pid" -o comm= 2>/dev/null || true)
>     printf '%-8s %10s kB %s\n' "$pid" "$kb" "$comm"
>   fi
> done | sort -k2,2nr | head -n 5
62725         88064 kB python3
35249          2048 kB hugo

The tested output shows the temporary Python process using 88064 kB of THP and a separate hugo process using 2048 kB.

If you get permission errors, run as root or use sudo. Some kernels and security settings restrict access to other users' smaps files.

For general per-process memory checks, see how to check memory usage per process in Linux.


Interpret common results

Result Meaning
enabled shows always [madvise] never THP is enabled only for mappings that request it with madvise
enabled shows [never] THP is disabled for normal anonymous mappings
HugePages_Total: 0 No static HugeTLB pages are reserved
AnonHugePages: 0 kB No anonymous THP is currently in use, or none is visible to that counter at the moment
Per-process AnonHugePages is non-zero That process has memory backed by THP
smaps_rollup missing or unreadable Kernel is old, process exited, or permissions block access

Should Transparent HugePages be enabled?

There is no universal answer. THP can help workloads with large contiguous memory access patterns, but it can hurt latency-sensitive workloads if memory compaction causes stalls. That is why many database products document specific THP recommendations.

General guidance:

  • Use madvise when you want applications to opt in to THP.
  • Use always only after testing workload latency and memory behavior.
  • Use never when the application vendor recommends disabling THP or when THP causes measurable latency spikes.
  • Use static HugeTLB pages when an application explicitly requires reserved hugepages.

To disable THP persistently on RHEL/CentOS-style systems, see how to disable Transparent HugePages on RHEL 8.


Troubleshooting

Problem Likely cause Fix
AnonHugePages stays at 0 No eligible workload is using THP Use a workload that requests THP or set THP mode appropriately in a test environment
THP is enabled but process usage is 0 Process has not touched enough anonymous memory, or mode is madvise and the app did not request THP Check the process memory pattern and application settings
HugePages_Total is 0 Static HugeTLB pool is not configured This is normal if you only care about THP; configure vm.nr_hugepages only for static hugepages
Permission denied reading smaps Access to another process' memory map is restricted Run as root or inspect a process owned by your user
Values change between commands THP allocation and collapse can happen while the process runs Re-run the command or monitor over time

Frequently Asked Questions

1. What is the fastest way to check if Transparent HugePages are enabled?

Read /sys/kernel/mm/transparent_hugepage/enabled. The active mode is shown in square brackets, such as always [madvise] never.

2. Does HugePages_Total equal Transparent HugePages usage?

No. HugePages_Total shows static HugeTLB pages reserved through nr_hugepages. Transparent HugePages usage is usually shown by AnonHugePages in /proc/meminfo and per-process smaps files.

3. What does AnonHugePages mean in Linux?

AnonHugePages is anonymous memory currently backed by Transparent HugePages. System-wide usage is in /proc/meminfo, while per-process usage is in smaps or smaps_rollup.

4. Why is AnonHugePages zero when Transparent HugePages are enabled?

THP being enabled does not guarantee current usage. The workload must allocate suitable anonymous memory, touch it, and either match the system policy or request THP with madvise when the mode is madvise.

5. How do I check which process is using Transparent HugePages?

Read /proc/PID/smaps_rollup for AnonHugePages, or sum AnonHugePages entries in /proc/PID/smaps. A loop over proc smaps_rollup files can find processes using THP.

6. What is vm.nr_hugepages?

vm.nr_hugepages controls the number of static HugeTLB pages reserved by the kernel. It is separate from Transparent HugePages.

Summary

Use cat /sys/kernel/mm/transparent_hugepage/enabled to check the THP mode. Use grep -i huge /proc/meminfo to compare Transparent HugePages counters such as AnonHugePages with static HugeTLB counters such as HugePages_Total. Use /proc/PID/smaps_rollup or /proc/PID/smaps to prove which process is actually using THP.

The most important distinction is this: vm.nr_hugepages and HugePages_Total are for static HugeTLB pages, while AnonHugePages shows Transparent HugePages currently in use.


References

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, …

  • Red Hat Certified System Administrator in Red Hat OpenStack
  • Certified Kubernetes Application Developer (CKAD)
  • Red Hat Certified Specialist in Ansible Automation
  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security