| Tested on | Rocky Linux 10.2 (Red Quartz) |
|---|---|
| Package | grubby 8.40tuned |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora |
| Privilege | sudo or root |
| Scope | Check, disable or set Transparent HugePages to madvise on RHEL 8–10, Rocky Linux, AlmaLinux, CentOS Stream and Oracle Linux. |
| Related guides | HugePages vs Transparent HugePages how to check Transparent HugePages in Linux GRUB2 and grubby guide Transparent HugePages decision guide Configure static HugePages on RHEL 7 |
Transparent HugePages let the kernel back eligible memory regions with larger pages automatically. Larger pages can reduce translation lookaside buffer misses, but THP allocation and memory compaction can also introduce latency for some workloads.
RHEL 8, 9, and 10 enable THP by default and support always, madvise, and never through runtime sysfs settings, TuneD, kernel command-line parameters, or a systemd unit. never is not automatically the best setting. Follow the current recommendation for your exact application version and validate the result with workload testing.
always, madvise, or never according to the current guidance for your application version and confirm the result with workload testing. See the Transparent HugePages decision guide for database-specific recommendations and performance considerations.
Transparent HugePages modes compared
| Mode | Kernel behavior | Typical reason to use it |
|---|---|---|
always |
Kernel attempts to use THP for eligible memory regions | Workloads known to benefit from automatic huge-page allocation |
madvise |
THP is primarily used for memory regions explicitly marked by applications | Selective use without system-wide aggressive allocation |
never |
Disables automatic THP allocation through the normal system policy | Application guidance requires it or testing shows latency problems |
defrag setting |
Controls memory compaction policy for obtaining huge pages | Tune allocation latency separately from the main THP mode |
enabled and defrag are related but separate controls.
| Transparent HugePages | Static HugeTLB |
|---|---|
| Automatically allocated by the kernel | Reserved explicitly |
| Normally backs anonymous memory automatically | Applications must be configured to use the reserved pool |
| Swappable in supported scenarios | Reserved HugeTLB memory is normally non-swappable |
| Controlled through THP sysfs and boot options | Controlled with hugepages, hugepagesz and related settings |
For the full comparison, see HugePages vs Transparent HugePages.
Check the current THP mode and usage
Read the allocation mode first.
cat /sys/kernel/mm/transparent_hugepage/enabledSample output:
[always] madvise neverThe value in square brackets is the active mode.
Check the compaction policy separately.
cat /sys/kernel/mm/transparent_hugepage/defragSample output:
always defer defer+madvise [madvise] neverCheck shared-memory THP policy when the kernel exposes it:
if [[ -f /sys/kernel/mm/transparent_hugepage/shmem_enabled ]]; then
cat /sys/kernel/mm/transparent_hugepage/shmem_enabled
fiInspect the running kernel command line.
cat /proc/cmdlineSample output:
BOOT_IMAGE=(hd0,gpt2)/vmlinuz-6.12.0-211.28.1.el10_2.x86_64 root=/dev/mapper/rlm-root ro resume=UUID=26765c90-fea0-4216-9293-9936cabf9135 rd.lvm.lv=rlm/rootCheck the default boot entry when no explicit transparent_hugepage= argument is present.
grubby --info="$(grubby --default-kernel)"Check whether TuneD is managing host tuning.
systemctl is-active tunedSample output:
activetuned-adm activeSample output:
Current active profile: balancedReview current THP memory counters.
grep -E 'AnonHugePages|ShmemHugePages|FileHugePages' /proc/meminfoSample output:
AnonHugePages: 399360 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kBgrep -E 'nr_anon_transparent_hugepages|thp_' /proc/vmstatSample output:
nr_anon_transparent_hugepages 195
thp_migration_success 0
thp_migration_fail 0
thp_migration_split 0
thp_fault_alloc 81100On newer RHEL 10 kernels, check whether multi-size THP directories are available:
find /sys/kernel/mm/transparent_hugepage \
-maxdepth 1 \
-type d \
-name 'hugepages-*' \
-printSample output:
/sys/kernel/mm/transparent_hugepage/hugepages-2048kB
/sys/kernel/mm/transparent_hugepage/hugepages-1024kB
/sys/kernel/mm/transparent_hugepage/hugepages-512kBView the anonymous THP count for each supported page size:
grep -H . \
/sys/kernel/mm/transparent_hugepage/hugepages-*/stats/nr_anon \
2>/dev/nullSample output:
/sys/kernel/mm/transparent_hugepage/hugepages-2048kB/stats/nr_anon:195
/sys/kernel/mm/transparent_hugepage/hugepages-1024kB/stats/nr_anon:0Check the per-size allocation policy:
grep -H . \
/sys/kernel/mm/transparent_hugepage/hugepages-*/enabled \
2>/dev/nullThe top-level enabled file primarily describes the global anonymous-memory policy. On newer kernels, also inspect shmem_enabled and each hugepages-*/enabled file. A top-level value of [never] does not by itself prove that every form and size of THP is disabled.
AnonHugePages and VM counters show current or historical usage. AnonHugePages in /proc/meminfo primarily reports traditional PMD-sized anonymous THP. Use the per-size statistics when multi-size THP is available. AnonHugePages: 0 kB does not by itself prove THP is disabled, and non-zero usage can remain after a runtime change until existing processes release or remap their memory. For per-process usage, see how to check Transparent HugePages in Linux.
Change Transparent HugePages temporarily
Runtime changes take effect immediately for new allocation decisions but do not survive reboot.
Set always:
echo always | sudo tee \
/sys/kernel/mm/transparent_hugepage/enabledSet madvise:
echo madvise | sudo tee \
/sys/kernel/mm/transparent_hugepage/enabledDisable automatic anonymous THP allocation through the top-level policy:
echo never | sudo tee \
/sys/kernel/mm/transparent_hugepage/enabledTo also disable direct memory compaction during a latency-sensitive test, set the THP defrag policy to never.
echo never | sudo tee \
/sys/kernel/mm/transparent_hugepage/defragVerify both values after a temporary change.
cat /sys/kernel/mm/transparent_hugepage/enabledcat /sys/kernel/mm/transparent_hugepage/defragSample output after setting never:
always madvise [never]Configure THP permanently with grubby
grubby is the supported persistent method on current RHEL-family releases with GRUB Boot Loader Specification entries.
Inspect all boot entries before changing kernel arguments.
grubby --info=ALL | grep -E '^kernel=|^args='Sample output:
kernel="/boot/vmlinuz-6.12.0-211.28.1.el10_2.x86_64"
args="ro resume=UUID=26765c90-fea0-4216-9293-9936cabf9135 rd.lvm.lv=rlm/root"
kernel="/boot/vmlinuz-6.12.0-211.16.1.el10_2.0.1.x86_64"
args="ro resume=UUID=26765c90-fea0-4216-9293-9936cabf9135 rd.lvm.lv=rlm/root"Remove an existing THP argument before changing modes.
sudo grubby \
--remove-args="transparent_hugepage" \
--update-kernel=ALLPermanently disable THP
sudo grubby \
--args="transparent_hugepage=never" \
--update-kernel=ALLPermanently set THP to madvise
sudo grubby \
--args="transparent_hugepage=madvise" \
--update-kernel=ALLPermanently enable THP
sudo grubby \
--args="transparent_hugepage=always" \
--update-kernel=ALL--update-kernel=ALL updates every installed boot entry so an older kernel does not boot with a different THP mode.
Verify before reboot:
grubby --info=ALL | grep -E '^kernel=|transparent_hugepage'Reboot to apply the boot-time setting:
sudo rebootRed Hat documents persistent THP changes with grubby using transparent_hugepage=always, transparent_hugepage=madvise, or transparent_hugepage=never, followed by a reboot.
Do not use grub2-editenv - set ... or manually rewrite the entire kernelopts value on current GRUB/BLS systems. That approach is error-prone and can remove unrelated kernel arguments. When using grubby as shown here, do not also run grub2-mkconfig; use one boot-argument management method consistently.
For general kernel-argument management on RHEL 8 and later, see the GRUB2 and grubby guide. This article does not cover the legacy RHEL 7 bootloader workflow.
Check TuneD for conflicting THP settings
TuneD profiles can configure THP persistently and may restore a value that differs from a manually selected mode.
Identify the active profile:
tuned-adm activeRecord the active profile before creating or enabling custom-thp; you will need it when restoring the previous configuration.
Inspect the active profile and included profiles:
tuned-adm profile_infoSearch TuneD configuration for THP settings:
grep -RniE \
'transparent_hugepages|transparent_hugepage' \
/etc/tuned /usr/lib/tuned /usr/lib/tuned/profilesSample output on Rocky Linux 10.2:
/usr/lib/tuned/profiles/network-latency/tuned.conf:10:transparent_hugepages=never
/usr/lib/tuned/profiles/throughput-performance/tuned.conf:40:transparent_hugepages=never
/usr/lib/tuned/profiles/hpc-compute/tuned.conf:12:transparent_hugepages=alwaysIf TuneD should own the setting, create an administrator-managed custom profile rather than editing files under /usr/lib/tuned.
RHEL 10 and equivalent TuneD releases
Create the profile directory:
sudo mkdir -p /etc/tuned/profiles/custom-thpCreate /etc/tuned/profiles/custom-thp/tuned.conf with:
[main]
include=balanced
[vm]
transparent_hugepages=never
[bootloader]
cmdline=transparent_hugepage=neverthroughput-performance already sets transparent_hugepages=never in its [vm] section. Inheriting that profile while adding a different bootloader argument can produce conflicting THP policy. Use balanced or another base profile that does not already set THP unless you intend to match its value in both [vm] and [bootloader].
Activate the profile:
sudo tuned-adm profile custom-thpReboot so the bootloader argument takes effect:
sudo rebootVerify:
tuned-adm activecat /proc/cmdlinecat /sys/kernel/mm/transparent_hugepage/enabledFor madvise or always, replace never consistently in both the [vm] and [bootloader] sections.
RHEL 8 and RHEL 9 path
On the traditional TuneD layout, create the profile at:
/etc/tuned/custom-thp/tuned.confRHEL 10 stores distribution profiles under /usr/lib/tuned/profiles and custom profiles under /etc/tuned/profiles. Older RHEL documentation uses /usr/lib/tuned and /etc/tuned. A TuneD bootloader profile requires a reboot before its kernel argument takes effect.
Do not configure one mode through TuneD and another through a separate startup service. Database-specific TuneD profiles may intentionally modify THP. The primary persistent method in this article remains grubby unless your site standardizes on TuneD.
Verify THP after reboot
Verify the active kernel argument:
cat /proc/cmdlineVerify the configured mode:
cat /sys/kernel/mm/transparent_hugepage/enabledVerify the compaction setting:
cat /sys/kernel/mm/transparent_hugepage/defragWhen present, also verify shared-memory THP policy:
if [[ -f /sys/kernel/mm/transparent_hugepage/shmem_enabled ]]; then
cat /sys/kernel/mm/transparent_hugepage/shmem_enabled
fiCheck the default boot entry:
grubby --info="$(grubby --default-kernel)"Check current usage:
grep AnonHugePages /proc/meminfogrep nr_anon_transparent_hugepages /proc/vmstat| Result | Meaning |
|---|---|
always madvise [never] |
Automatic anonymous THP allocation is disabled by the top-level policy |
always [madvise] never |
Applications can request THP selectively |
[always] madvise never |
THP is enabled generally |
AnonHugePages: 0 kB |
No anonymous THP currently counted; not proof of configuration |
Non-zero AnonHugePages after disabling |
Existing processes may still hold THP mappings |
Restart the workload after changing THP before comparing application behavior.
Restore the default or change modes
If a custom TuneD profile controls THP, switch away from it first:
sudo tuned-adm profile <previous-profile>Replace <previous-profile> with the profile reported by tuned-adm active before you enabled custom-thp. Use balanced only when it was the original profile.
Alternatively, remove the THP settings from the custom profile and reactivate it.
Then remove the explicit kernel argument:
sudo grubby \
--remove-args="transparent_hugepage" \
--update-kernel=ALLReboot:
sudo rebootRemoving the kernel argument restores the distribution kernel default only when no active TuneD profile, systemd unit, or configuration-management policy applies another THP setting.
To switch directly from one explicit mode to another, remove the existing parameter first and then add the new value. That avoids duplicate kernel arguments such as:
transparent_hugepage=never transparent_hugepage=madviseTroubleshoot THP configuration
THP still shows always after reboot
Check the boot command line and boot entries:
cat /proc/cmdlinegrubby --info=ALL | grep -E '^kernel=|transparent_hugepage'tuned-adm activePossible causes include a parameter added only to one kernel entry, booting the wrong kernel, a TuneD override, duplicate THP arguments, skipping reboot, or a custom systemd service overwriting the setting after boot.
AnonHugePages remains non-zero
Existing mappings are not necessarily removed immediately. Restart the application and check again. A non-zero value does not by itself mean the boot setting failed unless /sys/kernel/mm/transparent_hugepage/enabled also shows the wrong mode.
enabled and defrag show different values
They control different decisions. enabled controls when THP allocations are permitted. defrag controls how aggressively the kernel compacts memory to satisfy them. They do not have to display the same active value.
The parameter disappears after a kernel update
Confirm the argument was applied with --update-kernel=ALL, then inspect whether TuneD or configuration-management tools replace boot arguments after package updates.
grubby --info=ALLApplication documentation conflicts with this article
Follow the current documentation for the exact application version and operating-system kernel, then benchmark the workload. See the Transparent HugePages decision guide for workload-specific recommendations.
| Symptom | Likely cause | Main check |
|---|---|---|
| Wrong mode after reboot | Kernel argument missing or TuneD override | /proc/cmdline, tuned-adm active |
| Duplicate modes | Old argument not removed | grubby --info=ALL |
| Usage remains non-zero | Existing mappings | Restart workload |
| Latency remains high | Compaction or unrelated memory pressure | Check defrag, VM counters and workload metrics |
| New kernel behaves differently | Boot entries differ | grubby --info=ALL |
Conclusion
Do not disable Transparent HugePages automatically. Choose always, madvise, or never using the Transparent HugePages decision guide, use sysfs for temporary testing, use grubby for persistent RHEL 8–10 configuration, and check TuneD for conflicting policy. Verify the active mode separately from current THP usage and restart affected applications before comparing results.
References
- Red Hat Enterprise Linux 10 — Configuring huge pages — runtime THP settings, TuneD, kernel parameters and systemd
- Linux kernel — Transparent Hugepage Support — THP modes, multi-size THP, monitoring and MADV_COLLAPSE behavior
- HugePages vs Transparent HugePages — conceptual differences and use cases
- Check Transparent HugePages in Linux — per-process THP usage
- Transparent HugePages decision guide — whether to disable or tune THP
- Configure static HugePages on RHEL 7 — HugeTLB reservation, not THP mode selection

