A low-memory VPS can run Debian 12 and a database, but stability depends on the whole workload—not just MySQL’s configured cache. When available memory runs out, Linux may invoke the out-of-memory (OOM) killer, which terminates a process to protect the rest of the system. If that process is the database, the symptom can look like a random crash. The practical goal is to prevent sustained memory pressure and confirm what the kernel actually killed; no tuning setting can guarantee that OOM events will never occur.
Is Debian 12 running MySQL, or MariaDB?
Check the server before changing its configuration. Debian 12 (Bookworm) uses MariaDB for the default default-mysql-server package; Oracle MySQL is a separate installation path. Debian’s package information lists MariaDB as that metapackage’s server dependency. Run:
mariadb --version
mysql --version
dpkg-query -W -f='${Package} ${Version}\n' mariadb-server mysql-community-server 2>/dev/null
Use the MariaDB instructions below only if the installed service is MariaDB. Oracle MySQL uses compatible-looking option names in many cases, but package layouts, service names, available variables, and defaults can differ. Consult the manual for the exact MySQL release installed.
Primary references: Debian Bookworm’s default-mysql-server package and the MySQL 8.0 memory-use manual.
How can you tell whether OOM killed the database?
First distinguish a kernel OOM kill from a database error, service restart, reboot, or disk problem. On Debian, journalctl reads systemd’s journal. Search the current boot and inspect MariaDB’s service log:
sudo journalctl -k -b --no-pager | grep -Ei 'out of memory|oom-kill|killed process'
sudo journalctl -u mariadb -b --no-pager -n 100
sudo systemctl status mariadb --no-pager
If the kernel log names mariadbd or mysqld after an OOM message, you have evidence of a memory kill. If there is no matching entry, check the service’s own error log and the provider’s reboot or monitoring history. Logs may be unavailable after a reboot if journaling is not persistent, and a managed VPS provider may expose only part of the host’s diagnostics.
Capture a baseline while the server is under representative traffic, not only while idle:
free -h
swapon --show
vmstat 1
ps -eo pid,comm,rss,%mem --sort=-rss | head
In vmstat, watch the si and so columns for sustained swap-in and swap-out activity. A nonzero swap allocation by itself does not prove a problem; ongoing swapping together with slow response times indicates memory pressure. Linux documents OOM handling as a last-resort response when memory cannot be reclaimed sufficiently. See the Linux kernel memory-management concepts and Debian’s journalctl manual.
What should you measure before tuning?
Record total RAM, current and peak swap use, the biggest resident processes, database connections, and the web application’s normal peak. The database shares memory with Debian, the web server, application workers, monitoring agents, and filesystem cache. A VPS can also have a container or cgroup memory limit lower than the host’s physical RAM; size database caches to the memory limit visible to the service, not a larger host total.
For MariaDB, inspect current memory-related settings and connection peak:
sudo mariadb -e "SHOW VARIABLES WHERE Variable_name IN ('innodb_buffer_pool_size','max_connections','tmp_table_size','max_heap_table_size'); SHOW GLOBAL STATUS LIKE 'Max_used_connections'; SHOW GLOBAL STATUS LIKE 'Threads_connected';"
The InnoDB buffer pool caches table and index pages. Connection limits and query buffers can add memory demand as concurrent work increases. Avoid multiplying every per-connection buffer by max_connections as if every buffer were always fully allocated, but do treat a very high connection ceiling as a risk under bursts. MariaDB’s memory guide recommends sizing global caches, per-connection buffers, and engine settings together, and specifically calls out application connection pools. Read MariaDB’s memory allocation guide and its guide to handling too many connections.
How do you right-size MariaDB on a small VPS?
Make one change at a time, keep a copy of the original configuration, and test during a maintenance window if a restart would affect users. Debian’s packaged MariaDB configuration commonly includes files under /etc/mysql/mariadb.conf.d/; verify the active include directories on your installation before editing. A small drop-in file is easier to remove than replacing the vendor’s main file:
sudo cp -a /etc/mysql/mariadb.conf.d /root/mariadb.conf.d.backup
sudoedit /etc/mysql/mariadb.conf.d/90-low-memory.cnf
For a shared VPS with around 1 GiB of RAM, the following is only a cautious starting example—not a universal safe profile. Lower or raise values based on measured peak memory, database size, workload, and the RAM left for the operating system and application:
[mariadb]
innodb_buffer_pool_size = 192M
max_connections = 30
tmp_table_size = 16M
max_heap_table_size = 16M
MariaDB reads settings from option files at startup; verify your version’s supported section names and effective values. If this file fails to load, remove the drop-in and review the journal. Restarting the database interrupts existing connections, so schedule it appropriately:
sudo systemctl restart mariadb
sudo systemctl is-active mariadb
sudo journalctl -u mariadb -b --no-pager -n 80
sudo mariadb -e "SELECT @@innodb_buffer_pool_size, @@max_connections;"
Judge the result by both stability and service quality. A smaller buffer pool may reduce cache hits and increase disk reads. Lowering max_connections too far may instead produce “Too many connections” errors. Compare Max_used_connections with the configured limit and review application pool sizes before changing that limit again. If the database is still killed during normal peak traffic, or response time degrades from sustained disk swapping, move to a larger RAM tier or separate the database from the application.
Can swap prevent an OOM crash?
Swap gives Linux a slower place to move some memory pages and can absorb a brief peak. It does not add fast RAM, fix a leak, or make an undersized VPS suitable for a sustained workload. Heavy swapping can make both the database and application unresponsive. Check whether your provider supports swap files and whether the VPS has enough disk space before creating one.
If supported, a 1 GiB swap file can be created as follows. Adjust the size to the provider’s guidance and available disk, and verify each command’s result:
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
swapon --show
To enable it after reboot, add this entry to /etc/fstab after checking that an equivalent entry is not already present:
/swapfile none swap sw 0 0
Then validate the file with sudo findmnt --verify --verbose and confirm it appears in swapon --show. If fallocate is unsupported by the filesystem or the provider blocks swap, stop and use the provider’s supported procedure. Do not disable the OOM killer or assign an extreme OOM protection score to MySQL: that does not create memory and can leave the rest of a small VPS at greater risk.
How do you know the changes worked?
Observe the VPS through at least one normal busy period. A useful result has several signs:
- No new kernel OOM-kill entries during the workload that previously triggered the incident.
- MariaDB stays active and its restart count does not rise unexpectedly.
vmstat 1 does not show continuous swap-in and swap-out under ordinary traffic.- The application remains responsive, and database connection peaks stay below the new cap without connection errors.
- Backups complete and database queries continue to meet the application’s acceptable latency.
Do not use “the service starts” as the only success test. A setting that keeps MariaDB alive but pushes the system into constant swapping has not solved the underlying capacity problem. Likewise, one quiet day does not validate a monthly import, backup, traffic spike, or batch job that has not yet run.
When is tuning no longer the right fix?
Choose a larger VPS or move workloads apart when memory stays pressured after reasonable cache and concurrency adjustments, swap activity is sustained, query latency becomes unacceptable, or the app repeatedly hits the new connection limit. Database size matters too: an overly small buffer pool can avoid a memory spike while making disk I/O the new bottleneck. If the app and database have sharp but predictable peaks, first determine whether the application is opening excess connections or running memory-heavy jobs concurrently.
On Oracle MySQL rather than Debian’s default MariaDB, confirm the service name, option-file path, and memory variables against that server’s own versioned manual before applying these examples. On either engine, retain tested backups and change one variable at a time. The reliable outcome is not a promise that Linux will never invoke OOM handling; it is evidence that the VPS has enough headroom for its real peak workload and that MySQL or MariaDB is no longer the recurring victim.
Additional primary references: MariaDB’s startup troubleshooting guidance, which notes that the server also needs memory for other engines, per-connection buffers, and the operating system, and the MySQL 8.0 Reference Manual.