How to Restore a WordPress Site From a Backup (Without Losing New Orders)
Pick the right restore point, restore from a host snapshot, a backup plugin or raw files plus a SQL dump, and keep the orders and comments that arrived since.
Deleted a page, overwrote a post or broke a layout with one bad save? Get it back from the Trash, a revision, your page builder’s history or a backup, without rolling back the whole site.
You clicked Trash on the wrong page. You pasted over a long post and hit Update. A client “tidied up” the home page and now half the sections are gone. Or you spent an hour in the page builder, saved, and the layout is worse than before. Your first instinct may be to restore last night’s backup of the whole site. Usually you do not need to, and a full restore would throw away every order, form entry and comment since that backup.
WordPress keeps more safety nets than most people realize: a Trash that holds deleted posts and pages for 30 days by default, a revision history for every saved change, and page builders that keep their own history. This guide works through them from quickest to most involved, and ends with how to pull a single page out of a backup without touching the rest of the site. If the whole site is broken rather than one page, start with restoring from a backup or the deleted something triage page instead.
WordPress stores pages, posts and most custom content as rows in the wp_posts database table. Deleting and editing do not always remove data straight away.
| What you did | Where the old version usually is | How long it lasts |
|---|---|---|
| Moved a page, post or product to Trash | The Trash view of that list | 30 days by default (EMPTY_TRASH_DAYS), then deleted for good |
| Saved over content in the block or classic editor | Revisions for that page | Unlimited by default, unless WP_POST_REVISIONS limits or disables them |
| Changed a layout in a page builder | The builder’s history or revisions panel, often also WordPress revisions | Depends on the builder and its settings |
| Deleted a media file | Nowhere in WordPress. Media skips the Trash by default (MEDIA_TRASH is false) |
Only a backup has it |
| Deleted a menu item, or changed a setting | Not kept by WordPress | Only a backup has it |
| Emptied the Trash or used Delete Permanently | Not kept by WordPress | Only a backup has it |
So the order of attack is: Trash, revisions, builder history, and only then backups.
wp are WP-CLI and run over SSH in the site folder, the one containing wp-config.php. Some hosts name the command wp-cli. Every WP-CLI step here has an admin screen alternative, so SSH is optional. The WP-CLI cheat sheet explains connecting.Go to Pages (or Posts, or Products in WooCommerce). At the top of the list, next to All, Published and Draft, there is a Trash link with a count. It only appears when the Trash has something in it. Hover over the page and click Restore.
One detail catches people out: since WordPress 5.6, an item restored from the Trash list comes back as a Draft, not as published. Only the Undo link in the notice that appears straight after you trash something puts it back in its previous status. After restoring from the Trash list, open the page, check it, and click Publish. Until you do, visitors get a 404.
Over SSH, you can list what is in the Trash:
wp post list --post_type=page --post_status=trash --fields=ID,post_title,post_modified
--post_type=page limits the list to pages (use post, product or another type as needed), --post_status=trash shows only trashed items, and --fields picks the columns. Good output is a table with your page’s ID. An empty result means it is not in the Trash for that post type: either it was deleted permanently, the Trash was emptied, or it is a different post type. Restore it from the admin screen; it handles the stored previous status and slug for you.
When a page is trashed, WordPress adds __trashed to its slug so the address can be reused. On restore it normally puts the original slug back. If you created a new page with the same address while the old one was in the Trash, the restored page gets a different slug such as about-2. Edit the slug in the page settings, and delete or rename the stand-in page first.
Check whether someone set a shorter trash period. In wp-config.php, look for:
define( 'EMPTY_TRASH_DAYS', 30 );
The number is how many days items stay in the Trash before WordPress deletes them on a scheduled task. 0 disables the Trash completely, so Delete removes items immediately. If it is 0 or very low, the page is gone from WordPress and you need Step 5.
A revision is a saved copy of a post or page from a previous save. WordPress also keeps one autosave per user, taken every 60 seconds by default while you edit (AUTOSAVE_INTERVAL).
In the classic editor, Revisions sits in the Publish box. If it is missing, open Screen Options at the top of the screen and check Revisions.
wp post list --post_type=revision --post_parent=PAGE_ID --post_status=inherit --fields=ID,post_date,post_author --orderby=date --order=DESC
Replace PAGE_ID with the page’s ID (shown in the address bar as post=123 when you edit it). --post_parent limits the list to revisions of that page, --post_status=inherit is the status revisions use, and the order options put the newest first. Good output is a list of revision IDs with dates. To read one before restoring it:
wp post get REVISION_ID --field=post_content | head -n 40
This prints the first 40 lines of that revision’s content so you can check it is the version you want. To restore it from SSH, which is the same function the Restore button uses:
wp eval 'wp_restore_post_revision( REVISION_ID );'
wp eval runs one line of PHP with WordPress loaded. No output means it ran; check the page in the browser. The admin screen is safer for most people because you see the comparison first.
Check wp-config.php for WP_POST_REVISIONS. true (the default) keeps every revision, a number keeps that many per post, and false or 0 keeps none apart from the autosave. Speed plugins and database cleanup tools sometimes delete all revisions or set this to a low number. If revisions were cleaned out recently, the version you need is only in a backup. Setting a limit is fine for database size (see database bloat); turning revisions off entirely is what removes this safety net.
Page builders usually keep two layers: an undo history for the current editing session, and saved revisions that last longer.
| Builder | Where to look | Notes |
|---|---|---|
| Breakdance | In the builder, the ... menu, then History, with History and Revisions tabs |
History covers the current session only. Revisions lists saved versions; click one to load it, then save. A revision limit can be set in Breakdance settings. |
| Elementor | The History panel in the editor (Ctrl+Shift+H on Windows, Cmd+Shift+H on Mac), with Actions and Revisions tabs | Actions is the session undo list. Revisions lists saved versions, which Elementor stores as WordPress revisions, so WP_POST_REVISIONS affects them. |
| Divi | The History button in the Visual Builder’s bottom settings bar; WordPress revisions for saved versions | History lists undo states for the session. Older saved versions come from WordPress revisions. |
| Bricks, WPBakery, Avada | The builder’s own undo and revision tools, plus WordPress revisions | See the WPBakery, Avada and Bricks guide for where these store data. |
Menu labels move between versions, so if the label differs on your screen, look for a clock or history icon. Load the older version, check it in the preview, then save. Saving creates a new revision, so you can step back again if needed. After restoring a builder layout, regenerate or clear the builder’s CSS files if styles look wrong; the page builder troubleshooting guide covers that.
Headers, footers, global blocks, theme templates and design settings in builders and block themes are separate items with their own history, not part of the page. If the change you want to undo is in a header or a global style, open that template and check its own revisions. In block themes, templates and global styles have revisions in the Site Editor, and a customized template can be reset to the theme’s version; see Site Editor changes not saving.
wp-content/uploads; the guide on recovering with no backup shows how to register files back in the media library.If the page is not in the Trash, has no usable revisions and no builder history, you need a backup. The goal is to recover only that page, not to roll the whole site back. Never restore an old full backup over a live shop or membership site just to recover one page: you would lose every order, user and form entry since. The staging to live guide explains why.
Many control panels can restore a backup to a separate location, or restore only the database or only selected files. Restore the backup to a staging site or a new subdomain rather than over the live site. Then copy the page across using option B or C. The hosting control panel cheat sheet lists where backups live in common panels.
For pages built in the block or classic editor, the content field holds everything. On the staging copy, open the page, switch to the code editor (the three-dot menu, then Code editor, or Ctrl+Shift+Alt+M), copy everything, then paste it into the code editor of the page on the live site and save. Or over SSH on the staging copy:
wp post get PAGE_ID --field=post_content > page-content.html
This writes the page’s content to a file you can download and paste in. It does not include the featured image, template choice or custom fields; set those by hand.
If the page no longer exists on live at all, create a new page with the same slug and paste the content in. Or use Tools, Export on the staging copy, choose the page type, then Tools, Import on live with the WordPress Importer plugin. The importer creates the page as a new item with a new ID, and may skip it if a page with the same title and date already exists.
Builders such as Elementor, Breakdance and Bricks store the layout in post meta fields, not in the main content, so copying the content field alone gives you an empty or unstyled page. Use the builder’s own template export on the staging copy: save the page or its sections as a template, export it as a file, then import that template on the live site and insert it into the page. This is the method builder vendors support, and it carries the layout data intact.
Copying builder meta fields directly with SQL or WP-CLI is possible but fragile: the data is often JSON or serialized PHP that breaks if quotes or slashes are altered in transit. Leave that to a developer, and only on a copy.
Try the Wayback Machine and other caches described in recovering a site with no backup. For a single public page, a capture there often gives you all the text and images back, even if you have to rebuild the layout.
If you are not sure whether a page was trashed, deleted or just unpublished, look at its row directly. Over SSH in the site folder:
wp db query "SELECT ID, post_title, post_status, post_name, post_modified FROM $(wp db prefix)posts WHERE post_type='page' AND post_title LIKE '%PART_OF_TITLE%';"
$(wp db prefix) inserts your table prefix (often wp_), and PART_OF_TITLE is a word from the page title. A post_status of trash means it is in the Trash, draft or private means it is hidden but present, and no row at all means it was deleted permanently. This only reads data; it changes nothing.
To see who did it, check an activity log plugin if one is installed. WordPress itself does not log who deleted what, which is a good reason to install one on client sites before you need it.
Ask your host for a restore of the database to a separate location, from a date before the change. Send:
Once the page is back, take an on-demand backup and check your backup schedule against the backup plan checklist and the monthly maintenance checklist. If someone else on the team caused the change, give them an Editor account instead of Administrator.
Did this fix it?
Still stuck? Start again from what you can see in the Emergency Room.
Still stuck?
Print a free one-page checklist to keep, or open the Emergency Room if the symptom does not match.
Get the free checklistsKeep reading
Search the field manual
Or jump straight to a symptom
Press / to search from any page, Esc to close