Optimize Linux memory subsystem performance through advanced swap configuration, virtual memory tuning, and memory compression techniques. Learn to configure transparent huge pages, zram, and application-specific memory settings for high-performance workloads.
Prerequisites
- Root or sudo access
- Basic understanding of Linux system administration
- Familiarity with command line operations
What this solves
Linux memory management directly impacts application performance, system responsiveness, and workload throughput. Poor memory configuration can lead to excessive swapping, memory pressure, and Out of Memory (OOM) kills that crash critical applications. This tutorial shows you how to optimize Linux memory subsystem settings, configure intelligent swap strategies, and implement memory compression to maximize performance for high-throughput workloads like databases, web servers, and analytics platforms.
Step-by-step configuration
Install memory monitoring tools
Install essential tools for monitoring memory usage, pressure, and swap activity.
sudo apt update
sudo apt install -y htop iotop sysstat procps util-linux
Analyze current memory configuration
Examine your system's current memory usage patterns, swap configuration, and pressure indicators before making changes.
free -h
cat /proc/meminfo | grep -E 'MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree'
swapon --show
cat /proc/swaps
vmstat 1 5
Configure swap file optimization
Create an optimally-sized swap file with proper placement and permissions. Size should be 1-2x RAM for systems with 8GB+ RAM, or equal to RAM for smaller systems.
# Disable existing swap if present
sudo swapoff -a
Remove old swap entries from fstab
sudo cp /etc/fstab /etc/fstab.backup
sudo sed -i '/swap/d' /etc/fstab
Create optimized swap file (adjust size as needed - this creates 4GB)
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Add to /etc/fstab for persistence
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Configure memory management sysctl parameters
Optimize virtual memory settings for high-performance workloads. These settings control swap behavior, memory overcommit, and memory reclaim strategies.
# Swap behavior optimization
Reduce swappiness for better performance (default is 60)
vm.swappiness=10
Only swap when under severe memory pressure
vm.vfs_cache_pressure=50
Memory overcommit strategy
0 = heuristic overcommit (default)
1 = always overcommit
2 = strict accounting (recommended for critical systems)
vm.overcommit_memory=2
vm.overcommit_ratio=80
Dirty page handling for better I/O performance
vm.dirty_ratio=15
vm.dirty_background_ratio=5
vm.dirty_expire_centisecs=3000
vm.dirty_writeback_centisecs=500
Memory reclaim optimization
vm.min_free_kbytes=65536
vm.zone_reclaim_mode=0
OOM killer tuning
vm.panic_on_oom=0
vm.oom_kill_allocating_task=1
Shared memory optimization
kernel.shmmax=68719476736
kernel.shmall=4294967296
sudo sysctl -p /etc/sysctl.d/99-memory-optimization.conf
sudo sysctl --system
Configure transparent huge pages
Optimize transparent huge pages (THP) settings. While THP can improve performance for some workloads, databases often perform better with THP disabled to avoid memory fragmentation and latency spikes.
# Check current THP status
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongod.service mysqld.service postgresql.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null'
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/defrag > /dev/null'
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable disable-thp.service
sudo systemctl start disable-thp.service
Install and configure zram for memory compression
Set up zram to provide compressed RAM-based swap that's faster than disk-based swap and increases effective memory capacity.
sudo apt install -y zram-tools
# Configuration for zram swap
Percentage of RAM to use for zram (50% recommended)
PERCENT=50
Compression algorithm (lz4 is fastest, zstd has better ratio)
ALGO=lz4
Priority (higher than disk swap)
PRIORITY=100
sudo systemctl enable zramswap
sudo systemctl start zramswap
Verify zram setup
zramctl
swapon --show
Configure memory pressure monitoring
Set up monitoring for memory pressure events and OOM conditions to track optimization effectiveness.
[Unit]
Description=Memory Pressure Monitor
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/memory-monitor.sh
Restart=always
RestartSec=30
User=root
[Install]
WantedBy=multi-user.target
#!/bin/bash
Memory pressure monitoring script
LOGFILE="/var/log/memory-monitor.log"
THRESHOLD_FREE_MB=500
THRESHOLD_SWAP_PERCENT=50
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# Get memory info
MEM_FREE=$(free -m | awk 'NR==2{printf "%d", $7}')
SWAP_TOTAL=$(free -m | awk 'NR==3{printf "%d", $2}')
SWAP_USED=$(free -m | awk 'NR==3{printf "%d", $3}')
if [ $SWAP_TOTAL -gt 0 ]; then
SWAP_PERCENT=$(( (SWAP_USED * 100) / SWAP_TOTAL ))
else
SWAP_PERCENT=0
fi
# Check for memory pressure
if [ $MEM_FREE -lt $THRESHOLD_FREE_MB ] || [ $SWAP_PERCENT -gt $THRESHOLD_SWAP_PERCENT ]; then
echo "$TIMESTAMP WARNING: Memory pressure detected - Free: ${MEM_FREE}MB, Swap Used: ${SWAP_PERCENT}%" >> $LOGFILE
# Log top memory consumers
echo "$TIMESTAMP Top memory processes:" >> $LOGFILE
ps aux --sort=-%mem | head -6 >> $LOGFILE
echo "---" >> $LOGFILE
fi
sleep 60
done
sudo chmod +x /usr/local/bin/memory-monitor.sh
sudo systemctl enable memory-monitor.service
sudo systemctl start memory-monitor.service
Configure OOM killer optimization
Fine-tune the Out of Memory killer to protect critical system processes and terminate resource-heavy applications appropriately.
#!/bin/bash
Protect critical system processes from OOM killer
for pid in $(pgrep -f "systemd|kernel|kthreadd|ksoftirqd|migration|rcu_|watchdog"); do
echo -1000 > /proc/$pid/oom_score_adj 2>/dev/null || true
done
Protect SSH daemon
for pid in $(pgrep sshd); do
echo -900 > /proc/$pid/oom_score_adj 2>/dev/null || true
done
Make memory-intensive applications more likely to be killed
for service in mysql postgresql redis elasticsearch; do
for pid in $(pgrep $service); do
echo 200 > /proc/$pid/oom_score_adj 2>/dev/null || true
done
done
sudo chmod +x /usr/local/bin/oom-score-tuning.sh
Add to crontab to run on boot and periodically
echo '@reboot /usr/local/bin/oom-score-tuning.sh' | sudo crontab -
echo '/10 * /usr/local/bin/oom-score-tuning.sh' | sudo crontab -
Configure application-specific memory settings
Apply memory optimizations for common high-performance applications. These settings should be adjusted based on your specific workload requirements.
# Memory-related limits for applications
Format: domain type item value
Increase memory lock limits for databases
* soft memlock 64
* hard memlock 64
Increase virtual memory limits
* soft as unlimited
* hard as unlimited
Increase stack size for applications
* soft stack 8192
* hard stack 32768
Specific limits for database users
mysql soft memlock unlimited
mysql hard memlock unlimited
postgres soft memlock unlimited
postgres hard memlock unlimited
# Application-specific memory tuning
Increase shared memory for databases
kernel.shmmax=137438953472
kernel.shmall=33554432
Network buffer optimization
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
Process scheduling for memory-intensive workloads
kernel.sched_migration_cost_ns=5000000
kernel.sched_autogroup_enabled=0
sudo sysctl -p /etc/sysctl.d/99-app-memory.conf
Apply configuration and reboot
Apply all memory management configurations and restart the system to ensure all settings take effect properly.
# Verify all sysctl settings are loaded
sudo sysctl --system
Check memory configuration
free -h
cat /proc/sys/vm/swappiness
cat /proc/sys/vm/overcommit_memory
Reboot to ensure all settings are applied
sudo reboot
Verify your setup
After reboot, verify that all memory optimizations are working correctly and monitoring systems are active.
# Check memory and swap status
free -h
swapon --show
zramctl
Verify sysctl settings
sysctl vm.swappiness
sysctl vm.overcommit_memory
sysctl vm.dirty_ratio
Check transparent huge pages status
cat /sys/kernel/mm/transparent_hugepage/enabled
Verify services are running
sudo systemctl status zramswap
sudo systemctl status memory-monitor
sudo systemctl status disable-thp
Check memory pressure monitoring
sudo tail -f /var/log/memory-monitor.log
Test memory pressure response
stress --vm 2 --vm-bytes 1G --timeout 30s
Performance benchmarking
Use these commands to benchmark memory performance and validate your optimizations.
# Memory bandwidth test
sudo apt install -y sysbench
sysbench memory --memory-total-size=2G run
I/O performance with memory pressure
sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
sysbench fileio --file-total-size=2G --file-test-mode=rndrw run
sysbench fileio --file-total-size=2G --file-test-mode=rndrw cleanup
Monitor memory during benchmarks
watch -n 1 'free -h && echo && cat /proc/pressure/memory'
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| High swap usage despite available RAM | vm.swappiness too high | Set vm.swappiness=10 in sysctl configuration |
| OOM killer killing wrong processes | Default OOM scores | Run oom-score-tuning.sh to protect critical processes |
| Memory allocation failures | Strict overcommit policy | Adjust vm.overcommit_ratio or use vm.overcommit_memory=0 |
| Poor database performance | Transparent huge pages enabled | Disable THP using the systemd service |
| zram not working after reboot | Service not enabled | sudo systemctl enable zramswap |
| Memory pressure not detected | Monitoring thresholds too low | Adjust THRESHOLD values in memory-monitor.sh |
Next steps
- Configure Linux performance monitoring with collectd and InfluxDB for real-time metrics collection
- Optimize Linux system performance with kernel parameters and system tuning
- Set up Prometheus and Grafana monitoring stack with Docker compose
- Configure Linux NUMA optimization for multi-socket servers
- Implement Linux memory cgroups for container workload isolation
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Global variables
SWAP_SIZE=${1:-4G}
TOTAL_STEPS=7
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
usage() {
echo "Usage: $0 [SWAP_SIZE]"
echo " SWAP_SIZE: Size of swap file (default: 4G)"
echo " Examples: $0 8G, $0 2G"
exit 1
}
cleanup() {
print_error "Script failed. Cleaning up..."
if [ -f /swapfile.new ]; then
sudo swapoff /swapfile.new 2>/dev/null || true
sudo rm -f /swapfile.new
fi
if [ -f /etc/sysctl.d/99-memory-optimization.conf.new ]; then
sudo rm -f /etc/sysctl.d/99-memory-optimization.conf.new
fi
exit 1
}
trap cleanup ERR
check_prerequisites() {
if [[ $EUID -ne 0 ]] && ! sudo -n true 2>/dev/null; then
print_error "This script requires root privileges or passwordless sudo"
exit 1
fi
if [[ "$SWAP_SIZE" =~ ^[0-9]+[GMK]?$ ]]; then
:
else
print_error "Invalid swap size format. Use format like 4G, 8G, 2048M"
usage
fi
}
detect_distro() {
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
PROCPS_PKG="procps"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
PROCPS_PKG="procps-ng"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
PROCPS_PKG="procps-ng"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
else
print_error "Cannot detect distribution"
exit 1
fi
print_success "Detected distribution: $PRETTY_NAME"
}
install_monitoring_tools() {
echo "[1/$TOTAL_STEPS] Installing memory monitoring tools..."
print_status "Updating package repositories..."
sudo $PKG_UPDATE > /dev/null 2>&1
print_status "Installing monitoring tools..."
sudo $PKG_INSTALL htop iotop sysstat $PROCPS_PKG util-linux > /dev/null 2>&1
print_success "Memory monitoring tools installed"
}
analyze_current_memory() {
echo "[2/$TOTAL_STEPS] Analyzing current memory configuration..."
print_status "Current memory status:"
free -h
echo
print_status "Current swap configuration:"
swapon --show 2>/dev/null || echo "No swap currently active"
print_success "Memory analysis complete"
}
configure_swap() {
echo "[3/$TOTAL_STEPS] Configuring optimized swap file..."
# Backup fstab
sudo cp /etc/fstab /etc/fstab.backup.$(date +%Y%m%d_%H%M%S)
# Disable existing swap
if swapon --show | grep -q "/swapfile"; then
print_status "Disabling existing swap..."
sudo swapoff /swapfile 2>/dev/null || true
fi
# Remove old swap entries from fstab
sudo sed -i.bak '/\/swapfile.*swap/d' /etc/fstab
# Create new swap file
print_status "Creating ${SWAP_SIZE} swap file..."
sudo fallocate -l "$SWAP_SIZE" /swapfile.new
sudo chmod 600 /swapfile.new
sudo mkswap /swapfile.new > /dev/null 2>&1
# Replace old swap file
if [ -f /swapfile ]; then
sudo rm /swapfile
fi
sudo mv /swapfile.new /swapfile
# Enable swap
sudo swapon /swapfile
# Add to fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab > /dev/null
print_success "Swap file configured successfully"
}
configure_memory_parameters() {
echo "[4/$TOTAL_STEPS] Configuring memory management parameters..."
# Create sysctl configuration
sudo tee /etc/sysctl.d/99-memory-optimization.conf.new > /dev/null << 'EOF'
# Memory Management Optimization for High-Performance Workloads
# Swap behavior optimization
vm.swappiness=10
vm.vfs_cache_pressure=50
# Memory overcommit strategy (strict accounting)
vm.overcommit_memory=2
vm.overcommit_ratio=80
# Dirty page handling for better I/O performance
vm.dirty_ratio=15
vm.dirty_background_ratio=5
vm.dirty_expire_centisecs=3000
vm.dirty_writeback_centisecs=500
# Memory reclaim optimization
vm.min_free_kbytes=65536
vm.zone_reclaim_mode=0
# OOM killer tuning
vm.panic_on_oom=0
vm.oom_kill_allocating_task=1
# Shared memory optimization
kernel.shmmax=68719476736
kernel.shmall=4294967296
EOF
sudo mv /etc/sysctl.d/99-memory-optimization.conf.new /etc/sysctl.d/99-memory-optimization.conf
sudo chmod 644 /etc/sysctl.d/99-memory-optimization.conf
# Apply settings
sudo sysctl -p /etc/sysctl.d/99-memory-optimization.conf > /dev/null 2>&1
print_success "Memory management parameters configured"
}
configure_transparent_hugepages() {
echo "[5/$TOTAL_STEPS] Configuring Transparent Huge Pages..."
# Create systemd service to disable THP
sudo tee /etc/systemd/system/disable-thp.service > /dev/null << 'EOF'
[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongod.service mysqld.service postgresql.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null'
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/defrag > /dev/null'
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
EOF
sudo chmod 644 /etc/systemd/system/disable-thp.service
sudo systemctl daemon-reload
sudo systemctl enable disable-thp.service > /dev/null 2>&1
sudo systemctl start disable-thp.service > /dev/null 2>&1
print_success "Transparent Huge Pages disabled"
}
configure_zram() {
echo "[6/$TOTAL_STEPS] Installing and configuring zram..."
# Install zram-tools based on distro
if [[ "$PKG_MGR" == "apt" ]]; then
sudo $PKG_INSTALL zram-tools > /dev/null 2>&1
# Configure zram
sudo tee /etc/default/zramswap > /dev/null << 'EOF'
ALGO=lz4
PERCENT=25
SIZE=1024M
EOF
sudo systemctl enable zramswap > /dev/null 2>&1
sudo systemctl start zramswap > /dev/null 2>&1
else
# For RHEL-based systems, use zram-generator
sudo $PKG_INSTALL zram-generator > /dev/null 2>&1
sudo mkdir -p /etc/systemd/zram-generator.conf.d
sudo tee /etc/systemd/zram-generator.conf.d/zram-swap.conf > /dev/null << 'EOF'
[zram0]
zram-size = min(ram / 4, 2048)
compression-algorithm = lz4
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now systemd-zram-setup@zram0.service > /dev/null 2>&1
fi
print_success "zram configured for memory compression"
}
verify_configuration() {
echo "[7/$TOTAL_STEPS] Verifying configuration..."
print_status "Checking swap configuration:"
swapon --show
echo
print_status "Checking memory parameters:"
sysctl vm.swappiness vm.vfs_cache_pressure vm.overcommit_memory
echo
print_status "Checking Transparent Huge Pages:"
cat /sys/kernel/mm/transparent_hugepage/enabled
echo
print_status "Checking zram:"
if command -v zramctl > /dev/null; then
zramctl 2>/dev/null || echo "zram devices not yet initialized"
fi
print_success "Configuration verification complete"
}
main() {
echo "Linux Memory Management Optimization Script"
echo "==========================================="
echo
check_prerequisites
detect_distro
install_monitoring_tools
analyze_current_memory
configure_swap
configure_memory_parameters
configure_transparent_hugepages
configure_zram
verify_configuration
echo
print_success "Memory optimization completed successfully!"
print_warning "Some changes require a reboot to take full effect"
print_status "Monitor your system performance and adjust parameters as needed"
}
main "$@"
Review the script before running. Execute with: bash install.sh