{"id":35,"date":"2026-10-01T15:42:14","date_gmt":"2026-10-01T15:42:14","guid":{"rendered":"https:\/\/pomax-v3.weeltec.com\/?p=35"},"modified":"2026-10-01T15:53:04","modified_gmt":"2026-10-01T15:53:04","slug":"backups-arent-backups-until-you-restore","status":"publish","type":"post","link":"https:\/\/pomax-v3.weeltec.com\/?p=35","title":{"rendered":"Your Backup Isn't a Backup Until You've Restored It"},"content":{"rendered":"<div class=\"wt-post\">\n<style>.wt-post { --wt-bg: #0A0C0F; --wt-bg-2: #0E1116; --wt-surface: #12161C; --wt-line: #1F252E; --wt-line-strong: #2B333E; --wt-text: #E9ECEF; --wt-muted: #98A2AD; --wt-accent: #B9F24D; --wt-accent-hover: #C8FF5E; --wt-accent-dim: rgba(185, 242, 77, 0.10); --wt-accent-line: rgba(185, 242, 77, 0.25); --wt-danger: #F07A6B; --wt-ok: #7ED99A; --wt-sans: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif; --wt-mono: ui-monospace, \"Cascadia Code\", \"JetBrains Mono\", \"SF Mono\", Menlo, Consolas, monospace; --wt-radius: 4px; --wt-h1: var(--wt-text); --wt-h2: var(--wt-text); --wt-h3: var(--wt-text); box-sizing: border-box; background: var(--wt-bg); color: var(--wt-text); font-family: var(--wt-sans); font-size: 1rem; line-height: 1.7; padding: clamp(1.75rem, 4vw, 3rem); border: 1px solid var(--wt-line); border-radius: 0; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } .wt-post *, .wt-post *::before, .wt-post *::after { box-sizing: border-box; } .wt-post ::selection { background: var(--wt-accent); color: var(--wt-bg); } .wt-post.wt-post p { color: var(--wt-text); font-family: var(--wt-sans); font-size: 1rem; line-height: 1.7; margin: 0 0 1.15rem; max-width: 68ch; } .wt-post.wt-post p:last-child { margin-bottom: 0; } .wt-post.wt-post h1, .wt-post.wt-post h2, .wt-post.wt-post h3, .wt-post.wt-post h4, .wt-post.wt-post h5, .wt-post.wt-post h6 { font-family: var(--wt-sans); font-weight: 700; letter-spacing: -0.025em; line-height: 1.15; text-wrap: balance; } .wt-post.wt-post h2 { color: var(--wt-h2); font-size: clamp(1.45rem, 3vw, 2rem); margin: 2.4rem 0 0.9rem; display: flex; align-items: baseline; gap: 0.6rem; } .wt-post.wt-post h2::before { content: \"\"; flex: none; width: 8px; height: 8px; background: var(--wt-accent); transform: translateY(-2px); } .wt-post.wt-post h3 { color: var(--wt-h3); font-size: 1.15rem; font-weight: 650; margin: 1.8rem 0 0.7rem; padding-left: 0.85rem; border-left: 2px solid var(--wt-accent-line); } .wt-post.wt-post h2:first-child, .wt-post.wt-post h3:first-child { margin-top: 0; } .wt-post.wt-post strong { color: #FFFFFF; font-weight: 650; } .wt-post.wt-post em { color: var(--wt-muted); font-style: italic; } .wt-post.wt-post a { color: var(--wt-accent); text-decoration: none; border-bottom: 1px solid var(--wt-accent-line); transition: color 0.15s ease, border-color 0.15s ease; } .wt-post.wt-post a:hover { color: var(--wt-accent-hover); border-bottom-color: var(--wt-accent-hover); } .wt-post.wt-post ul, .wt-post.wt-post ol { margin: 0 0 1.3rem; padding: 0; list-style: none; max-width: 68ch; } .wt-post.wt-post li { position: relative; padding-left: 1.6rem; margin-bottom: 0.55rem; color: var(--wt-text); line-height: 1.65; } .wt-post.wt-post ul > li::before { content: \"\\25AE\"; color: var(--wt-accent); position: absolute; left: 0; top: 0; font-size: 0.85em; line-height: 1.65; } .wt-post.wt-post ol { counter-reset: wt-li; } .wt-post.wt-post ol > li { counter-increment: wt-li; } .wt-post.wt-post ol > li::before { content: counter(wt-li) \".\"; font-family: var(--wt-mono); font-size: 0.8em; color: var(--wt-accent); position: absolute; left: 0; top: 0; line-height: 1.9; } .wt-post.wt-post blockquote { margin: 1.8rem 0; padding: 1.1rem 1.4rem; background: var(--wt-accent-dim); border-left: 2px solid var(--wt-accent); border-radius: 0; color: var(--wt-text); font-size: 1.05rem; font-style: normal; line-height: 1.6; } .wt-post.wt-post blockquote p { margin: 0; color: var(--wt-text); font-style: normal; } .wt-post.wt-post blockquote::before { content: none; } .wt-post.wt-post code, .wt-post.wt-post kbd, .wt-post.wt-post pre { font-family: var(--wt-mono); font-size: 0.88em; } .wt-post.wt-post code { background: var(--wt-surface); border: 1px solid var(--wt-line); border-radius: var(--wt-radius); padding: 0.1em 0.4em; color: var(--wt-accent); } .wt-post.wt-post pre { background: #0C0F13; border: 1px solid var(--wt-line-strong); border-radius: var(--wt-radius); padding: 1.1rem 1.25rem; overflow-x: auto; color: var(--wt-text); line-height: 1.7; margin: 0 0 1.3rem; } .wt-post.wt-post pre code { background: none; border: 0; padding: 0; color: inherit; } .wt-post.wt-post hr { border: 0; border-top: 1px solid var(--wt-line); margin: 2.2rem 0; } .wt-post.wt-post img { max-width: 100%; height: auto; border-radius: var(--wt-radius); border: 1px solid var(--wt-line); } @media (max-width: 640px) { .wt-post.wt-post h2 { font-size: 1.35rem; } .wt-post.wt-post blockquote { padding: 0.9rem 1.1rem; } } @media (prefers-reduced-motion: reduce) { .wt-post.wt-post a { transition: none; } }<\/style>\n<p>Every infrastructure team has a backup. Far fewer have a restore. The gap between those two things is where companies die \u2014 quietly, and usually at the worst possible hour.<\/p>\n<p>A backup is a file. A restore is a procedure. Only one of them has ever saved anyone.<\/p>\n<h2>The uncomfortable question<\/h2>\n<p>Ask yourself, right now: when did you last restore from your production backup, on different hardware, and time how long it took?<\/p>\n<p>If the answer is \"we ran a test restore once, about two years ago,\" then what you own is not a disaster recovery plan. It is a belief system.<\/p>\n<p>We audit backup strategy for a living, and the same five failures show up over and over:<\/p>\n<ul>\n<li><strong>Untested backups.<\/strong> The job reports success. Nobody has verified that the archive actually contains a working database.<\/li>\n<li><strong>Same-fault domain.<\/strong> Backups live on the same host, same provider, or same credentials as production. Ransomware takes both.<\/li>\n<li><strong>Missing credentials.<\/strong> The encryption key is in a password manager nobody documented, held by someone who left.<\/li>\n<li><strong>Partial coverage.<\/strong> The database is covered; the object storage bucket holding customer uploads is not.<\/li>\n<li><strong>No restore runbook.<\/strong> Even with a perfect archive, nobody knows the order of operations under pressure.<\/li>\n<\/ul>\n<h2>What a real restore test looks like<\/h2>\n<p>A restore test is not \"the backup script exited 0.\" It is a rehearsal with a clock running:<\/p>\n<h3>1. Restore somewhere that is not production<\/h3>\n<p>Spin up a clean environment \u2014 different host, ideally different provider \u2014 and restore from the archive exactly the way you would in an emergency. No shortcuts because \"you already know the server.\"<\/p>\n<h3>2. Prove the application works, not just the database<\/h3>\n<p>A database that starts is not a database that serves. Point a copy of the app at it, log in, load a page, run a write, and confirm the data is sane. Corruption is rarely loud.<\/p>\n<h3>3. Measure the recovery time<\/h3>\n<p>Write down how long it took from \"we lost production\" to \"we are serving traffic.\" That number is your real RTO, and it is almost always larger than the one in the contract.<\/p>\n<h3>4. Restore the credentials and secrets too<\/h3>\n<p>An application restore without its environment variables, TLS certificates, and service credentials is a half-restore. Those belong in the backup and in the runbook.<\/p>\n<h3>5. Document what broke<\/h3>\n<p>Every restore test surfaces at least one thing that was assumed and never verified. That list is the actual value of the exercise.<\/p>\n<blockquote>\n<p>The purpose of a backup is not to make a copy. It is to make a promise you can keep.<\/p>\n<\/blockquote>\n<h2>How we do it at Weeltec<\/h2>\n<p>Our server management engagements start with an audit of what is actually protected, followed by a documented, scheduled restore test \u2014 not a one-off. Backups are versioned and stored outside the production fault domain, encryption keys are recorded in a password manager the team controls, and every restore procedure is written down as a runbook that a new engineer can follow without asking anyone.<\/p>\n<p>Monitoring closes the loop. A backup job that silently stops producing new archives is an incident, and it should page someone before the morning it is needed.<\/p>\n<h2>The rule<\/h2>\n<p>If your backup has never been restored, assume it does not work. Then prove yourself wrong \u2014 on purpose, on a Tuesday afternoon, not at 3 a.m. on the night before a product launch.<\/p>\n<p>Test the restore. Time it. Write it down. Repeat every quarter.<\/p>\n<p>That is the difference between having a backup and having a business that survives.<\/p>\n<p><em>Weeltec runs servers, Kubernetes clusters, and DevOps pipelines for companies that can't afford downtime. If your backup strategy has never been tested end to end, <a href=\"https:\/\/weeltec.com\/#contact\">get a quote<\/a> and we'll audit it properly.<\/em><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A backup you have never restored is a hope, not a safeguard. Here is how we test restore paths at Weeltec \u2014 and why the test matters more than the backup itself.<\/p>\n","protected":false},"author":1,"featured_media":34,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[4,6,5],"class_list":["post-35","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server-management","tag-backups","tag-devops","tag-disaster-recovery"],"_links":{"self":[{"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/posts\/35","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=35"}],"version-history":[{"count":3,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/posts\/35\/revisions"}],"predecessor-version":[{"id":77,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/posts\/35\/revisions\/77"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=\/wp\/v2\/media\/34"}],"wp:attachment":[{"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pomax-v3.weeltec.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}