{"id":1310,"date":"2026-09-28T02:34:15","date_gmt":"2026-09-28T02:34:15","guid":{"rendered":"https:\/\/affordablevpsserver.com\/blog\/?p=1310"},"modified":"2026-09-28T02:34:15","modified_gmt":"2026-09-28T02:34:15","slug":"postgresql-tuning-low-memory-vps","status":"publish","type":"post","link":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/","title":{"rendered":"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">PostgreSQL&#8217;s default configuration assumes a machine with far more RAM than a small server provides. On a 1 GB or 2 GB instance, out-of-the-box settings can push the database into swap within a day of moderate traffic, and swap thrashing on a shared virtual disk turns a 5 ms query into a 2-second one. This is a practical tuning walkthrough for memory-constrained PostgreSQL deployments.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Baseline: What Each Setting Costs<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Setting<\/th><th>Default<\/th><th>Memory behaviour<\/th><th>Sensible small-server value<\/th><\/tr><\/thead><tbody><tr><td><code>shared_buffers<\/code><\/td><td>128 MB<\/td><td>Fixed allocation at startup<\/td><td>25% of RAM, e.g. 256 MB on 1 GB<\/td><\/tr><tr><td><code>work_mem<\/code><\/td><td>4 MB<\/td><td>Per sort\/hash operation, can multiply<\/td><td>4-8 MB; keep low on shared boxes<\/td><\/tr><tr><td><code>maintenance_work_mem<\/code><\/td><td>64 MB<\/td><td>Per maintenance connection<\/td><td>64-128 MB<\/td><\/tr><tr><td><code>effective_cache_size<\/code><\/td><td>4 GB<\/td><td>Planner hint only, no allocation<\/td><td>50-75% of RAM<\/td><\/tr><tr><td><code>max_connections<\/code><\/td><td>100<\/td><td>Each backend ~5-10 MB<\/td><td>20-40, with a connection pooler<\/td><\/tr><tr><td><code>wal_buffers<\/code><\/td><td>-1 (auto)<\/td><td>Small fixed buffer<\/td><td>Leave default or 16 MB<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p class=\"wp-block-paragraph\">The dangerous settings are the per-operation ones. <code>work_mem<\/code> is allocated <em>per sort or hash node<\/em>, per connection. With <code>work_mem = 64MB<\/code> and 20 concurrent sort-heavy queries, PostgreSQL will attempt 1.28 GB of work memory on a 1 GB box. That is the classic path to swap death, and it happens gradually enough that people blame the provider instead of the config.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Tuning Sequence<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>Measure current usage.<\/strong> Run <code>free -m<\/code> and <code>ps aux --sort=-rss | head<\/code> to see actual PostgreSQL RSS. Check <code>vmstat 1 10<\/code> \u2014 a non-zero <code>si<\/code>\/<code>so<\/code> column during normal traffic means you are already swapping.<\/li><li><strong>Check the log for spills.<\/strong> Set <code>log_temp_files = 0<\/code> to log every temp file larger than 0 bytes. Frequent temp files mean <code>work_mem<\/code> is too small for your queries; one or two large ones mean a single bad query.<\/li><li><strong>Set shared_buffers to 25% of RAM.<\/strong> Edit <code>postgresql.conf<\/code>, restart, and confirm with <code>SHOW shared_buffers;<\/code>.<\/li><li><strong>Set max_connections to 20-40 and deploy a pooler.<\/strong> PgBouncer in transaction mode lets 200 application clients share 20 database backends \u2014 the single largest memory saving available.<\/li><li><strong>Cap work_mem conservatively.<\/strong> Multiply expected concurrent sort operations by <code>work_mem<\/code> and confirm the product stays under 20% of RAM.<\/li><li><strong>Set effective_cache_size to 60% of RAM.<\/strong> This is planner guidance only \u2014 it costs nothing and improves join planning.<\/li><li><strong>Restart and re-measure.<\/strong> Compare <code>vmstat<\/code> swap activity and query latency before and after.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Change one group of settings at a time. If you alter all seven at once and performance improves, you learn nothing about which change mattered, and you cannot safely tune the next server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sizing Guide by Instance RAM<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Instance RAM<\/th><th>shared_buffers<\/th><th>work_mem<\/th><th>max_connections<\/th><th>effective_cache_size<\/th><\/tr><\/thead><tbody><tr><td>1 GB<\/td><td>256 MB<\/td><td>4 MB<\/td><td>20<\/td><td>512 MB<\/td><\/tr><tr><td>2 GB<\/td><td>512 MB<\/td><td>6 MB<\/td><td>30<\/td><td>1 GB<\/td><\/tr><tr><td>4 GB<\/td><td>1 GB<\/td><td>8 MB<\/td><td>40<\/td><td>2.5 GB<\/td><\/tr><tr><td>8 GB<\/td><td>2 GB<\/td><td>16 MB<\/td><td>60<\/td><td>5 GB<\/td><\/tr><\/tbody><\/table>\n\n\n\n<h2 class=\"wp-block-heading\">Kernel and OS Level Adjustments<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Swap on SSD, not a spinning or network volume.<\/strong> If your provider gives you <code>swapon --show<\/code> output with a slow device, keep swap minimal rather than large.<\/li><li><strong>Lower <code>vm.swappiness<\/code> to 10<\/strong> so the kernel keeps the database in RAM instead of eagerly swapping idle pages.<\/li><li><strong>Consider <code>vm.overcommit_memory = 2<\/code><\/strong> with a modest overcommit ratio on dedicated boxes \u2014 it prevents the OOM killer from choosing random victims, though it can cause allocation failures instead.<\/li><li><strong>Install pg_stat_statements<\/strong> before tuning further; it adds small overhead but is the only reliable way to find the queries causing temp spills.<\/li><li><strong>Review autovacuum<\/strong> \u2014 a table bloated by stale rows reads more pages and burns more buffer cache than a freshly vacuumed one.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">When Tuning Is Not Enough<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>pg_stat_statements<\/code> shows a handful of queries causing multi-gigabyte sorts, the fix is an index or a rewritten query, not more RAM. Add the index, confirm the temp file count drops, and only then reconsider your plan size. Many deployments chase a plan upgrade when an index would have solved the problem for zero dollars.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you do conclude the instance is genuinely too small, size the upgrade against measured peak memory rather than guessing. You can <a href=\"https:\/\/affordablevpsserver.com\/\">compare budget VPS plans on our comparison table<\/a> to see which tiers give you the RAM headroom you need, and our guide to <a href=\"https:\/\/affordablevpsserver.com\/blog\/vps-ram-headroom-how-much-spare-memory-to-keep\/\">RAM headroom on a VPS<\/a> explains how much spare memory to keep on a database server. For swap-specific diagnostics, our analysis of <a href=\"https:\/\/affordablevpsserver.com\/blog\/vps-swap-file-hiding-real-memory-shortage\/\">swap versus RAM<\/a> covers how to tell a quiet memory shortage from a real one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run the tuning loop once a quarter, or after any traffic step-change. Configuration is not a one-time task \u2014 it is a habit that keeps a small database server fast without buying more hardware than you need.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Monitoring: Catching Swap Thrash Before Users Do<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tuning is static; monitoring is what keeps it working. Three cheap signals tell you a small PostgreSQL server is under memory pressure before queries slow down visibly. First, watch <code>si<\/code> and <code>so<\/code> in <code>vmstat<\/code> \u2014 sustained non-zero values mean active swapping, not just a loaded swap file. Second, track the count of temp files logged by <code>log_temp_files<\/code>; a rising count means queries are spilling to disk. Third, watch the OS page cache size with <code>free -m<\/code> \u2014 if the cache is being squeezed to near zero, the database has outgrown the instance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Set a simple alert on any of these and you get days of warning instead of a sudden outage. A cron job writing <code>vmstat<\/code> and <code>pg_stat_activity<\/code> summaries to a log, plus a weekly glance at the trend, is enough for most small deployments. The goal is to make the memory ceiling visible long before the OOM killer makes it obvious.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Realistic Before-and-After<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A typical 1 GB instance running PostgreSQL with default settings might show 200 MB of swap in use during peak traffic and a p99 query latency near 800 ms. After capping <code>work_mem<\/code> at 4 MB, adding PgBouncer, and setting <code>shared_buffers<\/code> to 256 MB, the same workload often drops to near-zero swap and a p99 in the low tens of milliseconds \u2014 on identical hardware, for no additional money. That gap is why tuning before upgrading is almost always the correct order of operations.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>PostgreSQL&#8217;s default configuration assumes a machine with far more RAM than a small server provides. On a 1 GB or 2 GB instance, out-of-the-box settings can push the database into swap within a day of moderate traffic, and swap thrashing on a shared virtual disk turns a 5 ms query into a 2-second one. This [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":2,"footnotes":""},"categories":[2],"tags":[],"class_list":["post-1310","post","type-post","status-publish","format-standard","hentry","category-budget-vps-guides"],"blocksy_meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash - Affordable VPS Server Blog<\/title>\n<meta name=\"description\" content=\"PostgreSQL&#039;s default configuration assumes a machine with far more RAM than a small server provides. On a 1 GB or 2 GB instance, out-of-the-box settings\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash\" \/>\n<meta property=\"og:description\" content=\"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash\" \/>\n<meta property=\"og:url\" content=\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/\" \/>\n<meta property=\"og:site_name\" content=\"Affordable VPS Server Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-28T02:34:15+00:00\" \/>\n<meta name=\"author\" content=\"Affordable-Vps-Server-Author\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Affordable-Vps-Server-Author\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/\",\"url\":\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/\",\"name\":\"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash - Affordable VPS Server Blog\",\"isPartOf\":{\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#website\"},\"datePublished\":\"2026-09-28T02:34:15+00:00\",\"author\":{\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7\"},\"description\":\"PostgreSQL's default configuration assumes a machine with far more RAM than a small server provides. On a 1 GB or 2 GB instance, out-of-the-box settings\",\"breadcrumb\":{\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/affordablevpsserver.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#website\",\"url\":\"https:\/\/affordablevpsserver.com\/blog\/\",\"name\":\"Affordable VPS Server Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/affordablevpsserver.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7\",\"name\":\"Affordable-Vps-Server-Author\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g\",\"caption\":\"Affordable-Vps-Server-Author\"},\"sameAs\":[\"https:\/\/affordablevpsserver.com\/blog\"],\"url\":\"https:\/\/affordablevpsserver.com\/blog\/author\/affordablevpsserver\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash - Affordable VPS Server Blog","description":"PostgreSQL's default configuration assumes a machine with far more RAM than a small server provides. On a 1 GB or 2 GB instance, out-of-the-box settings","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/","og_locale":"en_US","og_type":"article","og_title":"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash","og_description":"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash","og_url":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/","og_site_name":"Affordable VPS Server Blog","article_published_time":"2026-09-28T02:34:15+00:00","author":"Affordable-Vps-Server-Author","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Affordable-Vps-Server-Author","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/","url":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/","name":"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash - Affordable VPS Server Blog","isPartOf":{"@id":"https:\/\/affordablevpsserver.com\/blog\/#website"},"datePublished":"2026-09-28T02:34:15+00:00","author":{"@id":"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7"},"description":"PostgreSQL's default configuration assumes a machine with far more RAM than a small server provides. On a 1 GB or 2 GB instance, out-of-the-box settings","breadcrumb":{"@id":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/affordablevpsserver.com\/blog\/postgresql-tuning-low-memory-vps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/affordablevpsserver.com\/blog\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL on a Low-Memory Linux Server: Configuration Changes That Prevent Swap Thrash"}]},{"@type":"WebSite","@id":"https:\/\/affordablevpsserver.com\/blog\/#website","url":"https:\/\/affordablevpsserver.com\/blog\/","name":"Affordable VPS Server Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/affordablevpsserver.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7","name":"Affordable-Vps-Server-Author","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g","caption":"Affordable-Vps-Server-Author"},"sameAs":["https:\/\/affordablevpsserver.com\/blog"],"url":"https:\/\/affordablevpsserver.com\/blog\/author\/affordablevpsserver\/"}]}},"_links":{"self":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts\/1310","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/comments?post=1310"}],"version-history":[{"count":2,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts\/1310\/revisions"}],"predecessor-version":[{"id":1316,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts\/1310\/revisions\/1316"}],"wp:attachment":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/media?parent=1310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/categories?post=1310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/tags?post=1310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}