{"id":3589,"date":"2025-12-28T16:59:54","date_gmt":"2025-12-28T13:59:54","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/managing-ram-swap-and-the-oom-killer-on-vps-servers\/"},"modified":"2025-12-28T16:59:54","modified_gmt":"2025-12-28T13:59:54","slug":"managing-ram-swap-and-the-oom-killer-on-vps-servers","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/managing-ram-swap-and-the-oom-killer-on-vps-servers\/","title":{"rendered":"Managing RAM, Swap and the OOM Killer on VPS Servers"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>On a <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a>, RAM problems rarely start with a dramatic crash. They usually begin as a line on a resource report, a quick check in <code>htop<\/code>, or a capacity planning discussion for a new feature. One graph trends upward a bit too steadily, swap usage quietly appears, and at some point the Linux Out-of-Memory (OOM) killer decides which process must die. If you manage websites, APIs, e\u2011commerce stores or SaaS workloads, understanding how RAM, swap and the OOM killer actually work on a VPS is the difference between stable uptime and random failures that are hard to reproduce.<\/p>\n<p>In this guide, we will walk through how Linux memory management behaves on real VPS servers, how to configure swap correctly, what the OOM killer really does, and\u2014most importantly\u2014how to prevent out\u2011of\u2011memory errors before they hit production. We will look at PHP, databases, background workers and containers, plus show how to use simple tools and monitoring to turn memory from a mystery into a predictable resource you can plan around.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#How_Linux_Memory_Really_Works_on_a_VPS\"><span class=\"toc_number toc_depth_1\">1<\/span> How Linux Memory Really Works on a VPS<\/a><ul><li><a href=\"#Key_concepts_RAM_virtual_memory_cache_and_buffers\"><span class=\"toc_number toc_depth_2\">1.1<\/span> Key concepts: RAM, virtual memory, cache and buffers<\/a><\/li><li><a href=\"#Reading_free_-m_without_panicking\"><span class=\"toc_number toc_depth_2\">1.2<\/span> Reading free -m without panicking<\/a><\/li><li><a href=\"#Essential_tools_to_inspect_memory_on_a_VPS\"><span class=\"toc_number toc_depth_2\">1.3<\/span> Essential tools to inspect memory on a VPS<\/a><\/li><\/ul><\/li><li><a href=\"#Understanding_Swap_on_a_VPS\"><span class=\"toc_number toc_depth_1\">2<\/span> Understanding Swap on a VPS<\/a><ul><li><a href=\"#What_swap_is_and_what_it_is_not\"><span class=\"toc_number toc_depth_2\">2.1<\/span> What swap is (and what it is not)<\/a><\/li><li><a href=\"#Checking_existing_swap\"><span class=\"toc_number toc_depth_2\">2.2<\/span> Checking existing swap<\/a><\/li><li><a href=\"#Recommended_swap_sizes_on_VPS_servers\"><span class=\"toc_number toc_depth_2\">2.3<\/span> Recommended swap sizes on VPS servers<\/a><\/li><li><a href=\"#Creating_a_swap_file\"><span class=\"toc_number toc_depth_2\">2.4<\/span> Creating a swap file<\/a><\/li><li><a href=\"#Tuning_swappiness_for_better_behavior\"><span class=\"toc_number toc_depth_2\">2.5<\/span> Tuning swappiness for better behavior<\/a><\/li><\/ul><\/li><li><a href=\"#The_Linux_OOM_Killer_What_It_Does_and_Why\"><span class=\"toc_number toc_depth_1\">3<\/span> The Linux OOM Killer: What It Does and Why<\/a><ul><li><a href=\"#When_does_the_OOM_killer_trigger\"><span class=\"toc_number toc_depth_2\">3.1<\/span> When does the OOM killer trigger?<\/a><\/li><li><a href=\"#How_the_OOM_killer_decides_what_to_kill\"><span class=\"toc_number toc_depth_2\">3.2<\/span> How the OOM killer decides what to kill<\/a><\/li><li><a href=\"#Detecting_past_OOM_events\"><span class=\"toc_number toc_depth_2\">3.3<\/span> Detecting past OOM events<\/a><\/li><\/ul><\/li><li><a href=\"#Preventing_OutofMemory_Errors_in_Real_Workloads\"><span class=\"toc_number toc_depth_1\">4<\/span> Preventing Out\u2011of\u2011Memory Errors in Real Workloads<\/a><ul><li><a href=\"#Rightsizing_PHPFPM_Nodejs_and_other_application_servers\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Right\u2011sizing PHP\u2011FPM, Node.js and other application servers<\/a><ul><li><a href=\"#PHPFPM_workers\"><span class=\"toc_number toc_depth_3\">4.1.1<\/span> PHP\u2011FPM workers<\/a><\/li><li><a href=\"#Nodejs_and_similar_runtimes\"><span class=\"toc_number toc_depth_3\">4.1.2<\/span> Node.js and similar runtimes<\/a><\/li><\/ul><\/li><li><a href=\"#Databases_MySQLPostgreSQL_memory_budgets\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Databases: MySQL\/PostgreSQL memory budgets<\/a><\/li><li><a href=\"#Using_systemd_and_cgroups_to_fence_off_memory_hogs\"><span class=\"toc_number toc_depth_2\">4.3<\/span> Using systemd and cgroups to fence off memory hogs<\/a><\/li><li><a href=\"#Applicationlevel_limits_PHP_workers_and_queues\"><span class=\"toc_number toc_depth_2\">4.4<\/span> Application\u2011level limits: PHP, workers and queues<\/a><\/li><li><a href=\"#Security_and_abuse_scenarios\"><span class=\"toc_number toc_depth_2\">4.5<\/span> Security and abuse scenarios<\/a><\/li><\/ul><\/li><li><a href=\"#Monitoring_and_Alerting_Before_Memory_Becomes_a_Problem\"><span class=\"toc_number toc_depth_1\">5<\/span> Monitoring and Alerting Before Memory Becomes a Problem<\/a><ul><li><a href=\"#Simple_baseline_checks\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Simple baseline checks<\/a><\/li><li><a href=\"#Setting_up_real_monitoring_with_alerts\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Setting up real monitoring with alerts<\/a><\/li><li><a href=\"#What_to_monitor_specifically_for_OOM_prevention\"><span class=\"toc_number toc_depth_2\">5.3<\/span> What to monitor specifically for OOM prevention<\/a><\/li><\/ul><\/li><li><a href=\"#When_to_Upgrade_RAM_or_Rethink_Your_Architecture\"><span class=\"toc_number toc_depth_1\">6<\/span> When to Upgrade RAM or Rethink Your Architecture<\/a><ul><li><a href=\"#Signals_that_it_is_time_to_add_RAM\"><span class=\"toc_number toc_depth_2\">6.1<\/span> Signals that it is time to add RAM<\/a><\/li><li><a href=\"#Rethinking_architecture_not_just_RAM_size\"><span class=\"toc_number toc_depth_2\">6.2<\/span> Rethinking architecture, not just RAM size<\/a><\/li><\/ul><\/li><li><a href=\"#Putting_It_All_Together_A_Practical_Checklist\"><span class=\"toc_number toc_depth_1\">7<\/span> Putting It All Together: A Practical Checklist<\/a><\/li><li><a href=\"#Conclusion_Calm_Predictable_Memory_Management_on_Your_VPS\"><span class=\"toc_number toc_depth_1\">8<\/span> Conclusion: Calm, Predictable Memory Management on Your VPS<\/a><\/li><\/ul><\/div>\n<h2><span id=\"How_Linux_Memory_Really_Works_on_a_VPS\">How Linux Memory Really Works on a VPS<\/span><\/h2>\n<p>Linux memory usage on a VPS often looks scary at first glance: RAM is \u201calmost full\u201d even when the server seems idle. That is usually good news. The kernel aggressively uses free memory as cache to speed up disk access. To manage RAM safely, you need to distinguish between <strong>real pressure<\/strong> and <strong>healthy caching<\/strong>.<\/p>\n<h3><span id=\"Key_concepts_RAM_virtual_memory_cache_and_buffers\">Key concepts: RAM, virtual memory, cache and buffers<\/span><\/h3>\n<ul>\n<li><strong>Physical RAM<\/strong>: The actual memory available to your VPS. This is the hard limit; exceed it and the kernel may start swapping or invoke the OOM killer.<\/li>\n<li><strong>Virtual memory<\/strong>: The address space applications see. It includes RAM plus swap. Virtual memory can be larger than physical RAM.<\/li>\n<li><strong>Page cache<\/strong>: File data cached in RAM. Caching speeds up repeated file and database access and is dropped automatically when memory is needed.<\/li>\n<li><strong>Buffers<\/strong>: Metadata for block devices (file system structures, etc.). A smaller fraction of memory, but part of the \u201ccached\u201d concept.<\/li>\n<\/ul>\n<h3><span id=\"Reading_free_-m_without_panicking\">Reading <code>free -m<\/code> without panicking<\/span><\/h3>\n<p>Run:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">free -m\n<\/code><\/pre>\n<p>You will see something like:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">              total        used        free      shared  buff\/cache   available\nMem:           3953        2100         150          90        1700        1500\nSwap:          2047         150        1897\n<\/code><\/pre>\n<p>Many admins look only at the <strong>used<\/strong> and <strong>free<\/strong> columns and think \u201cI\u2019m using 2100 MB, only 150 MB free, I\u2019m about to crash\u201d. The line that matters most on modern kernels is <strong>available<\/strong>. This is the RAM the kernel can still give to processes without heavy swapping, counting cache that can be reclaimed. In the example above, 1500 MB is still realistically usable, so there is no immediate memory crisis.<\/p>\n<h3><span id=\"Essential_tools_to_inspect_memory_on_a_VPS\">Essential tools to inspect memory on a VPS<\/span><\/h3>\n<ul>\n<li><strong><code>htop<\/code><\/strong>: Interactive process viewer. Shows per\u2011process memory, swap, and CPU. Press <code>F6<\/code> to adjust sort order by RES (resident memory).<\/li>\n<li><strong><code>top<\/code><\/strong>: Installed almost everywhere. Press <code>M<\/code> to sort by memory usage.<\/li>\n<li><strong><code>vmstat 1<\/code><\/strong>: Shows system\u2011level statistics each second. The <code>si<\/code> and <code>so<\/code> columns (swap in\/out) tell you if the system is actively swapping.<\/li>\n<li><strong><code>ps aux --sort=-%mem | head<\/code><\/strong>: Quick way to list top memory\u2011consuming processes.<\/li>\n<\/ul>\n<p>If you want a deeper monitoring setup with charts and alerts, check our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-kaynak-kullanimi-izleme-rehberi-htop-iotop-netdata-ve-prometheus\/\">monitoring VPS resource usage with htop, iotop, Netdata and Prometheus<\/a>. It shows how to turn these snapshots into continuous visibility.<\/p>\n<h2><span id=\"Understanding_Swap_on_a_VPS\">Understanding Swap on a VPS<\/span><\/h2>\n<p>Swap is disk space used as an extension of RAM. It is much slower than real memory, but it gives the kernel more breathing room before it has to kill processes. On modern NVMe\u2011based storage, swap is far less painful than on HDDs, but it is still orders of magnitude slower than RAM.<\/p>\n<h3><span id=\"What_swap_is_and_what_it_is_not\">What swap is (and what it is not)<\/span><\/h3>\n<ul>\n<li><strong>Swap is not performance magic<\/strong>. If your workloads need 8 GB consistently and you only have 4 GB RAM, adding 8 GB swap will not make the server feel like it has 12 GB RAM. It will simply be slow.<\/li>\n<li><strong>Swap is a safety net<\/strong>. It helps absorb short spikes and background memory usage, and gives you some time to react to leaks or misconfigurations before the OOM killer steps in.<\/li>\n<li><strong>Swap can reduce crashes<\/strong>. A small swap area can prevent the kernel from killing MySQL or your web server due to a momentary spike.<\/li>\n<\/ul>\n<h3><span id=\"Checking_existing_swap\">Checking existing swap<\/span><\/h3>\n<p>On most Linux VPS distributions, you can inspect swap with:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">swapon --show\nfree -m\n<\/code><\/pre>\n<p>If you see no swap configured, it is usually worth adding at least a small swap file unless your provider forbids it at the hypervisor level.<\/p>\n<h3><span id=\"Recommended_swap_sizes_on_VPS_servers\">Recommended swap sizes on VPS servers<\/span><\/h3>\n<p>There is no one\u2011size\u2011fits\u2011all rule, but for general web and app hosting, these ballpark values work well:<\/p>\n<table>\n<thead>\n<tr>\n<th>RAM<\/th>\n<th>Suggested swap<\/th>\n<th>Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>&le; 2 GB<\/td>\n<td>1\u20132 GB<\/td>\n<td>Small VPS; swap mainly as a buffer, not for sustained use.<\/td>\n<\/tr>\n<tr>\n<td>2\u20134 GB<\/td>\n<td>2\u20134 GB<\/td>\n<td>Typical single\u2011site or small multi\u2011site VPS.<\/td>\n<\/tr>\n<tr>\n<td>4\u20138 GB<\/td>\n<td>2\u20134 GB<\/td>\n<td>Use swap to absorb peaks; watch for high swap\u2011in\/out.<\/td>\n<\/tr>\n<tr>\n<td>&gt; 8 GB<\/td>\n<td>~25\u201350% of RAM<\/td>\n<td>Depends heavily on workload; many databases like some swap but not too much.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For memory\u2011sensitive workloads (databases, in\u2011memory caches), keep swap modest and focus on correct sizing and configuration instead.<\/p>\n<h3><span id=\"Creating_a_swap_file\">Creating a swap file<\/span><\/h3>\n<p>Typical steps for a 2 GB swap file on a VPS with root access:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">fallocate -l 2G \/swapfile\nchmod 600 \/swapfile\nmkswap \/swapfile\nswapon \/swapfile\n<\/code><\/pre>\n<p>To make it persistent across reboots, add this line to <code>\/etc\/fstab<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/swapfile   none    swap    sw    0   0\n<\/code><\/pre>\n<h3><span id=\"Tuning_swappiness_for_better_behavior\">Tuning <code>swappiness<\/code> for better behavior<\/span><\/h3>\n<p><strong>Swappiness<\/strong> controls how aggressively Linux prefers to use swap versus dropping cache. Values range from 0 to 100:<\/p>\n<ul>\n<li><strong>10\u201320<\/strong>: Good for most VPS web workloads. Use RAM more, swap later.<\/li>\n<li><strong>60 (default on many distros)<\/strong>: Balanced for general desktops but often too aggressive on servers.<\/li>\n<li><strong>0\u20135<\/strong>: Only for very specific cases; can make the kernel reluctant to swap even when it would help performance.<\/li>\n<\/ul>\n<p>Check current value:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">cat \/proc\/sys\/vm\/swappiness\n<\/code><\/pre>\n<p>Temporarily set it to 10:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sysctl vm.swappiness=10\n<\/code><\/pre>\n<p>To make it persistent, add to <code>\/etc\/sysctl.conf<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">vm.swappiness = 10\n<\/code><\/pre>\n<h2><span id=\"The_Linux_OOM_Killer_What_It_Does_and_Why\">The Linux OOM Killer: What It Does and Why<\/span><\/h2>\n<p>The <strong>OOM (Out\u2011Of\u2011Memory) killer<\/strong> is a safety mechanism in the Linux kernel. When the system runs out of allocatable memory (RAM + usable swap) and cannot satisfy allocations, it must free memory quickly. That is when the OOM killer chooses one or more processes to terminate.<\/p>\n<h3><span id=\"When_does_the_OOM_killer_trigger\">When does the OOM killer trigger?<\/span><\/h3>\n<p>Typical situations on a VPS:<\/p>\n<ul>\n<li>A memory leak in an application or background worker slowly consumes RAM until nothing is left.<\/li>\n<li>Too many PHP\u2011FPM or Node.js workers are started, each using more memory than expected.<\/li>\n<li>A database (MySQL\/PostgreSQL) is configured for a much larger server than the actual VPS.<\/li>\n<li>A runaway cron job or script loads a huge dataset into memory.<\/li>\n<\/ul>\n<p>When the kernel cannot reclaim enough cache or swap to satisfy allocations, it logs an OOM event and starts killing processes.<\/p>\n<h3><span id=\"How_the_OOM_killer_decides_what_to_kill\">How the OOM killer decides what to kill<\/span><\/h3>\n<p>The kernel uses several factors (OOM score, memory usage, privileges) to find the \u201cbest\u201d victim. In practice, it often kills:<\/p>\n<ul>\n<li>The biggest memory consumer (e.g. <code>mysqld<\/code> or <code>php-fpm<\/code>), or<\/li>\n<li>Processes marked as low priority using <code>oom_score_adj<\/code> (if you customized it).<\/li>\n<\/ul>\n<p>This is why a single misconfigured app can take down a critical service: the OOM killer does not know which process matters most to your business; it just wants memory back.<\/p>\n<h3><span id=\"Detecting_past_OOM_events\">Detecting past OOM events<\/span><\/h3>\n<p>If you suspect the OOM killer ran, check:<\/p>\n<ul>\n<li><code>dmesg | grep -i \"out of memory\" -i kill<\/code><\/li>\n<li><code>journalctl -k | grep -i oom<\/code> (on systemd\u2011based distros)<\/li>\n<li><code>\/var\/log\/kern.log<\/code> or <code>\/var\/log\/messages<\/code>, depending on distribution.<\/li>\n<\/ul>\n<p>Typical log snippets look like:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">Out of memory: Killed process 1234 (php-fpm) total-vm:1024000kB, anon-rss:512000kB, ...\n<\/code><\/pre>\n<p>These logs are your starting point: they tell you which process was killed and how much memory it was using, which is crucial for tuning.<\/p>\n<h2><span id=\"Preventing_OutofMemory_Errors_in_Real_Workloads\">Preventing Out\u2011of\u2011Memory Errors in Real Workloads<\/span><\/h2>\n<p>Once you understand RAM, swap and the OOM killer, the real work is to configure your stack so that normal load never reaches that point. On a VPS, this often comes down to three pillars: <strong>right\u2011sizing processes<\/strong>, <strong>using system\u2011level limits<\/strong>, and <strong>good capacity planning<\/strong>.<\/p>\n<h3><span id=\"Rightsizing_PHPFPM_Nodejs_and_other_application_servers\">Right\u2011sizing PHP\u2011FPM, Node.js and other application servers<\/span><\/h3>\n<p>Dynamic applications usually have multiple worker processes. Each worker consumes memory; too many workers cause pressure even if CPU is fine.<\/p>\n<h4><span id=\"PHPFPM_workers\">PHP\u2011FPM workers<\/span><\/h4>\n<p>For PHP sites (WordPress, Laravel, WooCommerce, etc.), PHP\u2011FPM settings are critical. A common pattern is:<\/p>\n<ul>\n<li>Estimate average memory per PHP process under load (e.g. 80\u2013150 MB).<\/li>\n<li>Allocate at most ~70\u201380% of RAM for PHP workers.<\/li>\n<li>Set <code>pm.max_children<\/code> so total PHP memory stays within that budget.<\/li>\n<\/ul>\n<p>We explain these calculations in detail in our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/php-ayarlarini-dogru-yapmak-memory_limit-max_execution_time-ve-upload_max_filesize-kac-olmali\/\">choosing the right PHP memory_limit and related PHP settings<\/a>; pairing those PHP limits with sane <code>pm.max_children<\/code> is one of the most effective ways to prevent OOMs on a PHP\u2011heavy VPS.<\/p>\n<h4><span id=\"Nodejs_and_similar_runtimes\">Node.js and similar runtimes<\/span><\/h4>\n<ul>\n<li>Prefer a smaller number of well\u2011utilised Node workers rather than many idle ones.<\/li>\n<li>For heavy workloads, consider setting <code>--max-old-space-size<\/code> to prevent a single process from consuming the whole server.<\/li>\n<li>Use a process manager (PM2, systemd) with restart policies, but fix root causes instead of auto\u2011restarting infinite loops.<\/li>\n<\/ul>\n<h3><span id=\"Databases_MySQLPostgreSQL_memory_budgets\">Databases: MySQL\/PostgreSQL memory budgets<\/span><\/h3>\n<p>A frequent cause of VPS OOM events is copying configuration from a blog or from a much larger <a href=\"https:\/\/www.dchost.com\/dedicated-server\">dedicated server<\/a>. On a 2\u20134 GB RAM VPS, settings like <code>innodb_buffer_pool_size=4G<\/code> are simply impossible.<\/p>\n<ul>\n<li>Reserve a clear portion of RAM for the database (e.g. 30\u201350% on a single\u2011VPS stack).<\/li>\n<li>Size <code>innodb_buffer_pool_size<\/code> (MySQL\/MariaDB) or <code>shared_buffers<\/code> (PostgreSQL) accordingly.<\/li>\n<li>Avoid very large per\u2011connection buffers; they multiply quickly with concurrent clients.<\/li>\n<\/ul>\n<p>For e\u2011commerce and larger catalog sites, see our deeper dives such as <a href=\"https:\/\/www.dchost.com\/blog\/en\/woocommerce-ve-buyuk-katalog-siteleri-icin-mysql-indeksleme-ve-sorgu-optimizasyonu-rehberi\/\">MySQL indexing and query optimization for WooCommerce<\/a> and our <a href=\"https:\/\/www.dchost.com\/blog\/en\/vpste-postgresqli-ucurmak-shared_buffers-work_mem-wal-ve-pgbounceri-ne-zaman-nasil-ayarlariz\/\">friendly VPS playbook for PostgreSQL performance<\/a>. Tuning queries and indexes often reduces memory pressure more than simply adding RAM.<\/p>\n<h3><span id=\"Using_systemd_and_cgroups_to_fence_off_memory_hogs\">Using systemd and cgroups to fence off memory hogs<\/span><\/h3>\n<p>On modern Linux distributions with systemd, you can apply <strong>cgroup\u2011based memory limits<\/strong> per service. This is extremely helpful on a VPS where one component (e.g. a batch worker) should never be allowed to consume the entire server.<\/p>\n<p>Example for a background worker unit <code>\/etc\/systemd\/system\/worker.service<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">[Service]\nExecStart=\/usr\/bin\/php \/var\/www\/app\/artisan queue:work\nMemoryMax=512M\nMemoryHigh=384M\nOOMPolicy=restart\n<\/code><\/pre>\n<ul>\n<li><strong>MemoryHigh<\/strong>: Soft limit; the kernel will try to reclaim memory, slowing the service before things get critical.<\/li>\n<li><strong>MemoryMax<\/strong>: Hard limit; the process cannot use more than this. If it tries, it will be killed inside the cgroup rather than taking the whole VPS down.<\/li>\n<li><strong>OOMPolicy<\/strong>: Decide what happens when the service hits OOM (e.g. restart or stop).<\/li>\n<\/ul>\n<p>This approach isolates risky components and gives you predictable behavior during spikes or bugs.<\/p>\n<h3><span id=\"Applicationlevel_limits_PHP_workers_and_queues\">Application\u2011level limits: PHP, workers and queues<\/span><\/h3>\n<p>Even with system\u2011level protections, it is smart to put <strong>limits inside the application stack<\/strong>:<\/p>\n<ul>\n<li>Use appropriate <code>memory_limit<\/code> in <code>php.ini<\/code> so a single PHP script cannot allocate gigabytes.<\/li>\n<li>In queue workers (Laravel, Symfony, custom code), periodically restart workers after N jobs to mitigate leaks.<\/li>\n<li>For image manipulation or reporting jobs, explicitly cap the size of input files and the complexity of operations.<\/li>\n<\/ul>\n<p>Combining language\u2011level limits with systemd cgroups gives you several layers of defenses against accidental OOMs.<\/p>\n<h3><span id=\"Security_and_abuse_scenarios\">Security and abuse scenarios<\/span><\/h3>\n<p>Untrusted input can also cause memory problems: huge XML or JSON payloads, unbounded file uploads, or intentionally expensive queries. Pairing good RAM practices with hardening (firewalls, rate limiting, WAF) reduces the chance that an attacker can push your VPS into OOM territory. Our <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-guvenlik-sertlestirme-kontrol-listesi-sshd_config-fail2ban-ve-root-erisimini-kapatmak\/\">VPS security hardening checklist<\/a> covers many of these defensive layers.<\/p>\n<h2><span id=\"Monitoring_and_Alerting_Before_Memory_Becomes_a_Problem\">Monitoring and Alerting Before Memory Becomes a Problem<\/span><\/h2>\n<p>The most reliable way to avoid the OOM killer is to see memory trends early and react before hitting the wall. That means going beyond occasional <code>htop<\/code> checks and setting up at least basic monitoring and alerts.<\/p>\n<h3><span id=\"Simple_baseline_checks\">Simple baseline checks<\/span><\/h3>\n<p>Start with a regular habit:<\/p>\n<ul>\n<li>Check <code>free -m<\/code> and <code>htop<\/code> during peak traffic.<\/li>\n<li>Track which processes consistently use the most RAM.<\/li>\n<li>Note swap usage and whether <code>vmstat<\/code> shows frequent swap in\/out activity.<\/li>\n<\/ul>\n<p>If you see swap usage slowly grow and never return to near\u2011zero, or if <code>available<\/code> memory on <code>free -m<\/code> steadily declines across days, that is a sign to investigate before an OOM event.<\/p>\n<h3><span id=\"Setting_up_real_monitoring_with_alerts\">Setting up real monitoring with alerts<\/span><\/h3>\n<p>For production VPS workloads, metrics + alerts are essential. With tools like Prometheus, Grafana and Uptime Kuma, you can:<\/p>\n<ul>\n<li>Graph RAM usage (total, used, cache, available) over time.<\/li>\n<li>Track per\u2011process memory for key services (PHP\u2011FPM, MySQL, Redis, etc.).<\/li>\n<li>Set thresholds\u2014for example \u201calert if RAM usage &gt; 80% for 15 minutes\u201d or \u201calert if swap usage &gt; 512 MB\u201d.<\/li>\n<\/ul>\n<p>If you want a practical walk\u2011through, see our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-izleme-ve-alarm-kurulumu-prometheus-grafana-ve-uptime-kuma-ile-baslangic\/\">VPS monitoring and alerts with Prometheus, Grafana and Uptime Kuma<\/a>. Once configured, you will receive early warnings long before the OOM killer needs to step in.<\/p>\n<h3><span id=\"What_to_monitor_specifically_for_OOM_prevention\">What to monitor specifically for OOM prevention<\/span><\/h3>\n<ul>\n<li><strong>Memory utilisation<\/strong>: Use the \u201cavailable\u201d metric, not just \u201cfree\u201d.<\/li>\n<li><strong>Swap usage and swap\u2011in\/out rate<\/strong>: Small, occasional swap use is fine; constant high swap I\/O is a red flag.<\/li>\n<li><strong>Per\u2011service memory<\/strong>: Especially <code>mysqld<\/code>, <code>php-fpm<\/code>, <code>redis-server<\/code>, <code>node<\/code> processes and background workers.<\/li>\n<li><strong>OOM events<\/strong>: Scrape kernel logs for \u201cOut of memory\u201d and alert when they appear.<\/li>\n<\/ul>\n<h2><span id=\"When_to_Upgrade_RAM_or_Rethink_Your_Architecture\">When to Upgrade RAM or Rethink Your Architecture<\/span><\/h2>\n<p>Even with perfect tuning, there is a point where your workload simply needs more RAM than a given VPS can offer. The key is to recognise this early, using data rather than guessing.<\/p>\n<h3><span id=\"Signals_that_it_is_time_to_add_RAM\">Signals that it is time to add RAM<\/span><\/h3>\n<ul>\n<li>Memory usage regularly stays above 75\u201380% even after optimisations.<\/li>\n<li>Swap usage grows during peak and does not return to near zero afterwards.<\/li>\n<li>You have already tuned PHP\u2011FPM, databases and workers, but OOM events still occur under legitimate load.<\/li>\n<li>Performance testing (e.g. with k6, JMeter or Locust) shows memory saturation before CPU or I\/O become bottlenecks.<\/li>\n<\/ul>\n<p>For realistic load simulations, our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/trafik-patlamasindan-once-load-test-yapmak-k6-jmeter-ve-locust-ile-kapasite-olcme-rehberi\/\">load testing hosting with k6, JMeter and Locust<\/a> explains how to find such limits in a controlled way instead of discovering them in production.<\/p>\n<h3><span id=\"Rethinking_architecture_not_just_RAM_size\">Rethinking architecture, not just RAM size<\/span><\/h3>\n<p>Sometimes the right move is to change how you deploy rather than endlessly scaling RAM on one VPS:<\/p>\n<ul>\n<li>Separate database and application servers when both are competing heavily for memory.<\/li>\n<li>Introduce dedicated cache layers (Redis, Memcached) to offload repeated queries and session storage.<\/li>\n<li>Move heavy analytics, reporting or image processing jobs to a separate background VPS.<\/li>\n<\/ul>\n<p>At dchost.com we see many customers start with a single VPS and gradually evolve towards more specialised machines or even dedicated servers and colocation as their workloads grow. The same memory management principles still apply; you simply have more RAM to distribute.<\/p>\n<h2><span id=\"Putting_It_All_Together_A_Practical_Checklist\">Putting It All Together: A Practical Checklist<\/span><\/h2>\n<p>To make this concrete, here is a pragmatic checklist you can apply to any Linux VPS:<\/p>\n<ol>\n<li><strong>Get visibility<\/strong>\n<ul>\n<li>Install <code>htop<\/code>, <code>vmstat<\/code>, and a basic monitoring stack if you do not have one.<\/li>\n<li>Measure typical memory usage during quiet and peak times.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Enable and size swap safely<\/strong>\n<ul>\n<li>Create a swap file (1\u20134 GB for most small\/mid VPS), unless your provider already manages it.<\/li>\n<li>Set <code>vm.swappiness<\/code> to 10\u201320 to prefer RAM while keeping swap as a safety net.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Tune key services<\/strong>\n<ul>\n<li>Set realistic PHP\u2011FPM <code>pm.max_children<\/code> and <code>memory_limit<\/code>.<\/li>\n<li>Adjust MySQL\/PostgreSQL buffer sizes to fit your RAM budget.<\/li>\n<li>Cap Node.js and other workers so their total memory fits within 60\u201370% of RAM.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Fence off risky workloads<\/strong>\n<ul>\n<li>Use systemd <code>MemoryMax<\/code> and <code>MemoryHigh<\/code> for batch jobs and workers.<\/li>\n<li>Restart long\u2011running workers periodically to avoid leaks.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Set alerts for early warning<\/strong>\n<ul>\n<li>Alert if RAM usage stays above 80% for more than 10\u201315 minutes.<\/li>\n<li>Alert if swap usage exceeds a threshold (e.g. 25\u201330% of total swap).<\/li>\n<li>Alert on any kernel OOM messages.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Review regularly<\/strong>\n<ul>\n<li>Re\u2011evaluate settings after major code deployments or traffic increases.<\/li>\n<li>Periodically sanity\u2011check resource allocations as part of your regular maintenance, alongside backups and security updates. Our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/yeni-vpste-ilk-24-saat-guncelleme-guvenlik-duvari-ve-kullanici-hesaplari\/\">what to do in the first 24 hours on a new VPS<\/a> is a good baseline.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h2><span id=\"Conclusion_Calm_Predictable_Memory_Management_on_Your_VPS\">Conclusion: Calm, Predictable Memory Management on Your VPS<\/span><\/h2>\n<p>Reliable VPS hosting is not just about CPU cores and NVMe disks; it is about understanding how your workloads use memory and giving the Linux kernel the right conditions to do its job. Once you know what \u201cused\u201d, \u201cavailable\u201d, cache and swap really mean, the memory graph on your monitoring dashboard stops being a source of anxiety and becomes a planning tool. The OOM killer is no longer a mysterious villain\u2014it is a last\u2011resort mechanism you rarely see because your stack is sized and tuned with intent.<\/p>\n<p>If you take away one idea, let it be this: combine <strong>realistic RAM sizing<\/strong>, <strong>a modest swap safety net<\/strong>, <strong>sensible service limits<\/strong> and <strong>simple alerts<\/strong>. That combination prevents almost all surprise out\u2011of\u2011memory crashes we encounter in practice. As your projects grow, our team at dchost.com can help you move from a single VPS to larger VPS plans, dedicated servers or colocation while preserving the same calm, predictable memory behavior. With a bit of upfront tuning and the right platform underneath, your applications can run for months without a single OOM event\u2014and that is exactly the kind of boring, stable infrastructure you want.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>On a VPS, RAM problems rarely start with a dramatic crash. They usually begin as a line on a resource report, a quick check in htop, or a capacity planning discussion for a new feature. One graph trends upward a bit too steadily, swap usage quietly appears, and at some point the Linux Out-of-Memory (OOM) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3590,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-3589","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/3589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=3589"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/3589\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/3590"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=3589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=3589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=3589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}