{"id":84646,"date":"2026-07-06T07:30:00","date_gmt":"2026-07-06T14:30:00","guid":{"rendered":"https:\/\/dhblog.dream.press\/blog\/?p=84646"},"modified":"2026-07-06T11:55:47","modified_gmt":"2026-07-06T18:55:47","slug":"postgresql-vps","status":"publish","type":"post","link":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/","title":{"rendered":"Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing"},"content":{"rendered":"<div class=\"tldr-block\" style=\"display: none;\">\n\t<div class=\"svg\">\n\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 119.25 37.8\">\n\t<g>\n\t\t<g>\n\t\t\t<path fill=\"#ffffff\" d=\"M23.4,6.93h-8.1v24.57h-7.2V6.93H0V0h23.4v6.93Z\" \/>\n\t\t\t<path fill=\"#ffffff\" d=\"M45,24.57v6.93h-18.45V0h7.2v24.57h11.25Z\" \/>\n\t\t\t<path fill=\"#ffffff\"\n\t\t\t\td=\"M90.9,15.75c0,8.91-6.61,15.75-15.3,15.75h-12.6V0h12.6c8.68,0,15.3,6.84,15.3,15.75ZM83.97,15.75c0-5.4-3.42-8.82-8.37-8.82h-5.4v17.64h5.4c4.95,0,8.37-3.42,8.37-8.82Z\" \/>\n\t\t\t<path fill=\"#ffffff\"\n\t\t\t\td=\"M105.57,21.15h-3.42v10.35h-7.2V0h12.6c5.98,0,10.8,4.81,10.8,10.8,0,3.87-2.34,7.38-5.81,9.13l6.71,11.56h-7.74l-5.94-10.35ZM102.15,14.85h5.4c1.98,0,3.6-1.75,3.6-4.05s-1.62-4.05-3.6-4.05h-5.4v8.1Z\" \/>\n\t\t<\/g>\n\t\t<path\n\t\t\tfill=\"#0173ec\"\n\t\t\td=\"M53.97,37.8h-5.4l1.8-13.27h7.2l-3.6,13.27ZM49.02,12.55c0-2.34,1.93-4.27,4.27-4.27s4.27,1.94,4.27,4.27-1.93,4.27-4.27,4.27-4.27-1.94-4.27-4.27Z\"\n\t\t \/>\n\t<\/g>\n<\/svg>\n\t<\/div>\n\t<div class=\"tldr-wrap\">\n\t\t\n\n<p class=\"wp-block-paragraph\">Self-hosting PostgreSQL on a 4 GB VPS commonly runs at a fraction of equivalent managed-DB pricing once storage, backups, and egress beyond the free tier are stacked on.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For most production application databases, Stack 4 (4 GB RAM) is the baseline; Stack 8 or higher fits larger datasets or high concurrency. A self-hosted Postgres on a small VPS frequently costs less than the compute line alone of a comparable RDS, Supabase Pro, or Neon Scale plan.<\/p>\n\n\n\t<\/div>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Compute. Storage. Backup retention.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The snapshot export you forgot about. The egress fee from the staging environment that ran a \u2018pg_dump\u2019 last Tuesday.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nobody opens their managed-database invoice expecting it to be cheap.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But, dang.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The gap between &#8220;Postgres for $25 a month&#8221; and what shows up on the card has gotten <em>wide<\/em>, and a 4 GB VPS at the price of a single Supabase add-on now runs your whole database with room to spare for the OS to cache hot pages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Self-hosting a production Postgres database isn\u2019t the operational nightmare it once was. The PostgreSQL Global Development Group (PGDG) repo is solid; modern PostgreSQL installations (v14+) default to SCRAM-SHA-256 password encryption, with legacy MD5 officially deprecated as of v18. The reasons people stay on RDS, Supabase, or Neon today are operational, not technical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019re talking about actual invoices, actual operational overhead, and what modern Postgres hosting really looks like.<\/p>\n\n\n\n<h2 id=\"h-how-much-does-it-actually-cost-to-self-host-postgresql-on-a-vps\" class=\"wp-block-heading\">How Much Does It Actually Cost to Self-Host PostgreSQL on a VPS?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Self-hosted PostgreSQL on a 4 GB VPS commonly runs at a fraction of equivalent RDS, Supabase Pro, or Neon Scale pricing once storage, backups, and egress are stacked into the managed bill.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL is the database 55.6% of developers use, <a target=\"_blank\" href=\"https:\/\/survey.stackoverflow.co\/2025\/technology\/\">according to Stack Overflow&#8217;s 2025 Developer Survey<\/a>, the most popular for the past two years running. It&#8217;s also the database you can comfortably run yourself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Comparison for a representative small-team workload (4 GB RAM, ~100 GB data, low-to-moderate write load, single region), priced as of May 2026:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>Option<\/strong><\/th><th><strong>Compute<\/strong><\/th><th><strong>Storage<\/strong><\/th><th><strong>Egress past the free tier<\/strong><\/th><th><strong>Best for<\/strong><\/th><\/tr><\/thead><tbody><tr><td>Self-hosted on a 4 GB VPS<\/td><td>Flat plan price<\/td><td>Usually included<\/td><td>Usually unmetered or high-cap<\/td><td>Steady workloads, cost-sensitive teams comfortable with Linux<\/td><\/tr><tr><td><a target=\"_blank\" href=\"https:\/\/aws.amazon.com\/rds\/postgresql\/pricing\">AWS RDS<\/a> db.t4g.medium<\/td><td>$47.45\/month compute-only<\/td><td>~$0.115\/GB-month gp3<\/td><td>~$0.09\/GB internet\/out-region<\/td><td>Teams that want managed backups, failover, and AWS-native ops<\/td><\/tr><tr><td>Supabase Pro<\/td><td><a target=\"_blank\" href=\"https:\/\/supabase.com\/pricing\">$25\/month<\/a> base + usage<\/td><td>$0.125\/GB database disk beyond the 8 GB included<\/td><td>$0.09\/GB past 250 GB<\/td><td>Apps that need Postgres, auth, storage, and real-time in one stack<\/td><\/tr><tr><td>Neon Scale<\/td><td>$0.222 per CU\/hour<\/td><td>$0.35 per GB\/month<\/td><td><a target=\"_blank\" href=\"https:\/\/neon.com\/pricing\">Usage-metered<\/a><\/td><td>Spiky, preview-heavy, branch-heavy development workflows<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The RDS db.t4g.medium on-demand price is roughly $0.065 an hour, or about <a target=\"_blank\" href=\"https:\/\/instances.vantage.sh\/aws\/rds\/db.t4g.medium?currency=USD\">$47.45 a month<\/a> for compute alone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Add 100 GB of gp3 storage at roughly $0.115\/GB-month and automated backups, and a Single-AZ box lands near $60\/month. Turn on Multi-AZ failover and the compute line roughly doubles, pushing a production-grade configuration to $100\/month and up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s not a small gap.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/blog\/self-hosting\/\">Self-hosting<\/a> is cheaper because <em>you<\/em> do the work that the managed bill was paying for. Ops discipline, on-call, at 2 a.m. when the disk fills. The managed-DB alternative you&#8217;re sizing against may have a different floor next quarter, so run the math against your own bill before committing.<\/p>\n\n\n\n<div class=\"article-newsletter article-newsletter--gradient\">\n\n\n<h2>Get Content Delivered Straight to Your Inbox<\/h2><p>Subscribe now to receive all the latest updates, delivered directly to your inbox.<\/p><form class=\"nwsl-form\" id=\"newsletter_block_\" novalidate><div class=\"messages\"><\/div><div class=\"form-group\"><label for=\"input_newsletter_block_\"><input type=\"email\"name=\"email\"id=\"input_newsletter_block_\"placeholder=\"Enter your email address\"novalidatedisabled=\"disabled\"\/><\/label><button type=\"submit\"class=\"btn btn--brand\"disabled=\"disabled\"><span>Sign Me Up!<\/span><svg width=\"21\" height=\"14\" viewBox=\"0 0 21 14\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M13.8523 0.42524L12.9323 1.34521C12.7095 1.56801 12.7132 1.9304 12.9404 2.14865L16.7241 5.7823H0.5625C0.251859 5.7823 0 6.03416 0 6.3448V7.6573C0 7.96794 0.251859 8.2198 0.5625 8.2198H16.7241L12.9405 11.8535C12.7132 12.0717 12.7095 12.4341 12.9323 12.6569L13.8523 13.5769C14.072 13.7965 14.4281 13.7965 14.6478 13.5769L20.8259 7.39879C21.0456 7.17913 21.0456 6.82298 20.8259 6.60327L14.6477 0.42524C14.4281 0.205584 14.0719 0.205584 13.8523 0.42524Z\" fill=\"white\"\/>\n<\/svg>\n<\/button><\/div><\/form><\/div>\n\n\n<h2 id=\"h-when-does-self-hosting-postgresql-make-sense\" class=\"wp-block-heading\">When Does Self-Hosting PostgreSQL Make Sense?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Self-hosting PostgreSQL on a VPS makes sense when you have basic Linux comfort on the team, a steady workload, a predictable working-set size, and a real reason to escape the managed bill.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It doesn&#8217;t work when you have no ops capacity, regulated HA requirements you can&#8217;t build yourself, or a bursty pattern that benefits from instant scale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Three things drive this decision. Cost, privacy and <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/blog\/data-portability\/\">data sovereignty<\/a>, and control.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"2560\" height=\"1734\" data-src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-scaled.webp\" alt=\"Self-hosted deployment for steady, privacy-sensitive workloads; managed for bursty, distributed, regulated environments.\" class=\"wp-image-84649 lazyload\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-scaled.webp 2560w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-300x203.webp 300w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-1024x694.webp 1024w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-768x520.webp 768w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-1536x1041.webp 1536w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-2048x1388.webp 2048w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-600x407.webp 600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-1200x813.webp 1200w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-730x495.webp 730w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-1460x989.webp 1460w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-784x531.webp 784w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-1568x1062.webp 1568w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-877x594.webp 877w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01_self_host_or_managed_-1754x1188.webp 1754w\" data-sizes=\"(max-width: 2560px) 100vw, 2560px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2560px; --smush-placeholder-aspect-ratio: 2560\/1734;\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Where self-hosted wins cleanly:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Steady traffic in a single region with a predictable working set.<\/li>\n\n\n\n<li>Small-to-medium SaaS apps with one Postgres database and a Linux-comfortable team.<\/li>\n\n\n\n<li>Privacy-sensitive workloads where the database shouldn&#8217;t sit in someone else&#8217;s tenancy.<\/li>\n\n\n\n<li>Cost-conscious teams whose managed bill has crept past the operational hassle threshold.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Where managed wins cleanly:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bursty workloads that benefit from instant scale-up and scale-down.<\/li>\n\n\n\n<li>Multi-region setups where global replication is the product.<\/li>\n\n\n\n<li>Regulated environments needing turnkey HA, compliance certs, and audit trails.<\/li>\n\n\n\n<li>Teams with no spare ops capacity and no plan to build it.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The 40% to 60% cost-savings number gets cited a lot. Date it carefully.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As of 2021, AWS author Rupesh Desai documented PostgreSQL on EC2 running <a target=\"_blank\" href=\"https:\/\/medium.com\/amazon-web-services\/by-using-postgresql-on-ec2-save-40-to-60-cost-over-aws-rds-postgresql-e96afdd2210b\">40% to 60%<\/a> cheaper than RDS at equivalent specs, older than most current RDS instance families.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The current version is byteiota&#8217;s cost-stack analysis, published in late 2025, which says RDS is <\/strong><a target=\"_blank\" href=\"https:\/\/byteiota.com\/self-hosting-postgres-vs-rds-the-379-month-lie\/\"><strong>75% to 88% more expensive<\/strong><\/a><strong> than equivalent dedicated hardware.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The honest break-even is operational hours, not server cost.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-pick-the-right-vps-size-for-postgresql\" class=\"wp-block-heading\">How Do You Pick the Right VPS Size for PostgreSQL?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Most production application databases run comfortably on 4 GB of RAM with NVMe storage. <\/strong>Larger datasets, heavy concurrent connections, or analytics workloads push the requirement to 8 GB or 16 GB and up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RAM determines how much of your working set Postgres can keep in memory; once hot pages spill to disk, queries slow down. NVMe matters because Postgres is sensitive to random-read latency for hot pages and to flush throughput for the write-ahead log.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Common <a target=\"_blank\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Tuning_Your_PostgreSQL_Server\">PostgreSQL tuning guidance<\/a> starts with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>shared_buffers<\/code> <\/strong>at roughly 25% of system RAM.<\/li>\n\n\n\n<li><strong><code>effective_cache_size<\/code><\/strong> at roughly 50%-75% of system RAM.<\/li>\n\n\n\n<li><strong><code>work_mem<\/code><\/strong> sized conservatively \u2014 based on concurrent query complexity, not total RAM alone.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">On a 4 GB VPS, that usually means allocating around 1 GB to shared_buffers while leaving enough memory for the Linux page cache to hold frequently accessed data. That balance is part of why a modest 4 GB box can comfortably run many small-to-midsize production workloads.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The plan-to-workload map you need to know:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>RAM Tier<\/strong><\/th><th><strong>Typical Workload<\/strong><\/th><th><strong>Recommended Stack Plan<\/strong><\/th><\/tr><\/thead><tbody><tr><td>2 GB<\/td><td>Dev environments, low-traffic side projects<\/td><td>Below baseline<\/td><\/tr><tr><td>4 GB<\/td><td>Most production application databases<\/td><td>Stack 4<\/td><\/tr><tr><td>8 GB<\/td><td>Larger datasets, more concurrent connections<\/td><td>Stack 8<\/td><\/tr><tr><td>16 GB+<\/td><td>Postgres alongside other heavy services, analytics<\/td><td>Stack 16<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/hosting\/vps\/\"><strong>DreamHost&#8217;s VPS Hosting<\/strong><\/a><strong> plans give you root access, NVMe storage, and unmetered bandwidth on a predictable monthly bill.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Those are the four things a self-hosted Postgres workload depends on.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-install-postgresql-on-a-vps\" class=\"wp-block-heading\">How Do You Install PostgreSQL on a VPS?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You install PostgreSQL on a VPS in five compressed steps.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"2560\" height=\"1336\" data-src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-scaled.webp\" alt=\"Process flow showing database server setup from initial VPS provisioning through firewall security lock.\" class=\"wp-image-84650 lazyload\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-scaled.webp 2560w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-300x157.webp 300w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-1024x534.webp 1024w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-768x401.webp 768w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-1536x802.webp 1536w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-2048x1069.webp 2048w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-600x313.webp 600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-1200x626.webp 1200w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-730x381.webp 730w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-1460x762.webp 1460w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-784x409.webp 784w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-1568x818.webp 1568w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-877x458.webp 877w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02_from_blank_server_to_running_database-1754x915.webp 1754w\" data-sizes=\"(max-width: 2560px) 100vw, 2560px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2560px; --smush-placeholder-aspect-ratio: 2560\/1336;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Provision the VPS:<\/strong> Pick a plan with enough RAM for your working set (Stack 4\/4 GB is the baseline). <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/blog\/check-ubuntu-version\/\">Ubuntu<\/a> 24.04 LTS is the recommended OS. SSH in with key-based authentication, not a password.<\/li>\n\n\n\n<li><strong>Install from the official PGDG repo:<\/strong> The distro <code>\u2018apt install postgresql\u2019<\/code> lags major versions. Add the PGDG apt repo, then <code>\u2018sudo apt install postgresql-18.\u2019<\/code> Confirm with <code>\u2018sudo systemctl status postgresql\u2019<\/code><\/li>\n\n\n\n<li><strong>Set the postgres password and create your app role:<\/strong> Run <strong><code>sudo -i -u postgres<\/code><\/strong>, then <strong><code>psql<\/code><\/strong>, then <strong><code>password postgres<\/code><\/strong>. Create a dedicated least-privilege role: <code>\u2018CREATE ROLE myapp WITH LOGIN PASSWORD '...';\u2019<\/code> and <code>\u2018CREATE DATABASE myapp_prod OWNER myapp;\u2019<\/code><\/li>\n\n\n\n<li><strong>Bind the listener correctly: <\/strong>Open <strong>\/etc\/postgresql\/18\/main\/postgresql.conf<\/strong>. Set listen_addresses = &#8216;localhost&#8217; if the app and database share the box, or bind to a private IP if the app runs on a separate VPS. Avoid binding PostgreSQL to 0.0.0.0 on a publicly reachable interface. Exposed PostgreSQL instances are aggressively scanned and brute-forced by automated bots.<\/li>\n\n\n\n<li><strong>Lock down \u2018pg_hba.conf\u2019 and UFW: <\/strong>Edit <strong>pg_hba.conf<\/strong> to allow only the application IPs you actually need, with \u2018scram-sha-256\u2019 as the auth method. Configure UFW to allow port 5432 only from those same IPs. SSH-tunnel for admin tools (and please don&#8217;t open 5432 to the public internet).<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Try this from another machine: <strong><code>psql -h &lt;vps-ip> -U postgres<\/code><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A timeout or refused connection from an unauthorized IP usually means your listener and firewall rules are doing their job. A password prompt from the public internet means something is misconfigured. Once Postgres is running, the configuration is only half the job.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-secure-postgresql-on-a-vps\" class=\"wp-block-heading\">How Do You Secure PostgreSQL on a VPS?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL on a VPS gets secured at three layers, plus role hygiene and patching cadence.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Authentication: <\/strong>Use <strong>scram-sha-256<\/strong> for new installs and remove legacy md5 rules from <a target=\"_blank\" href=\"https:\/\/www.postgresql.org\/docs\/current\/auth-pg-hba-conf.html\"><strong>pg_hba.conf<\/strong><\/a>. PostgreSQL\u2019s docs now warn that MD5-encrypted password support is deprecated and will be removed in a future release.<\/li>\n\n\n\n<li><strong>Network:<\/strong> Bind PostgreSQL to \u2018localhost,\u2019 a private IP, or an interface reachable only by your application servers. Avoid binding it to a publicly reachable interface. Layer UFW on top and allow port 5432 only from trusted application IPs.<\/li>\n\n\n\n<li><strong>Encryption in transit: <\/strong>Turn on <a target=\"_blank\" href=\"https:\/\/www.percona.com\/blog\/enabling-and-enforcing-ssl-tls-for-postgresql-connections\/\">TLS<\/a> for any connection crossing a network boundary. Set <strong>ssl = on<\/strong> in <strong>postgresql.conf<\/strong>, then use <strong>hostssl &#8230; scram-sha-256<\/strong> rules in <strong>pg_hba.conf<\/strong> so clients can\u2019t silently fall back to non-TLS connections. Self-signed certificates are acceptable for internal traffic if clients verify them properly.<\/li>\n\n\n\n<li><strong>Roles:<\/strong> Application connections should use a least-privilege role with only the rights needed for that app\u2019s schemas. The superuser is for migrations and emergencies.<\/li>\n\n\n\n<li><strong>Patching:<\/strong> Use the PGDG apt repo for current PostgreSQL packages. Enable unattended security updates for the OS, but schedule PostgreSQL updates deliberately so a surprise restart doesn\u2019t become your incident of the week.&nbsp;<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Your security checklist:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use scram-sha-256 only; disable md5.<\/li>\n\n\n\n<li>Bind \u2018listen_addresses\u2019 to localhost or private IP.<\/li>\n\n\n\n<li>UFW rules allow 5432 only from trusted IPs.<\/li>\n\n\n\n<li>SSL\/TLS on for any network-crossing connection.<\/li>\n\n\n\n<li>App connects as a least-privileged role, never as \u2018postgres.\u2019<\/li>\n\n\n\n<li>Unattended security updates enabled.<\/li>\n\n\n\n<li>No \u2018host all all 0.0.0.0\/0 md5\u2019 lines anywhere in \u2018pg_hba.conf,\u2019 ever.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">That last bullet is the cautionary tale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Public-facing port 5432 with weak credentials is a known <a target=\"_blank\" href=\"https:\/\/www.wiz.io\/blog\/postgresql-cryptomining\">cryptominer and brute-force target<\/a>. Exposed PostgreSQL instances get scanned continuously by automated bots looking for default accounts, leaked passwords, or permissive pg_hba.conf rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Publicly reachable Postgres instances with weak authentication frequently get compromised shockingly fast. A database exposed directly to the internet without proper network controls, TLS, and role isolation is the kind of mistake that turns into an incident report. A properly configured database is still one disk failure away from data loss.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-back-up-and-replicate-postgresql-on-a-vps\" class=\"wp-block-heading\">How Do You Back Up and Replicate PostgreSQL on a VPS?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL backups on a VPS use one of three mechanisms, picked by the failure you&#8217;re protecting against. Logical backups via <a target=\"_blank\" href=\"https:\/\/www.postgresql.org\/docs\/current\/app-pgdump.html\"><strong>pg_dump<\/strong><\/a> for portability, physical backups via <a target=\"_blank\" href=\"https:\/\/www.postgresql.org\/docs\/current\/app-pgbasebackup.html\"><strong>pg_basebackup<\/strong><\/a> plus WAL archiving for point-in-time recovery, and streaming replication for high availability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Logical backups handle migrations, partial restores, and dev refreshes. <strong>Run pg_dump &#8211;format=custom &#8211;file=mydb.dump mydb_prod<\/strong> from a daily <a target=\"_blank\" href=\"https:\/\/help.dreamhost.com\/hc\/en-us\/articles\/215088668-Create-a-cron-job\">cron job<\/a>. Custom format compresses well and, along with the directory format, supports pg_restore&#8217;s parallel and selective restore options. Push the dump to off-VPS object storage (DreamObjects, S3-compatible).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Physical backups handle full-system restores and point-in-time recovery. <strong>pg_basebackup<\/strong> plus continuous Write-Ahead Log (WAL) archiving lets you recover to any moment between the last base backup and the most recent WAL segment, the production-grade option when data loss tolerance is seconds, not hours.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Streaming replication is the third option. A read replica on a second VPS is a hot standby for read-heavy workloads or a fast failover target. The database replication setup costs a second VPS but bounds your worst-case outage to minutes.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>Mechanism<\/strong><\/th><th><strong>What It Gives You<\/strong><\/th><th><strong>What It Costs<\/strong><\/th><\/tr><\/thead><tbody><tr><td>pg_dump + cron + off-VPS storage<\/td><td>Daily logical backup, portable<\/td><td>Restore latency, not point-in-time<\/td><\/tr><tr><td>pg_basebackup + WAL archiving<\/td><td>Physical backup with point-in-time recovery<\/td><td>Storage and operational complexity<\/td><\/tr><tr><td>Streaming replication<\/td><td>Hot standby, near-zero Recovery Point Objective (RPO), read scaling<\/td><td>Second VPS plus replication management<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Restore-test monthly. Managed services bake all this in, and it&#8217;s part of what the self-hosting savings are buying back. If you\u2019re already on a managed provider, the path out is simpler than it looks.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-migrate-from-rds-supabase-or-neon-to-a-vps\" class=\"wp-block-heading\">How Do You Migrate From RDS, Supabase, or Neon to a VPS?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You migrate from a managed Postgres provider to a VPS in four steps.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Provision the target VPS:<\/strong> Match the source Postgres major version exactly. Install PostgreSQL on the new VPS following the steps above, then pre-create the application role and database.<\/li>\n\n\n\n<li><strong>Dump from the source:<\/strong> Run <strong>pg_dump &#8211;format=custom &#8211;no-owner &#8211;no-privileges &#8211;file=src.dump &lt;source-connection-string&gt;<\/strong>. The &#8211;no-owner and &#8211;no-privileges flags strip provider-specific role grants that rarely recreate cleanly on a new host.<\/li>\n\n\n\n<li><strong>Restore to the target: <\/strong>Run <strong>pg_restore &#8211;dbname=myapp_prod &#8211;jobs=4 &#8211;no-owner &#8211;no-privileges src.dump<\/strong>. Watch for extension warnings. RDS, Supabase, and Neon often enable extensions that may not exist on vanilla Postgres. Install compatible extensions from PGDG packages or <strong>postgresql-contrib<\/strong> before restoring.<\/li>\n\n\n\n<li><strong>Connection-string swap and verification:<\/strong> Point a staging environment at the new VPS first, run your test suite, then validate representative production queries and application flows before switching the production connection string. For low-write applications, a short maintenance window during final cutover is often simpler than setting up replication. Keep the source database online and read-only for several days as a rollback target.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">What changes by provider?<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>From RDS:<\/strong> RDS-specific roles (\u2018rds_superuser,\u2019 \u2018rdsadmin\u2019) don&#8217;t exist on vanilla Postgres; &#8211;no-owner and &#8211;no-privileges handle most of it. Some RDS-managed extensions need a manual install, and egress out of AWS during the dump is billable.<\/li>\n\n\n\n<li><strong>From Supabase:<\/strong> The Postgres is real Postgres, but Supabase&#8217;s auth, storage, and edge layers don&#8217;t migrate. Your application schema does. Replace those layers with self-hosted equivalents before cutting over.<\/li>\n\n\n\n<li><strong>From Neon:<\/strong> Branching is gone post-migration; plan for backups instead. Dump-and-restore is straightforward, but operational habits like instant branches need a replacement workflow.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The migration itself usually takes less time than picking the VPS plan. Realistic downtime is minutes for small databases, longer with WAL replay for large ones. Most installs stop here, but there is one scenario that pushes you further\u2026<\/p>\n\n\n\n<h2 id=\"h-when-should-you-add-pgbouncer-or-stick-with-vanilla-postgres\" class=\"wp-block-heading\">When Should You Add PgBouncer or Stick With Vanilla Postgres?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most apps on a 4 GB VPS don&#8217;t need a connection pooler at the start. Add <a target=\"_blank\" href=\"https:\/\/www.pgbouncer.org\/\">PgBouncer<\/a> when concurrent connections exceed roughly 100, or your application stack opens a new connection per request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL connections are heavy because each one is a full operating system process. With 4 GB of RAM, you don&#8217;t want hundreds of idle connections eating memory. The pooler holds the expensive Postgres connections on its side and hands out cheap, short-lived connections to your app on the other.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two pooling modes matter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Session pooling:<\/strong> Each client gets one server connection for the session. Safe for any app, no semantics change, lower throughput gain.<\/li>\n\n\n\n<li><strong>Transaction pooling:<\/strong> Each client gets a server connection for one transaction. Big throughput gain. You lose features relying on session state (prepared statements, advisory locks, \u2018LISTEN\u2019\/\u2019NOTIFY\u2019) unless the app is written to expect it.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Most small <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/blog\/saas-websites\/\">SaaS apps<\/a> with a connection-pooled ORM are fine without PgBouncer until they aren&#8217;t. The signal that you&#8217;ve crossed the line is \u2018FATAL: too many connections\u2019 errors or memory pressure from idle connections.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Install it with <strong>sudo apt install pgbouncer<\/strong>, configure <strong>\/etc\/pgbouncer\/pgbouncer.ini<\/strong> with your database list and pool mode, then point the app at PgBouncer on port 6432.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, you&#8217;ll know when you need it.<\/p>\n\n\n\n<h2 id=\"h-making-the-final-call\" class=\"wp-block-heading\">Making the Final Call<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The cost gap is real enough to justify running the math against your own bill. But setup isn&#8217;t the hard part.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The hard part is the operational work that the managed bill was paying for. Backups, restore drills, patching, and monitoring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Either way, take a deep breath before you open that next invoice.<\/p>\n\n\n\n\n<div class=\"article-cta-shared article-cta-small article-cta--product\">\n\t<div class=\"tr-img-wrap-outer jsLoading\"><img decoding=\"async\" class=\"js-img-lazy \" src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/themes\/blog2018\/assets\/img\/lazy-loading-transparent.webp\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/06\/cta_image_a-877x522.webp 1x, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/06\/cta_image_a.webp 2x\"  \/><\/div>\n\n\t<a href='https:\/\/www.dreamhost.com\/hosting\/vps\/' class='link-top' target='_blank' rel='noopener noreferrer'>\n\t\t<span>VPS<\/span>\n\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 384 512\" width=\"15\"><path d=\"M342.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L274.7 256 105.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z\"\/><\/svg>\n\t<\/a>\n\n\t<div class=\"content-btm\">\n\t\t<h2 class=\"h2--md\">\n\t\t\tOwn Your Entire Stack. Apps, AI, Databases, and More.\n\t\t<\/h2>\n\t\t<p class=\"p--md\">\n\t\t\tKeep every credential and conversation on a server you control, with NVMe speed and unmetered bandwidth built in.\n\t\t<\/p>\n\n\t\t        <a\n            href=\"https:\/\/www.dreamhost.com\/hosting\/vps\/\"\n                        class=\"btn btn--white-outline btn--sm btn--round\"\n                                    target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            >\n                            Explore VPS Hosting Plans                    <\/a>\n\n\t<\/div>\n<\/div>\n\n\n<h2 id=\"h-frequently-asked-questions-about-postgresql-on-a-vps\" class=\"wp-block-heading\">Frequently Asked Questions About PostgreSQL on a VPS<\/h2>\n\n\n\n<h3 id=\"h-how-much-ram-does-postgresql-need-on-a-vps\" class=\"wp-block-heading\">How much RAM does PostgreSQL need on a VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL runs on 1 to 2 GB for tiny workloads and comfortably on 4 GB for most production application databases. Heavier datasets, more concurrent connections, or analytics workloads push the requirement to 8 GB or more.<\/p>\n\n\n\n<h3 id=\"h-can-i-run-postgresql-on-a-2-gb-vps\" class=\"wp-block-heading\">Can I run PostgreSQL on a 2 GB VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, you can run PostgreSQL on a 2 GB VPS for small apps, dev environments, and low-traffic side projects. A 2 GB box leaves little headroom for caching, so query performance drops as your data outgrows memory. For production workloads, 4 GB is the safer baseline.<\/p>\n\n\n\n<h3 id=\"h-is-self-hosting-postgresql-on-a-vps-cheaper-than-rds-or-supabase\" class=\"wp-block-heading\">Is self-hosting PostgreSQL on a VPS cheaper than RDS or Supabase?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, self-hosting PostgreSQL on a VPS is cheaper than RDS or Supabase for most steady-state workloads. A 4 GB VPS commonly runs at a fraction of the equivalent RDS, Supabase Pro, or Neon Scale spec once storage, backups, and egress are stacked in. The trade-off is that you operate the database yourself.<\/p>\n\n\n\n<h3 id=\"h-how-do-i-expose-postgresql-on-a-vps-securely\" class=\"wp-block-heading\">How do I expose PostgreSQL on a VPS securely?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Don&#8217;t expose port 5432 to the public internet. Bind PostgreSQL to localhost or a private IP, require scram-sha-256 authentication, and SSH-tunnel admin tools instead of opening 5432 to your laptop. Public 5432 with weak auth is a known cryptominer target.<\/p>\n\n\n\n<h3 id=\"h-do-i-need-to-use-docker-for-postgresql-on-a-vps\" class=\"wp-block-heading\">Do I need to use Docker for PostgreSQL on a VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No, <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/blog\/what-is-docker\/\">Docker<\/a> is not required. The official PGDG apt repository installs PostgreSQL as a native system service, which is the simplest production-grade setup. Docker is reasonable if you&#8217;re already running other containers.<\/p>\n\n\n\n<h3 id=\"h-how-do-i-back-up-postgresql-on-a-vps\" class=\"wp-block-heading\">How do I back up PostgreSQL on a VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run <strong>pg_dump &#8211;format=custom<\/strong> on a daily cron schedule and store the output off-VPS in S3-compatible object storage. Use <strong>pg_basebackup<\/strong> plus WAL archiving for point-in-time recovery when seconds of data loss matter. Restore-test monthly.<\/p>\n\n\n\n<h3 id=\"h-what-plan-should-i-choose-for-self-hosting-postgresql-on-dreamhost\" class=\"wp-block-heading\">What plan should I choose for self-hosting PostgreSQL on DreamHost?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">DreamHost&#8217;s VPS Stack 4 plan (4 GB RAM) is the recommended baseline for most production application databases. Choose Stack 8 (8 GB) for larger datasets or high concurrency, and Stack 16 for Postgres alongside other resource-heavy services.<\/p>\n\n\n\n<h3 id=\"h-should-i-use-pgbouncer-with-postgresql-on-a-small-vps\" class=\"wp-block-heading\">Should I use PgBouncer with PostgreSQL on a small VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Most apps on a 4 GB VPS don&#8217;t need PgBouncer at the start. Add a connection pooler when concurrent connections approach 100, or when your app opens a new connection per request.<\/p>\n\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@graph\": [\n    {\n      \"@type\": \"FAQPage\",\n      \"mainEntity\": [\n        {\n          \"@type\": \"Question\",\n          \"name\": \"How much RAM does PostgreSQL need on a VPS?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"PostgreSQL runs on 1 to 2 GB for tiny workloads and comfortably on 4 GB for most production application databases. Heavier datasets, more concurrent connections, or analytics workloads push the requirement to 8 GB or more.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Can I run PostgreSQL on a 2 GB VPS?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Yes, you can run PostgreSQL on a 2 GB VPS for small apps, dev environments, and low-traffic side projects. A 2 GB box leaves little headroom for caching, so query performance drops as your data outgrows memory. For production workloads, 4 GB is the safer baseline.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Is self-hosting PostgreSQL on a VPS cheaper than RDS or Supabase?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Yes, self-hosting PostgreSQL on a VPS is cheaper than RDS or Supabase for most steady-state workloads. A 4 GB VPS commonly runs at a fraction of the equivalent RDS, Supabase Pro, or Neon Scale spec once storage, backups, and egress are stacked in. The trade-off is that you operate the database yourself.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"How do I expose PostgreSQL on a VPS securely?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Don't expose port 5432 to the public internet. Bind PostgreSQL to localhost or a private IP, restrict pg_hba.conf to specific application IPs, require scram-sha-256 authentication, and SSH-tunnel admin tools instead of opening 5432 to your laptop. Public 5432 with weak auth is a known cryptominer target.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Do I need to use Docker for PostgreSQL on a VPS?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"No, Docker is not required. The official PGDG apt repository installs PostgreSQL as a native system service, which is the simplest production-grade setup. Docker is reasonable if you're already running other containers.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"How do I back up PostgreSQL on a VPS?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Run pg_dump --format=custom on a daily cron schedule and store the output off-VPS in S3-compatible object storage. Use pg_basebackup plus WAL archiving for point-in-time recovery when seconds of data loss matter. Restore-test monthly. A backup you haven't restored is a hope.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"What plan should I choose for self-hosting PostgreSQL on DreamHost?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"DreamHost's VPS Stack 4 plan (4 GB RAM) is the recommended baseline for most production application databases. Choose Stack 8 (8 GB) for larger datasets or high concurrency, and Stack 16 for Postgres alongside other resource-heavy services.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Should I use PgBouncer with PostgreSQL on a small VPS?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Most apps on a 4 GB VPS don't need PgBouncer at the start. Add a connection pooler when concurrent connections approach 100, or when your app opens a new connection per request. The signal that you've crossed the line is FATAL: too many connections errors or memory pressure from idle connections.\"\n          }\n        }\n      ]\n    },\n    {\n      \"@type\": \"HowTo\",\n      \"name\": \"How to install PostgreSQL on a VPS\",\n      \"step\": [\n        {\n          \"@type\": \"HowToStep\",\n          \"name\": \"Provision the VPS\",\n          \"text\": \"Pick a plan with enough RAM for your working set (Stack 4 \/ 4 GB is the baseline). Ubuntu 24.04 LTS is the recommended OS. SSH in with key-based authentication, not a password.\"\n        },\n        {\n          \"@type\": \"HowToStep\",\n          \"name\": \"Install from the official PGDG repo\",\n          \"text\": \"The distro apt install postgresql lags major versions. Add the PGDG apt repo, then sudo apt install postgresql-18. Confirm with sudo systemctl status postgresql.\"\n        },\n        {\n          \"@type\": \"HowToStep\",\n          \"name\": \"Set the postgres password and create your app role\",\n          \"text\": \"Run sudo -i -u postgres, then psql, then password postgres. Create a dedicated least-privilege role: CREATE ROLE myapp WITH LOGIN PASSWORD '...'; and CREATE DATABASE myapp_prod OWNER myapp; PostgreSQL 14+ defaults to scram-sha-256 hashing.\"\n        },\n        {\n          \"@type\": \"HowToStep\",\n          \"name\": \"Bind the listener correctly\",\n          \"text\": \"Open postgresql.conf. Set listen_addresses = 'localhost' if app and database share the box, or bind to a private IP if the app runs on a separate VPS. Never bind to 0.0.0.0 on a public interface.\"\n        },\n        {\n          \"@type\": \"HowToStep\",\n          \"name\": \"Lock down pg_hba.conf and UFW\",\n          \"text\": \"Edit pg_hba.conf to allow only the application IPs you actually need, with scram-sha-256 as the auth method. Configure UFW to allow port 5432 only from those same IPs. SSH-tunnel for admin tools.\"\n        }\n      ]\n    }\n  ]\n}\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Run PostgreSQL on a VPS for a fraction of RDS or Supabase pricing. Covers install, security, sizing, backups, and when self-hosting actually pays off.<\/p>\n","protected":false},"author":2,"featured_media":84648,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_yoast_wpseo_opengraph-title":"Self-Host PostgreSQL on a VPS and Slash Your Database Bill","_yoast_wpseo_opengraph-description":"Self-hosting PostgreSQL on a 4 GB VPS costs a fraction of RDS, Supabase Pro, or Neon Scale. Learn how to install, secure, back up, and migrate your database.","_yoast_wpseo_twitter-title":"Self-Host PostgreSQL on a VPS and Slash Your Database Bill","_yoast_wpseo_twitter-description":"Self-hosting PostgreSQL on a 4 GB VPS costs a fraction of RDS, Supabase Pro, or Neon Scale. Learn how to install, secure, back up, and migrate your database.","toc_headlines":"[[\"h-how-much-does-it-actually-cost-to-self-host-postgresql-on-a-vps\",\"How Much Does It Actually Cost to Self-Host PostgreSQL on a VPS?\"],[\"h-when-does-self-hosting-postgresql-make-sense\",\"When Does Self-Hosting PostgreSQL Make Sense?\"],[\"h-how-do-you-pick-the-right-vps-size-for-postgresql\",\"How Do You Pick the Right VPS Size for PostgreSQL?\"],[\"h-how-do-you-install-postgresql-on-a-vps\",\"How Do You Install PostgreSQL on a VPS?\"],[\"h-how-do-you-secure-postgresql-on-a-vps\",\"How Do You Secure PostgreSQL on a VPS?\"],[\"h-how-do-you-back-up-and-replicate-postgresql-on-a-vps\",\"How Do You Back Up and Replicate PostgreSQL on a VPS?\"],[\"h-how-do-you-migrate-from-rds-supabase-or-neon-to-a-vps\",\"How Do You Migrate From RDS, Supabase, or Neon to a VPS?\"],[\"h-when-should-you-add-pgbouncer-or-stick-with-vanilla-postgres\",\"When Should You Add PgBouncer or Stick With Vanilla Postgres?\"],[\"h-making-the-final-call\",\"Making the Final Call\"],[\"h-frequently-asked-questions-about-postgresql-on-a-vps\",\"Frequently Asked Questions About PostgreSQL on a VPS\"]]","hide_toc":false,"footnotes":""},"categories":[550,807,804],"tags":[],"class_list":["post-84646","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-vps-hosting","category-web-hosting"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.3 (Yoast SEO v27.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing - DreamHost<\/title>\n<meta name=\"description\" content=\"Run PostgreSQL on a VPS for a fraction of RDS or Supabase pricing. Covers install, security, sizing, backups, and when self-hosting actually pays off.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Self-Host PostgreSQL on a VPS and Slash Your Database Bill\" \/>\n<meta property=\"og:description\" content=\"Self-hosting PostgreSQL on a 4 GB VPS costs a fraction of RDS, Supabase Pro, or Neon Scale. Learn how to install, secure, back up, and migrate your database.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/\" \/>\n<meta property=\"og:site_name\" content=\"DreamHost Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/DreamHost\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-06T14:30:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-06T18:55:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1220_x_628_ogimage_self_host_postgresql_on_a_vps-scaled.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1340\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Dallas Kashuba\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Self-Host PostgreSQL on a VPS and Slash Your Database Bill\" \/>\n<meta name=\"twitter:description\" content=\"Self-hosting PostgreSQL on a 4 GB VPS costs a fraction of RDS, Supabase Pro, or Neon Scale. Learn how to install, secure, back up, and migrate your database.\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/dallas\" \/>\n<meta name=\"twitter:site\" content=\"@dreamhost\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dallas Kashuba\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing - DreamHost","description":"Run PostgreSQL on a VPS for a fraction of RDS or Supabase pricing. Covers install, security, sizing, backups, and when self-hosting actually pays off.","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:\/\/www.dreamhost.com\/blog\/postgresql-vps\/","og_locale":"en_US","og_type":"article","og_title":"Self-Host PostgreSQL on a VPS and Slash Your Database Bill","og_description":"Self-hosting PostgreSQL on a 4 GB VPS costs a fraction of RDS, Supabase Pro, or Neon Scale. Learn how to install, secure, back up, and migrate your database.","og_url":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/","og_site_name":"DreamHost Blog","article_publisher":"https:\/\/www.facebook.com\/DreamHost\/","article_published_time":"2026-07-06T14:30:00+00:00","article_modified_time":"2026-07-06T18:55:47+00:00","og_image":[{"width":2560,"height":1340,"url":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1220_x_628_ogimage_self_host_postgresql_on_a_vps-scaled.webp","type":"image\/webp"}],"author":"Dallas Kashuba","twitter_card":"summary_large_image","twitter_title":"Self-Host PostgreSQL on a VPS and Slash Your Database Bill","twitter_description":"Self-hosting PostgreSQL on a 4 GB VPS costs a fraction of RDS, Supabase Pro, or Neon Scale. Learn how to install, secure, back up, and migrate your database.","twitter_creator":"@http:\/\/twitter.com\/dallas","twitter_site":"@dreamhost","twitter_misc":{"Written by":"Dallas Kashuba","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#article","isPartOf":{"@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/"},"author":{"name":"Dallas Kashuba","@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/person\/f6a12ad459538e8e418cf31b8b603814"},"headline":"Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing","datePublished":"2026-07-06T14:30:00+00:00","dateModified":"2026-07-06T18:55:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/"},"wordCount":2851,"publisher":{"@id":"https:\/\/www.dreamhost.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095_blog_hero_self_host_postgresql_on_a_vps-scaled.webp","articleSection":["Tutorials","VPS Hosting","Web Hosting"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/","url":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/","name":"Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing - DreamHost","isPartOf":{"@id":"https:\/\/www.dreamhost.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#primaryimage"},"image":{"@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095_blog_hero_self_host_postgresql_on_a_vps-scaled.webp","datePublished":"2026-07-06T14:30:00+00:00","dateModified":"2026-07-06T18:55:47+00:00","description":"Run PostgreSQL on a VPS for a fraction of RDS or Supabase pricing. Covers install, security, sizing, backups, and when self-hosting actually pays off.","breadcrumb":{"@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#primaryimage","url":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095_blog_hero_self_host_postgresql_on_a_vps-scaled.webp","contentUrl":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095_blog_hero_self_host_postgresql_on_a_vps-scaled.webp","width":2560,"height":1920,"caption":"Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing"},{"@type":"BreadcrumbList","@id":"https:\/\/www.dreamhost.com\/blog\/postgresql-vps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.dreamhost.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Self-Hosted PostgreSQL on a VPS: Escape Managed DB Pricing"}]},{"@type":"WebSite","@id":"https:\/\/www.dreamhost.com\/blog\/#website","url":"https:\/\/www.dreamhost.com\/blog\/","name":"DreamHost Blog","description":"","publisher":{"@id":"https:\/\/www.dreamhost.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dreamhost.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.dreamhost.com\/blog\/#organization","name":"DreamHost","url":"https:\/\/www.dreamhost.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/dhblog.dream.press\/blog\/wp-content\/uploads\/2019\/01\/dh_logo-blue-2.png","contentUrl":"https:\/\/dhblog.dream.press\/blog\/wp-content\/uploads\/2019\/01\/dh_logo-blue-2.png","width":1200,"height":168,"caption":"DreamHost"},"image":{"@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/DreamHost\/","https:\/\/x.com\/dreamhost","https:\/\/www.instagram.com\/dreamhost\/","https:\/\/www.linkedin.com\/company\/dreamhost\/","https:\/\/www.youtube.com\/user\/dreamhostusa"]},{"@type":"Person","@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/person\/f6a12ad459538e8e418cf31b8b603814","name":"Dallas Kashuba","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/05ab6fb1606be97d16c74efb0fba01b3c11e91501dc5f9661bdfbb5c5b0cd113?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/05ab6fb1606be97d16c74efb0fba01b3c11e91501dc5f9661bdfbb5c5b0cd113?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/05ab6fb1606be97d16c74efb0fba01b3c11e91501dc5f9661bdfbb5c5b0cd113?s=96&d=mm&r=g","caption":"Dallas Kashuba"},"description":"Dallas Kashuba co-founded DreamHost while attending Harvey Mudd College and has spent nearly three decades building infrastructure at scale. Today he serves as an advisor, board member, and investor for various tech startups, with a consistent focus on user privacy, open source, and data portability. When he's not thinking about the Open Web, he's probably making music. Follow Dallas on X.","sameAs":["http:\/\/www.idallas.com\/","https:\/\/x.com\/http:\/\/twitter.com\/dallas"],"url":"https:\/\/www.dreamhost.com\/blog\/author\/dallas\/"}]}},"lang":"en","translations":{"en":84646,"uk":84831,"pt":84807,"de":84810,"fr":84812,"es":84814,"it":84816,"nl":84821,"pl":84825,"ru":84828},"pll_sync_post":{},"_links":{"self":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts\/84646","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"version-history":[{"count":8,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts\/84646\/revisions"}],"predecessor-version":[{"id":84661,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts\/84646\/revisions\/84661"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/media\/84648"}],"wp:attachment":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/media?parent=84646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/categories?post=84646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/tags?post=84646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}