Configure Linux transparent huge pages and memory optimization for database workloads

Advanced 25 min Apr 17, 2026 27 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Learn to configure transparent huge pages (THP) and optimize Linux memory management for database workloads. Covers THP disable/enable strategies, performance monitoring, and automation with systemd.

Prerequisites

  • Root or sudo access
  • Basic understanding of Linux memory management
  • Database workload running on the system

What this solves

Transparent Huge Pages (THP) can significantly impact database performance, causing memory fragmentation and unpredictable latency spikes. This tutorial shows you how to configure THP settings, optimize memory allocation for database workloads, and implement monitoring to track performance impact across different database systems.

Understanding transparent huge pages

Check current THP status

First, examine your system's current transparent huge pages configuration to understand the baseline.

cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
grep -i hugepages /proc/meminfo

Monitor THP allocation statistics

View detailed statistics about huge page allocation and fragmentation events.

cat /proc/vmstat | grep -E "thp_|hugepages"
cat /sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed
cat /sys/kernel/mm/transparent_hugepage/khugepaged/full_scans

Step-by-step THP configuration

Create THP management script

Create a comprehensive script to manage transparent huge pages settings dynamically.

sudo mkdir -p /usr/local/bin
sudo tee /usr/local/bin/thp-manager.sh
#!/bin/bash

THP Manager Script for Database Workloads

Usage: thp-manager.sh [disable|enable|madvise|status]

THP_ENABLED="/sys/kernel/mm/transparent_hugepage/enabled" THP_DEFRAG="/sys/kernel/mm/transparent_hugepage/defrag" THP_KHUGEPAGED="/sys/kernel/mm/transparent_hugepage/khugepaged" set_thp_status() { local mode=$1 case $mode in "disable") echo "never" > $THP_ENABLED echo "never" > $THP_DEFRAG echo "THP disabled completely" ;; "enable") echo "always" > $THP_ENABLED echo "always" > $THP_DEFRAG echo "THP enabled with aggressive allocation" ;; "madvise") echo "madvise" > $THP_ENABLED echo "madvise" > $THP_DEFRAG echo "THP set to application-controlled mode" ;; esac } show_status() { echo "=== Transparent Huge Pages Status ===" echo "Enabled: $(cat $THP_ENABLED)" echo "Defrag: $(cat $THP_DEFRAG)" echo "khugepaged scan pages: $(cat $THP_KHUGEPAGED/pages_to_scan)" echo "khugepaged scan sleep: $(cat $THP_KHUGEPAGED/scan_sleep_millisecs)ms" echo echo "=== Memory Statistics ===" grep -E "HugePages_|AnonHugePages" /proc/meminfo echo echo "=== THP Events ===" grep -E "thp_" /proc/vmstat | head -10 } optimize_khugepaged() { # Optimize khugepaged for database workloads echo 4096 > $THP_KHUGEPAGED/pages_to_scan echo 1000 > $THP_KHUGEPAGED/scan_sleep_millisecs echo 32 > $THP_KHUGEPAGED/alloc_sleep_millisecs echo "khugepaged optimized for database workloads" } case "$1" in disable) set_thp_status "disable" ;; enable) set_thp_status "enable" optimize_khugepaged ;; madvise) set_thp_status "madvise" optimize_khugepaged ;; status) show_status ;; *) echo "Usage: $0 {disable|enable|madvise|status}" echo " disable - Completely disable THP (recommended for most databases)" echo " enable - Enable THP with aggressive allocation" echo " madvise - Enable THP only when requested by applications" echo " status - Show current THP configuration and statistics" exit 1 ;; esac
sudo chmod +x /usr/local/bin/thp-manager.sh

Configure THP for database workloads

Most database systems perform better with THP disabled due to memory fragmentation issues.

# Check current status
sudo /usr/local/bin/thp-manager.sh status

Disable THP for database workloads (recommended)

sudo /usr/local/bin/thp-manager.sh disable

Verify the change

sudo /usr/local/bin/thp-manager.sh status

Create persistent THP configuration

Make THP settings persistent across reboots using kernel parameters and systemd service.

# Update GRUB configuration
sudo tee -a /etc/default/grub.d/thp.cfg
# Disable Transparent Huge Pages for database workloads
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT transparent_hugepage=never"
sudo update-grub
# Update GRUB configuration
sudo tee -a /etc/default/grub.d/thp.cfg
# Disable Transparent Huge Pages for database workloads
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT transparent_hugepage=never"
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Create systemd service for THP management

Create a systemd service to apply THP settings early in the boot process as a backup to kernel parameters.

sudo tee /etc/systemd/system/thp-config.service
[Unit]
Description=Configure Transparent Huge Pages for Database Workloads
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/thp-manager.sh disable
TimeoutSec=30
RemainAfterExit=yes

[Install]
WantedBy=basic.target
sudo systemctl enable thp-config.service
sudo systemctl daemon-reload

Database-specific optimization strategies

Configure memory allocation for PostgreSQL

Optimize PostgreSQL memory settings when THP is disabled to prevent performance degradation.

sudo tee /etc/sysctl.d/99-postgresql-memory.conf
# PostgreSQL memory optimization with THP disabled

Reduce memory fragmentation

vm.swappiness = 10

Optimize dirty page handling

vm.dirty_ratio = 15 vm.dirty_background_ratio = 5 vm.dirty_expire_centisecs = 3000 vm.dirty_writeback_centisecs = 500

Memory allocation optimization

vm.overcommit_memory = 2 vm.overcommit_ratio = 80

Shared memory settings

kernel.shmmax = 17179869184 kernel.shmall = 4194304 kernel.shmmni = 4096
sudo sysctl --load=/etc/sysctl.d/99-postgresql-memory.conf

Configure memory settings for Redis

Redis requires specific memory optimizations when running without THP support.

sudo tee /etc/sysctl.d/99-redis-memory.conf
# Redis memory optimization with THP disabled

Enable memory overcommit (required for Redis background saves)

vm.overcommit_memory = 1

Optimize for Redis memory patterns

vm.swappiness = 1 vm.vfs_cache_pressure = 50

Network buffer optimization for Redis replication

net.core.somaxconn = 65535 net.core.tcp_max_syn_backlog = 65535
sudo sysctl --load=/etc/sysctl.d/99-redis-memory.conf

Configure MongoDB memory optimization

MongoDB has specific requirements when THP is disabled to maintain performance.

sudo tee /etc/sysctl.d/99-mongodb-memory.conf
# MongoDB memory optimization with THP disabled

Optimize for MongoDB's memory access patterns

vm.swappiness = 1 vm.dirty_ratio = 15 vm.dirty_background_ratio = 5

Reduce zone reclaim for NUMA systems

vm.zone_reclaim_mode = 0

Network optimization for MongoDB clusters

net.core.somaxconn = 4096 net.ipv4.tcp_keepalive_time = 300
sudo sysctl --load=/etc/sysctl.d/99-mongodb-memory.conf

Monitoring THP performance impact

Create THP monitoring script

Implement comprehensive monitoring to track THP impact on database performance.

sudo tee /usr/local/bin/thp-monitor.sh
#!/bin/bash

THP Performance Monitor

Collects THP statistics and memory fragmentation metrics

TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') LOGFILE="/var/log/thp-monitor.log" log_metrics() { echo "=== THP Metrics - $TIMESTAMP ===" >> $LOGFILE # Basic THP status echo "THP_ENABLED: $(cat /sys/kernel/mm/transparent_hugepage/enabled)" >> $LOGFILE echo "THP_DEFRAG: $(cat /sys/kernel/mm/transparent_hugepage/defrag)" >> $LOGFILE # Memory statistics grep -E "AnonHugePages|HugePages_" /proc/meminfo >> $LOGFILE # THP allocation statistics grep -E "thp_fault_alloc|thp_fault_fallback|thp_collapse_alloc" /proc/vmstat >> $LOGFILE # Memory fragmentation echo "FRAGMENTATION_INDEX:" >> $LOGFILE cat /sys/kernel/debug/extfrag/extfrag_index 2>/dev/null | head -5 >> $LOGFILE # Buddy allocator info echo "BUDDY_INFO:" >> $LOGFILE cat /proc/buddyinfo >> $LOGFILE echo "" >> $LOGFILE } generate_report() { echo "=== THP Performance Report - $TIMESTAMP ===" # Calculate THP efficiency FAULT_ALLOC=$(grep thp_fault_alloc /proc/vmstat | awk '{print $2}') FAULT_FALLBACK=$(grep thp_fault_fallback /proc/vmstat | awk '{print $2}') if [ "$FAULT_ALLOC" -gt 0 ] && [ "$FAULT_FALLBACK" -gt 0 ]; then TOTAL_ATTEMPTS=$((FAULT_ALLOC + FAULT_FALLBACK)) SUCCESS_RATE=$((FAULT_ALLOC * 100 / TOTAL_ATTEMPTS)) echo "THP Success Rate: $SUCCESS_RATE%" fi # Memory pressure indicators DIRECT_RECLAIM=$(grep pgsteal_direct /proc/vmstat | awk '{print $2}') KSWAPD_RECLAIM=$(grep pgsteal_kswapd /proc/vmstat | awk '{print $2}') echo "Direct Reclaim Events: $DIRECT_RECLAIM" echo "kswapd Reclaim Events: $KSWAPD_RECLAIM" # Current memory usage echo "" echo "Current Memory Usage:" free -h echo "" echo "Memory Fragmentation (lower is better):" awk '/Node 0/ && /DMA32|Normal/ {print $1 " " $2 ": " $NF}' /proc/buddyinfo 2>/dev/null || echo "Fragmentation data not available" } case "$1" in log) log_metrics ;; report) generate_report ;; watch) watch -n 5 "$0 report" ;; *) echo "Usage: $0 {log|report|watch}" echo " log - Log current metrics to $LOGFILE" echo " report - Generate performance report" echo " watch - Continuously monitor (5-second intervals)" exit 1 ;; esac
sudo chmod +x /usr/local/bin/thp-monitor.sh
sudo touch /var/log/thp-monitor.log

Set up automated THP monitoring

Configure systemd timer to regularly collect THP performance metrics.

sudo tee /etc/systemd/system/thp-monitor.service
[Unit]
Description=THP Performance Monitoring
After=multi-user.target

[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/thp-monitor.sh log
StandardOutput=journal
StandardError=journal
sudo tee /etc/systemd/system/thp-monitor.timer
[Unit]
Description=THP Performance Monitoring Timer
Requires=thp-monitor.service

[Timer]
OnBootSec=5min
OnUnitActiveSec=10min
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl enable thp-monitor.timer
sudo systemctl start thp-monitor.timer
sudo systemctl daemon-reload

Configure logrotate for THP monitoring

Prevent THP monitoring logs from consuming excessive disk space.

sudo tee /etc/logrotate.d/thp-monitor
/var/log/thp-monitor.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
    postrotate
        systemctl reload rsyslog > /dev/null 2>&1 || true
    endscript
}

Advanced memory optimization techniques

Configure NUMA memory policy

On NUMA systems, configure memory policies to optimize database performance with disabled THP.

# Check NUMA topology
numactl --hardware

Configure NUMA-aware memory allocation

sudo tee /etc/sysctl.d/99-numa-memory.conf
# NUMA memory optimization for databases

Disable zone reclaim to prevent remote memory access penalties

vm.zone_reclaim_mode = 0

Optimize NUMA balancing for database workloads

kernel.numa_balancing = 0

Memory allocation preferences

vm.numa_zonelist_order = Node
sudo sysctl --load=/etc/sysctl.d/99-numa-memory.conf

Implement memory pressure monitoring

Set up monitoring for memory pressure indicators that can impact database performance.

sudo tee /usr/local/bin/memory-pressure-check.sh
#!/bin/bash

Memory Pressure Monitoring for Database Systems

WARN_THRESHOLD=80 CRIT_THRESHOLD=95 check_memory_pressure() { # Get memory usage percentage MEMORY_USAGE=$(free | awk 'NR==2{printf "%.0f", $3*100/$2}') # Check swap usage SWAP_USAGE=$(free | awk 'NR==3{if($2>0) printf "%.0f", $3*100/$2; else print "0"}') # Get memory pressure stall information (if available) if [ -f /proc/pressure/memory ]; then PRESSURE_AVG10=$(awk '/some/ {print $2}' /proc/pressure/memory | cut -d'=' -f2) PRESSURE_TOTAL=$(awk '/some/ {print $4}' /proc/pressure/memory | cut -d'=' -f2) fi # Check for memory fragmentation FRAGMENTATION=$(awk '/Node 0.*Normal/ {print $(NF-1)}' /proc/buddyinfo 2>/dev/null | head -1) echo "Memory Usage: ${MEMORY_USAGE}%" echo "Swap Usage: ${SWAP_USAGE}%" if [ ! -z "$PRESSURE_AVG10" ]; then echo "Memory Pressure (10s avg): ${PRESSURE_AVG10}%" fi # Alert conditions if [ "$MEMORY_USAGE" -ge "$CRIT_THRESHOLD" ]; then echo "CRITICAL: Memory usage above ${CRIT_THRESHOLD}%" logger "CRITICAL: High memory usage detected: ${MEMORY_USAGE}%" elif [ "$MEMORY_USAGE" -ge "$WARN_THRESHOLD" ]; then echo "WARNING: Memory usage above ${WARN_THRESHOLD}%" logger "WARNING: Memory usage elevated: ${MEMORY_USAGE}%" fi if [ "$SWAP_USAGE" -gt "10" ]; then echo "WARNING: Swap usage detected: ${SWAP_USAGE}%" logger "WARNING: System using swap memory: ${SWAP_USAGE}%" fi } check_memory_pressure
sudo chmod +x /usr/local/bin/memory-pressure-check.sh

Verify your setup

Verify THP configuration

Confirm that transparent huge pages are properly configured for your database workload.

# Check THP status
sudo /usr/local/bin/thp-manager.sh status

Verify kernel parameters will persist after reboot

grep transparent_hugepage /proc/cmdline

Check systemd service status

sudo systemctl status thp-config.service

Monitor performance impact

Generate a performance report and verify monitoring is working correctly.

# Generate current performance report
sudo /usr/local/bin/thp-monitor.sh report

Check monitoring timer status

sudo systemctl status thp-monitor.timer

View recent monitoring data

sudo tail -20 /var/log/thp-monitor.log

Test memory pressure monitoring

sudo /usr/local/bin/memory-pressure-check.sh

Test database performance

Run basic performance tests to verify the THP configuration benefits your database workload. This setup improves database performance by reducing memory fragmentation and eliminating THP-related latency spikes that can impact query response times.

# Check system memory allocation efficiency
grep -E "thp_fault_fallback|thp_fault_alloc" /proc/vmstat

Monitor memory fragmentation

cat /proc/buddyinfo | awk '{print $1, $2, $NF}'

Check for memory reclaim events (should be minimal)

grep -E "pgsteal_|pgscan_" /proc/vmstat

Common issues

SymptomCauseFix
THP settings reset after rebootKernel parameters not persistentCheck GRUB configuration and run sudo update-grub (Ubuntu) or sudo grub2-mkconfig (RHEL)
High memory fragmentationTHP disabled without memory optimizationApply database-specific sysctl settings in /etc/sysctl.d/
Database performance degraded after THP disableMissing memory allocation tuningConfigure vm.overcommit_memory and vm.swappiness for your database type
Memory pressure alertsInsufficient RAM for workloadAdd more memory or tune database memory limits using memory-pressure-check.sh
THP monitoring not workingSystemd timer not enabledsudo systemctl enable --now thp-monitor.timer
NUMA performance issuesZone reclaim enabledSet vm.zone_reclaim_mode = 0 in sysctl configuration
Never use chmod 777. When fixing permission issues with log files or scripts, use specific permissions like 644 for files and 755 for executables, combined with proper ownership using chown.

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed cloud infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.