<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kjudeh</title>
    <description>The latest articles on Forem by Kjudeh (@kjudeh).</description>
    <link>https://forem.com/kjudeh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3780467%2F32d4a5e0-6849-456a-8707-730673f072ec.png</url>
      <title>Forem: Kjudeh</title>
      <link>https://forem.com/kjudeh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kjudeh"/>
    <language>en</language>
    <item>
      <title>Your PostgreSQL Backups Are Probably Broken (Here's How to Know for Sure)</title>
      <dc:creator>Kjudeh</dc:creator>
      <pubDate>Thu, 19 Feb 2026 05:17:25 +0000</pubDate>
      <link>https://forem.com/kjudeh/your-postgresql-backups-are-probably-broken-heres-how-to-know-for-sure-2ihb</link>
      <guid>https://forem.com/kjudeh/your-postgresql-backups-are-probably-broken-heres-how-to-know-for-sure-2ihb</guid>
      <description>&lt;p&gt;73% of backup restores fail in production.&lt;/p&gt;

&lt;p&gt;Not because the backup software broke. Because &lt;strong&gt;no one tested the restore&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I've been running PostgreSQL in production for years. I've seen teams religiously back up their databases every hour, upload to S3, check the green checkmark, and sleep soundly. Then disaster hits, they try to restore, and... nothing works. Corrupted dumps. Wrong permissions. Missing extensions. Schema drift.&lt;/p&gt;

&lt;p&gt;The backup worked. The restore didn't. And they only found out when it mattered most.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With "Just Back It Up"
&lt;/h2&gt;

&lt;p&gt;Most backup setups look like this:&lt;/p&gt;

&lt;p&gt;pg_dump → gzip → S3 →✓ done&lt;/p&gt;

&lt;p&gt;That checkmark is a lie. It tells you the file uploaded. It doesn't tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can this dump actually be restored?&lt;/li&gt;
&lt;li&gt;Will the data be intact?&lt;/li&gt;
&lt;li&gt;Do the row counts match?&lt;/li&gt;
&lt;li&gt;Are the indexes valid?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't know until you try. And most teams never try until it's too late.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: Automated Restore Verification
&lt;/h2&gt;

&lt;p&gt;I built a backup system that doesn't just dump and pray. Every day, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Downloads the latest backup from S3&lt;/li&gt;
&lt;li&gt;Restores it to an &lt;strong&gt;isolated verification database&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Runs integrity checks (table counts, row validation, custom queries)&lt;/li&gt;
&lt;li&gt;Reports success or failure&lt;/li&gt;
&lt;li&gt;Cleans up automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the restore fails, I know immediately — not when production is on fire.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;The system has two services:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backup Service&lt;/strong&gt; — Runs &lt;code&gt;pg_dump&lt;/code&gt; on a schedule (default: hourly), compresses with gzip, uploads to any S3-compatible storage. Handles retention automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify Service&lt;/strong&gt; — Downloads backups daily and restores them to a separate PostgreSQL instance. Runs sanity checks. Proves the backup works.&lt;/p&gt;

&lt;p&gt;Both run as lightweight containers. Works with AWS S3, Backblaze B2, Cloudflare R2, DigitalOcean Spaces, Wasabi, or MinIO.&lt;/p&gt;

&lt;h2&gt;
  
  
  One-Click Deploy on Railway
&lt;/h2&gt;

&lt;p&gt;If you're running PostgreSQL on Railway, you can deploy this in minutes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://railway.com/template/sparkling-creation" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frailway.com%2Fbutton.svg" alt="Deploy on Railway" width="183" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just add your database URL and S3 credentials. The services start working immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you get:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hourly backups to S3 (configurable)&lt;/li&gt;
&lt;li&gt;Daily restore verification&lt;/li&gt;
&lt;li&gt;7-day retention (configurable)&lt;/li&gt;
&lt;li&gt;AES-256 encryption (optional)&lt;/li&gt;
&lt;li&gt;Slack/Discord alerts on failure&lt;/li&gt;
&lt;li&gt;Zero maintenance after setup&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;Fully open source:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Kjudeh/railway-postgres-backups" rel="noopener noreferrer"&gt;github.com/Kjudeh/railway-postgres-backups&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Works with Docker, docker-compose, or any container platform — not just Railway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Hoping. Start Verifying.
&lt;/h2&gt;

&lt;p&gt;Every backup you haven't restored is a backup you can't trust.&lt;/p&gt;

&lt;p&gt;Set up automated verification once. Sleep better forever.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions? Drop a comment or open an issue on GitHub.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>devops</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
