Run Debian 12 on a Low-RAM VPS Without OOM Crashes Taking Down MySQL

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.

Leave a Comment

How to Record Speaker Output on Linux with Audacity

How to Record Speaker Output on Linux with Audacity

Capture Linux desktop audio in Audacity by routing its recording stream to your output device’s monitor source. Follow PulseAudio and PipeWire steps, export tips, and fixes for silent tracks.

How to Use Dropbox on Linux: Install and Sync Your Files

How to Use Dropbox on Linux: Install and Sync Your Files

Install Dropbox on Linux from the official package, sign in, sync a local folder, manage selective sync, and check status from the command line.

How to Install Inkscape on Linux: Ubuntu, Fedora, Arch, and More

How to Install Inkscape on Linux: Ubuntu, Fedora, Arch, and More

Install Inkscape from your Linux distribution’s repositories, the Ubuntu stable PPA, Snap, or Flathub, with current commands and notes for choosing a package source.

How to Find and Remove Duplicate Files on Linux With FSlint

How to Find and Remove Duplicate Files on Linux With FSlint

Use FSlint to scan selected Linux folders, review duplicate groups, and safely delete redundant files or learn when hard-link merging is appropriate.

How to Install SABnzbd on Linux and Configure It

How to Install SABnzbd on Linux and Configure It

Install SABnzbd on Ubuntu or Debian, or run it in Docker on another Linux host. Then open the web interface and configure your provider and download folders.

How to Install the Paper GTK Theme on Linux

How to Install the Paper GTK Theme on Linux

Install the Paper GTK theme from supported Linux repositories, enable it for GTK apps in GNOME Tweaks, and see what the legacy theme can and cannot change.

How to Install and Set Up Plex on OpenMediaVault with Compose

How to Install and Set Up Plex on OpenMediaVault with Compose

The old OpenMediaVault Plex plugin is archived. Set up Plex on OMV 8 with OMV-Extras, the Compose plugin, persistent storage, and Plex’s official container.

How to Clean and Speed Up Ubuntu Safely

How to Clean and Speed Up Ubuntu Safely

Clean and speed up Ubuntu with safe APT cleanup, storage checks, and startup controls that help free space and troubleshoot a sluggish desktop.

How to Install the Hiri Email Client on Linux

How to Install the Hiri Email Client on Linux

Install Hiri on Linux with its Snap package or official tarball, add a desktop launcher, and check supported accounts plus a warning about Hiri’s old Snap release.

How to Get System Specifications for a Linux PC

How to Get System Specifications for a Linux PC

Use Fastfetch and built-in Linux commands to check your distro, kernel, CPU, memory, graphics, storage, and connected devices, then save a clear report.