MySQL and MariaDB Performance Tuning for Low-Memory VPS: Configuration for 1-2 GB RAM Servers

Running MySQL or MariaDB on a 1-2 GB VPS requires deliberate configuration. Default installation values assume a dedicated server with 8-16 GB of RAM, which guarantees swap usage, OOM-killer intervention, and unpredictable query latency on a constrained VPS. This guide provides a production-tested configuration for low-memory environments, covering memory budgeting, InnoDB tuning, connection limits, and verification steps — all validated for VPS instances with 1-2 GB RAM.

Calculate Your Memory Budget First

Before touching any MySQL configuration file, calculate your available memory. On a 2 GB VPS running Nginx, PHP-FPM, and MySQL, the database should use at most 500-800 MB. Rough breakdown: 200 MB for the operating system, 200-300 MB for Nginx plus PHP-FPM, and a 100-200 MB buffer for peak traffic. The remaining 900-1300 MB is the hard ceiling for MySQL.

# Check current memory usage
free -h
# Check MySQL connection and buffer usage
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';"
mysql -e "SHOW VARIABLES LIKE 'thread_stack';"
mysql -e "SHOW VARIABLES LIKE 'sort_buffer_size';"
mysql -e "SHOW VARIABLES LIKE 'join_buffer_size';"

InnoDB Buffer Pool: The Most Important Setting

The InnoDB buffer pool is the single largest memory consumer in MySQL and the most impactful tuning lever. On a 1-2 GB VPS, set innodb_buffer_pool_size to 25-40% of total RAM. For a 1 GB VPS, use 256 MB. For a 2 GB VPS, use 512-768 MB. Too high causes swapping; too low degrades read performance because every query hits disk.

[mysqld]
# 2 GB VPS: 512 MB buffer pool
innodb_buffer_pool_size = 512M
# 1 GB VPS: 256 MB
# innodb_buffer_pool_size = 256M

# Disable buffer pool dump/load at shutdown (saves memory on small VPS)
innodb_buffer_pool_dump_at_shutdown = OFF
innodb_buffer_pool_load_at_startup = OFF

InnoDB Log File and Flush Settings

Log file size directly impacts write performance and crash recovery time. On a low-memory VPS, set innodb_log_file_size to 64-128 MB — large enough to absorb write bursts, small enough to keep memory usage in check. Keep innodb_log_buffer_size at 8-16 MB; larger values waste memory for typical low-concurrency workloads.

innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
# Safer flush for VPS: guarantees no data loss on crash
innodb_flush_log_at_trx_commit = 1
# O_DIRECT bypasses the OS page cache, ideal for VPS with limited RAM
innodb_flush_method = O_DIRECT

Connection and Thread Tuning

Every MySQL connection consumes memory for thread stacks, sort buffers, and temporary tables. Limit max_connections to 50-100 on a 1-2 GB VPS and lower per-connection buffers so a connection storm cannot exhaust RAM. Set thread_cache_size to 8-16 to reduce connection churn.

max_connections = 50
thread_cache_size = 8
thread_stack = 192K
sort_buffer_size = 2M
read_buffer_size = 128K
read_rnd_buffer_size = 256K
join_buffer_size = 128K
tmp_table_size = 32M
max_heap_table_size = 32M

Query Cache and Performance Schema

The query cache is deprecated in MySQL 8.0 and removed in MariaDB 10.6+, so leave it disabled. The Performance Schema also consumes significant memory — on a 1 GB VPS where you don’t need detailed profiling, disabling it frees 100-200 MB.

# Disable deprecated query cache (MySQL 8.0 / MariaDB 10.6+)
query_cache_type = 0
query_cache_size = 0

# Optional: disable performance schema on 1 GB VPS
# performance_schema = OFF

Verify and Monitor After Changes

Apply the configuration, restart MySQL, and verify the server stays within your memory budget under load. Run MySQLTuner periodically to catch regressions after software updates.

systemctl restart mysql
# Confirm memory usage is stable
ps aux | grep mysql
# Run MySQLTuner for recommendations
wget -q https://github.com/major/MySQLTuner-perl/raw/master/mysqltuner.pl
perl mysqltuner.pl --noprofile

Complete my.cnf Template for a 2 GB VPS

[mysqld]
innodb_buffer_pool_size = 512M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
innodb_buffer_pool_dump_at_shutdown = OFF
innodb_buffer_pool_load_at_startup = OFF
max_connections = 50
thread_cache_size = 8
thread_stack = 192K
sort_buffer_size = 2M
read_buffer_size = 128K
read_rnd_buffer_size = 256K
join_buffer_size = 128K
tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0
query_cache_size = 0
key_buffer_size = 8M

This configuration keeps MySQL within 600-700 MB on a 2 GB VPS, leaving comfortable headroom for the web server, application layer, and operating system. For more server-level optimization ideas, see our VPS features overview and provider comparisons.

Leave a Reply