HugePages for PostgreSQL on Linux

Not satisfied with the instructions I found on setting up Linux HugePages for PostgreSQL, I wrote my own for our team.

Inside psql:
postgres=# select name, setting from pg_settings where name like '%huge%';
              name               | setting
---------------------------------+---------
huge_page_size                   | 0
huge_pages                       | try
huge_pages_status                | off
shared_memory_size_in_huge_pages | 72

Note the last line above. It’s much better to go by shared_memory_size_in_huge_pages than by shared_buffers, which is only part of the shared memory used by the Postgres instance (albeit the biggest part).

As root on the OS, try to set HugePages to 1 plus shared_memory_size_in_huge_pages:

# echo 73 > /proc/sys/vm/nr_hugepages; cat /proc/sys/vm/nr_hugepages

If cat shows less than you want, 73 here, try a few more times. If it's still less, you have to reboot because there's not enough contiguous free memory. But put vm.nr_hugepages = 73 in /etc/sysctl.conf before you reboot.[note1]

If you get 73, then

# grep ^Huge /proc/meminfo

It should show HugePages_Total, HugePages_Free, and HugePages_Rsvd as 73, 73, 0, respectively.

Bounce Postgres (we’re using version 17; the service name is found by systemctl list-units|grep progresql, if you don’t remember it):

# systemctl restart postgresql-17

Check HugePages again. HugePages_Free should be smaller and HugePages_Rsvd should be only 1 smaller than it, e.g.

# grep ^Huge /proc/meminfo
HugePages_Total: 73
HugePages_Free: 65
HugePages_Rsvd: 64
...

The difference between HugePages_Free and HugePages_Rsvd is the wastage (we intentionally waste 1 page as a guard), because HugePages_Free includes reserved but not actually used memory.[note2]

And inside psql, the query against pg_settings should show on for huge_pages_status.

If you have not done so, as root, add vm.nr_hugepages = 73 to /etc/sysctl.conf so HugePages will be reserved on future reboots.

Lastly, transparent HugePages causes sporadic CPU spikes, non-contiguous memory chunks, and other problems. It's strongly recommended we disable it. The new way to do so is

grubby --args="transparent_hugepage=never" --update-kernel ALL
followed by reboot. Before and after reboot, you can check by
cat /sys/kernel/mm/transparent_hugepage/enabled #should have [always] before reboot, [never] after
grep AnonHugePages /proc/meminfo #should have a non-zero value before reboot, 0 after
cat /proc/cmdline #should have transparent_hugepage=never appended after reboot
If the above grubby command doesn't work, see Section 7 of the article on Oracle HugePages for older Linux versions.

If you change shared_buffers in Postgres, check the pg_settings view again to get a new shared_memory_size_in_huge_pages, and set HugePages at the OS level accordingly again.

In case you ask why HugePages: These memory pages are locked in system memory and have much bigger page size than the default, so it benefits software programs that demand a large amount of memory such as a database. Using HugePages reduces sys (kernel) CPU usage thus improves system performance.

__________________________

[note1]
Ideally, you need to do more work to ensure HugePages is properly set up. For example, postgres soft memlock limit and postgres hard memlock limit should be added to /etc/security/limits.conf, where limit can just be the system memory in KB to make it simple (it's meaningless but harmless to set it bigger than that).
In /etc/sysctl.conf, kernel.shmmax should be set to a large number, which can be system memory in bytes (note: not KB!).
session required pam_limits.so should be added to /etc/pam.d/login.
But if HugePages already works, these settings become optional.

[note2]
To understand the 3 lines of HugePages_* in /proc/meminfo, look at this simple diagram

UUUUUFFFF <-- Total split into really used (U) and free (F)
UUUUURRR. <-- Total split into really used (U), reserved (R) and really free (.)
If one letter or dot is one HugePage, the above says
HugePages_Total: 9
HugePages_Free:  4
HugePages_Rsvd:  3
and you’ll have 4–3=1 page completely wasted.


August 2026
(originally posted on LinkedIn)

Contact me
To my Computer Page