A few days ago my company website was blank. No content, no error message, no admin login. Thirty minutes later it was running again, not from a backup but from a complete rebuild from nothing. This article describes that cold start step by step: what gets deleted, in which order, what comes back afterwards and which conditions make it possible at all. At the end comes the classification of why a cold start does not replace a backup but does something else entirely.
Contents
- The site was blank
- Why troubleshooting is the trap
- What a cold start requires
- Why design is the most painful part
- Step 1: take stock of what only lives on the server
- Step 2: detach the domain from the web space
- Step 3: delete every file, really every one
- Step 4: drop the database, do not empty it
- Step 5: install WordPress from scratch
- Step 6: run the deploy
- Step 7: plugins, legal pages and cookie banner
- Step 8: the acceptance checklist
- The 30 minutes in detail
- What the cold start does not bring back
- The manual remainder: what the provider does not offer
- Cold start or backup?
- Practising the cold start without risking the live site
- FAQ
- Conclusion
- Sources
The site was blank
Loading the home page returned an empty response. No layout, no text, no error message in the browser, because displaying PHP errors is rightly switched off on a production server. The backend at /wp-admin behaved identically: blank page, no form, no way to log in.
The site had run for weeks without complaint before that, and there had been no deploy during those weeks, so no new line of code was a candidate cause. Whatever had happened, it had not been triggered by a change of mine.
The obvious way out was the host’s backup. It could not be turned back into a working site. That ruled out the comfortable option and left the real question on the table: repair or rebuild?
The stakes are higher than a company website initially sounds. That site carries the imprint and the privacy policy, and both have to be reachable as long as the offering is online. A site that serves nothing is therefore more than an image problem.
Why troubleshooting is the trap
The reflex that sounds professional is diagnosis. Disable plugins one by one, swap the theme for a default one, switch on WP_DEBUG, raise the memory limit, read through the host’s logs. All of that is right if the cause surfaces within minutes.
It is wrong when it does not. Troubleshooting has no upper bound. It delivers no result at a time you can commit to, and in an outage that is the property that decides everything. A rebuild, by contrast, has a known duration. Anyone who knows both numbers does not need to debate: if the rebuild takes half an hour, the search must not swallow two.
On top of that comes an argument that weighs more. A blank page with no visible cause can be a compromise. In that case repair is the wrong answer, because nobody knows what else is sitting in the file system and in the database. Deleting is then the only clean route.
The resulting order is this: rebuild first, so the site is back online. Investigate the cause afterwards, without time pressure and on a copy, if you want to know it.
What a cold start requires
A cold start is not a stunt. It is the consequence of a decision made long beforehand. It only works if the site does not exist exclusively on the server.
The content exists under version control, so page structure, texts and images as files in a repository and not only as database rows. The configuration is described rather than clicked, so menus, home page, permalink structure and theme options. The plugin list is part of that description and not part of my memory. The legal pages are under version control as well. And there is a repeatable deploy step that produces the complete site from that description.
That changes the status of the running installation. You are allowed to throw it away, because it can be recreated at any time without anyone having to think.
The principle is not new, it is the website edition of immutable infrastructure: servers get replaced instead of nursed. What is new at best is how rarely it gets applied to websites. Most company sites are grown one-off pieces whose origin nobody can reconstruct any more, and that is why the backup remains the only hope there.
Why design is the most painful part
Pages and posts can be exported, WordPress ships a tool for that itself. What makes a cold start hard is the appearance, and the reason is structural: the design lives in the database and not in files.
Theme settings sit as a single serialised value in the options table, under a name that contains the theme name. Menus are entries of a taxonomy plus their own records that point at page IDs. The assignment of widget areas is another option. And once a page builder is involved, the entire layout of every single page sits as a large serialised block in that page’s metadata, with absolute URLs and numeric IDs buried inside it.
After a reinstall the content is back and the appearance is bare. Colours, font sizes, spacing, header and footer, the home page assignment and every setting that was ever moved on a slider are defaults. Rebuilding that by hand is not a ten-minute job but an afternoon, and it never turns out identical, because nobody remembers the value of every slider.
On top of that the IDs are new. A freshly installed WordPress hands out new numbers for pages and media. Copy a page builder’s design data straight back and you get no error message, but vanished images and links that point at the wrong page. That is what naive migrations fail on, silently and without warning.
Either the design lives as code in the theme, meaning templates and CSS in a repository, in which case it is simply there after the deploy. Or the design settings are exported as files and put back on import, in which case the import has to rewrite the old IDs to the newly assigned ones, usually via unique names rather than numbers.
With a builder-driven design a cold start is considerably harder, because the builder’s data is the design. Anyone taking that route should know they are tying themselves to their backup. For our own site this was one of the reasons to pull the appearance into the theme as code, and this incident was the invoice issued for that decision.
Step 1: take stock of what only lives on the server
Before the first deletion comes a question nobody likes asking. What exists exclusively on this server and nowhere else? Everything that falls under it is gone after the deletion, and the decision about it happens now, not later.
Typical candidates are the uploads folder with media that never made it into the repository, submissions from the contact form, comments, access statistics and texts that were edited directly in the backend at some point. That last one is the most dangerous, because it is invisible. A wording corrected in the backend looks online exactly like a versioned one but behaves in the opposite way during a cold start.
In practice this step takes a few minutes: download the uploads folder over FTP, pull a database dump and save the plugin list. The dump is worth having even if it cannot be restored, because it is the material for the later root cause analysis.
Step 2: detach the domain from the web space
This step comes before the deletion, and the order is not a detail. As long as the domain points at the broken directory, you are working on the publicly reachable system. Visitors, crawlers and monitoring then see every intermediate state: the half-emptied installation, a bare directory listing, in the worst case the WordPress setup wizard.
That last case is the serious one, and it is worse than it first sounds. A WordPress without wp-config.php sends every visitor into the setup, and the setup asks for nothing beyond a reachable database. An attacker supplies their own, the installer writes those credentials into wp-config.php, and from then on a working site runs under your domain on a foreign database. A single request is enough. Wordfence described the technique in 2017 as the WPSetup attack, and it still works, because it exploits no vulnerability but the intended flow. A maintenance window of ten minutes is enough for that.
Either you release the domain assignment in the hosting panel and let it point at a static maintenance page, or you build the new installation in parallel in a second directory and switch the domain over only at the end. The second route is the better one, because the downtime shrinks to a single click.
A change to the domain assignment can trigger a reissue of the certificate, and that takes its minutes. And anyone turning the DNS instead of the directory additionally waits out the validity period of the old record. That is why the DNS record is best left untouched.
Step 3: delete every file, really every one
Nothing is left in the document directory afterwards.
wp-admin/
wp-includes/
wp-content/ complete, including uploads, plugins, themes, mu-plugins
wp-config.php
wp-config-sample.php
index.php
xmlrpc.php
wp-*.php every other file matching this pattern
.htaccess
.user.ini and every other hidden fileThe reflex to keep wp-content is understandable and exactly the point where a cold start stops being one. That folder holds more than images and plugins. It also holds mu-plugins, which WordPress loads without activation, drop-ins such as object-cache.php and advanced-cache.php, which hook into the core, generated cache directories and, in case of a compromise, the most interesting files of all. Take that folder along and you have reinstalled while keeping the old state.
Without SSH access this runs over FTP or the host’s file manager, and both are slow with thousands of small files. It is faster to delete the document directory as a whole and create it again, if the host allows that. And the FTP client has to show hidden files, otherwise the old .htaccess stays behind and writes rewrite rules for an installation that no longer exists.
Step 4: drop the database, do not empty it
Emptying tables feels clean and is not. What remains are the table structures of old plugin versions, orphaned rows in wp_options, options with autoload set that get loaded on every single request, expired transients and broken serialised values that PHP fails on silently. In case of a compromise, entries in wp_users and wp_usermeta join in that look unremarkable at first glance.
The database is therefore discarded and created anew, with a new user and a new password. The new user matters, because the old credentials may have been the cause themselves.
DROP DATABASE old_database;
CREATE DATABASE new_database
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_520_ci;
CREATE USER 'new_user'@'localhost' IDENTIFIED BY 'freshly-generated-password';
GRANT ALL PRIVILEGES ON new_database.* TO 'new_user'@'localhost';
FLUSH PRIVILEGES;On rented web space this is often not doable that way, because DROP DATABASE and creating users are not offered in the web interface at all. In that case you delete the database in the host’s panel and create a new one. The result is the same, the route is manual work. The article comes back to that point further down.
The character set specification is not decoration. Deviate from the previous setting here and you get broken special characters when the content is imported, and the damage does not show on the home page but in older texts that are rarely opened.
Step 5: install WordPress from scratch
Now the current WordPress version goes into the empty directory. Three things are deliberately set rather than carried over.
You choose the PHP version yourself instead of accepting the host’s default. A cold start is the cheapest moment to move to a current version, because everything is arriving fresh anyway and incompatibilities show up immediately instead of in six months.
The wp-config.php is written from scratch rather than restored from the backup. It contains the new database credentials and fresh security keys. New keys invalidate every existing session and every login cookie that was set, and that is precisely what you want. Added to that are the settings this host needs, for instance a fixed method for file system access so that installations do not ask for FTP credentials.
The item overlooked most often is visibility for search engines. A fresh installation can be configured to prevent indexing, and that setting survives the entire rebuild unnoticed. Equally important is the permalink structure. If it is not set the way it was before, every subpage answers with 404 even though the content is fully present.
Step 6: run the deploy
The part that makes the 30 minutes possible at all is the shortest one. A deploy step brings back theme, page structure, texts, images, menus and settings, because all of it exists as a description.
Which technology sits behind that is secondary for this article. The step is repeatable, so it produces the same result from the same starting state, and it is idempotent, so a second run changes nothing. That sounds academic and pays off during an outage, because you rarely know for certain what has already run and what has not.
A backup produces a state whose origin nobody knows. A deploy produces a state whose origin exists as a description and is therefore verifiable.
There is still an order inside this step, and it is not arbitrary. Media come before content, because content refers to media IDs. Content comes before menus, because menu items point at page IDs. Settings come last. Reverse the order and you get no error, but silent references into nothing, and that is the worse of the two outcomes.
The appearance comes along in this step because it lives in the theme as code and not in the options table. That is exactly the difference between 30 minutes and an afternoon.
Step 7: plugins, legal pages and cookie banner
At this point the plugin list is not a memory exercise. It is in the description, and it gets rebuilt in a particular order.
First the consent management, meaning the banner and the rules about which services stay blocked before consent. In Germany, consent for accessing end devices is governed by Section 25 TDDDG, and the law has carried that name since 13 May 2024, before which it was called TTDSG. Technically necessary items such as a session cookie are exempt, everything beyond that needs active agreement. A banner that only appears after the cookies have been set does not serve its purpose.
Then the legal pages. Imprint and privacy policy belong to the cold start and not to an addendum in the evening. In Germany the imprint obligation has been in Section 5 DDG since 14 May 2024, in the place where Section 5 TMG used to stand. If the texts come from a law firm or a service, that link has to be rebuilt. The text itself belongs in the repository, otherwise it is gone after the deletion just like everything else from the database.
Next come the contact form and the mail delivery. Delivery over an SMTP account has to be reconfigured, including credentials and sender address. Experience says this is the point forgotten on a first cold start, because it cannot be looked at. You see nothing, no mail simply arrives.
Deliberately absent is everything you wanted to get rid of anyway. A cold start is the cheapest moment to shorten a plugin list, because nothing needs uninstalling. It simply does not get installed again.
The reason this order has to be finished before the domain is switched over is in step 2: the site must not be publicly reachable without an imprint and without a consent banner, not even for ten minutes.
Step 8: the acceptance checklist
The site is not done when the home page looks like it did before. It is done when a list has been worked through. Looking at it is exactly how you miss the things you cannot see.
home page answers with 200
three subpages answer with 200
an invented URL answers with 404, not with 200
imprint and privacy policy reachable and linked in the footer
consent banner appears in a private window
declining sets no optional cookies
contact form sends a mail, and it arrives
all images load over https, no mixed content warning
certificate valid, including for the www variant
no noindex directive in the source
sitemap reachable
redirects for old URLs take effect
admin login with the new credentialsTwo of those points can be checked in seconds and are still the ones most often missed:
curl -s -o /dev/null -w "%{http_code}n" https://your-domain.com/
curl -s https://your-domain.com/ | grep -i "noindex"The second line has to output nothing. If it outputs something, the site is online and invisible to search engines, and that state otherwise only surfaces when the traffic numbers collapse.
The 30 minutes in detail
The time does not sit where you expect it. Broken down, the run looked roughly like this:
| Step | Duration |
|---|---|
| Taking stock and saving what matters | 5 minutes |
| Releasing the domain from the directory | 2 minutes |
| Deleting files | 6 minutes |
| Discarding and recreating the database | 2 minutes |
| Installing and configuring WordPress | 4 minutes |
| Deploy | 3 minutes |
| Plugins, legal pages, consent, mail delivery | 5 minutes |
| Acceptance and switching the domain back | 3 minutes |
The slowest item is the deletion over FTP, not the rebuild. The deploy itself is the shortest part of the whole procedure, and that is the actual point of the exercise.
One row is missing from this table that would be the largest on most sites: the design. Were it not described as code in the theme but clicked together in the database, an item of several hours would have to stand here, and the 30 minutes would be a different number.
What is not in this calculation is the root cause analysis. That came afterwards, on a copy, without time pressure and without a publicly reachable site depending on it.
What the cold start does not bring back
Everything that lived exclusively in the database is gone. Form submissions, comments, access statistics and every text that was edited directly in the backend at some point. A cold start brings back what is described, and only that.
From that follows a working rule that is harder to keep up than the technical part. If you keep your site as code, you have to make changes there too. Every correction that happens only in the backend lets the live state drift away from the description, and the next cold start silently throws it away. The method is therefore only as good as the discipline with which it is used.
This is exactly where backups remain indispensable. They are the answer to data that cannot be reproduced, and almost every site has some.
The manual remainder: what the provider does not offer
The honest part of this story is the provider. Classic web hosting offers no interface for what was needed here: releasing a domain assignment, emptying a directory, discarding and recreating a database, setting the PHP version, reissuing a certificate. Those are clicks in a web interface, in their own order, and they are the reason 30 minutes do not become three.
On real cloud infrastructure this part would be described rather than clicked as well. Then not only the site would be reproducible but also the environment it runs in, and the cold start would be a procedure instead of manual labour. That is the more interesting sequel to this story, and it leads to the same place we work on with Vela Atlas anyway: environments that come out of a description and are therefore repeatable.
In this incident the website was reproducible, its environment was not. The difference cost around ten minutes of clicking, and those ten minutes are the only part of the procedure that cannot be practised, because it is equally boring and equally error-prone every time.
Cold start or backup?
The question is put wrongly, because both turn different dials. Two figures from disaster recovery make that tangible.
The recovery time, usually called RTO, describes how long it takes until operations are running again. The maximum tolerated data loss, the RPO, describes how much data may be lost in the process. A cold start pushes down the recovery time, because it works regardless of whether a backup is usable. It changes nothing about the data loss. Backups push down the data loss and say nothing about the duration.
If you want both, you need both. The practical complement is the familiar rule of keeping several copies on different media with one of them off site. And the sentence that demands the same test of both sides: a backup that has never been restored is an assumption. A cold start that has never been practised is one too.
Practising the cold start without risking the live site
This can be practised without risk, either on a subdomain with its own database or in a local container. The procedure is the same as in the real case: delete everything, run the deploy, work through the checklist, measure the time.
The value is not in the time but in what stands out. There is always one setting that existed only in someone’s head and in no description. For me it was the mail delivery. After the first run it was in the description, and in the real outage it was no longer an issue.
One run per quarter is enough. It costs half an hour and replaces the debate about whether the backups probably work.
FAQ
Would troubleshooting not be the more professional route? It is the more professional route when the cause is found quickly. Without a time budget it is a blank cheque, because a diagnosis guarantees no result at a fixed point in time whereas a rebuild with a known duration does. The cause can be established afterwards on a copy, at leisure.
Is it not enough to keep wp-content and only reinstall the core? For a quick repair yes, for a cold start no. wp-content holds mu-plugins that load without activation, drop-ins such as object-cache.php, generated cache directories and, in case of a compromise, the actually interesting files. Keeping the folder means taking the old state along.
Why is design harder to bring back in WordPress than content? Because it lives in the database and not in files. Theme settings sit as a serialised value in the options table, menus as taxonomy entries with references to page IDs, and with a page builder the layout of each page sits in its metadata. After a reinstall the IDs are new, which is why simply copying it back breaks silently. It only becomes reliable once the appearance lives as code in the theme.
Does the database really have to be deleted, or is emptying the tables enough? It gets discarded. Emptying leaves behind table structures of old plugin versions, orphaned options with autoload set, broken serialised values and possible foreign user accounts. New database name, new user, new password.
Why does the domain have to go before anything is deleted? Because a WordPress without wp-config.php sends every visitor into the setup and asks for nothing beyond a reachable database. An attacker enters their own and runs the site under your domain from then on. Wordfence describes this as the WPSetup attack. A short maintenance window is enough for it.
What happens to email accounts, DNS records and the certificate? Email accounts and DNS records do not hang off the web space at the host and stay in place as long as you do not touch them. That is exactly why the DNS record stays untouched and the switch happens through the directory assignment. The certificate may need a reissue, which needs planning in.
Does a cold start replace backups? No. It replaces the dependency on a backup working at the decisive moment. For data that cannot be reproduced, such as form submissions or orders, backups remain the only answer.
What do RTO and RPO mean here concretely? The recovery time (RTO) is the duration until operations run again, the maximum tolerated data loss (RPO) is the amount of data that may be lost in the process. The cold start improves the first figure, backups improve the second. They are two dials, not an either-or.
Does this work with a website builder as well? Only to a limited extent. A builder keeps content and configuration in its own system, and whatever cannot be exported and imported again cannot be rebuilt either. A cold start requires the site to be fully described outside its runtime environment.
Does the imprint have to stay reachable during maintenance? The safe route is to let the domain point at a static maintenance page during the rebuild that contains the imprint and the privacy policy. That settles the question, and the effort is a single HTML file.
Conclusion
Recovery is not the question of whether a backup exists but of whether a cold start is possible. Keep content, configuration, plugin list and legal pages as a description and you trade a hope for a procedure: the running installation becomes replaceable, and an outage turns into half an hour of work with a known ending instead of a search with an open one.
The next step is small. Take your own site and write down what exists only on the server and in no repository. That list is the difference between a cold start and a rebuild from memory.
Sources
- WordPress documentation on reinstalling,
wp-config.phpand security keys, wordpress.org - Wordfence, The WPSetup Attack, on taking over fresh installations through the setup page, wordfence.com
- Section 5 Digitale-Dienste-Gesetz (DDG), since 14 May 2024 in the place of Section 5 TMG
- Section 25 Telekommunikation-Digitale-Dienste-Datenschutz-Gesetz (TDDDG), since 13 May 2024 the name of the former TTDSG
- Regulation (EU) 2016/679 (General Data Protection Regulation), Article 32 on security of processing
- BSI IT-Grundschutz compendium, module CON.3 on backup concepts, bsi.bund.de
All examples come from the incident itself and are written from scratch. This article is a field report from practice and not legal advice. For your specific case, bring in a lawyer.