Memory on Linux is managed in pages, normally 4 KB each. A server with 16 GB of RAM has millions of them, and translating addresses for all those pages costs CPU time. Huge pages (typically 2 MB) reduce that overhead. There are two mechanisms: static HugePages (reserved explicitly) and Transparent Huge Pages (THP) (automatic). Databases have strong opinions about both.

Why it matters

  • The CPU caches address translations in the TLB (translation lookaside buffer). With bigger pages, fewer entries cover more memory, so there are fewer TLB misses, which helps large-memory workloads.
  • But THP’s background work (compacting memory to create huge pages, and splitting them) can cause latency spikes and memory bloat for some databases.

Check the current THP setting

cat /sys/kernel/mm/transparent_hugepage/enabled
# [always] madvise never     ← the bracketed value is active
cat /sys/kernel/mm/transparent_hugepage/defrag
grep -i huge /proc/meminfo
Value Meaning
always Kernel uses huge pages wherever it can
madvise Only for memory regions where the application asks (madvise())
never Disabled

Ubuntu and Debian default to madvise on recent releases. Others may use always.

What databases recommend

Software Recommendation (check current docs for your version)
Redis / Valkey Disable THP (never); Redis logs a warning when THP is always (latency and copy-on-write memory issues during persistence)
MongoDB Historically disable THP; newer versions (8.0+) recommend enabling it. Follow your version’s production notes
PostgreSQL THP madvise or never; optionally use static HugePages via huge_pages = try
MySQL / MariaDB Usually disable THP; static large pages optional
Java apps Optional: -XX:+UseTransparentHugePages or static pages

madvise is a good general default: applications that benefit can opt in, and others are unaffected.

Change THP at runtime

echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo defer+madvise | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

Make it permanent

Option 1: kernel command line (GRUB):

sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/&transparent_hugepage=madvise /' /etc/default/grub
sudo update-grub && sudo reboot

Option 2: a small systemd unit that sets it at boot:

# /etc/systemd/system/thp-madvise.service
[Unit]
Description=Set THP to madvise
After=sysinit.target local-fs.target
Before=redis-server.service mongod.service postgresql.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo madvise > /sys/kernel/mm/transparent_hugepage/enabled'

[Install]
WantedBy=basic.target
sudo systemctl daemon-reload && sudo systemctl enable --now thp-madvise

See systemd unit files.

Static HugePages (PostgreSQL example)

Reserve huge pages for PostgreSQL’s shared memory:

# PostgreSQL 15+: how many pages it needs (server stopped or using -C)
sudo -u postgres /usr/lib/postgresql/16/bin/postgres -D /var/lib/postgresql/16/main -C shared_memory_size_in_huge_pages
echo "vm.nr_hugepages = 1100" | sudo tee /etc/sysctl.d/60-hugepages.conf
sudo sysctl --system

In postgresql.conf: huge_pages = try (or on, to fail if unavailable). Restart PostgreSQL, and check HugePages_Free in /proc/meminfo.

Reserved huge pages are unavailable to other programs, even when unused. Only reserve what the database needs. See PostgreSQL performance tuning.

On a VPS

THP and HugePages work inside a KVM VPS, since you control your own kernel. Gains are most noticeable for databases with large buffer pools (several GB). For small instances, leaving THP at madvise is the sensible choice. See what is KVM virtualization.

Quick reference

Task Command / file
THP status cat /sys/kernel/mm/transparent_hugepage/enabled
Set THP now echo madvise | sudo tee …/enabled
Permanent GRUB transparent_hugepage=madvise or systemd unit
Huge page stats grep -i huge /proc/meminfo
Reserve static pages vm.nr_hugepages in sysctl

Related: Redis maxmemory and eviction and Linux memory usage.

  • Linux
  • Performance
  • Databases