What we actually ran
On September 14, 2026 we ran the official WordPress Playground CLI package @wp-playground/[email protected] using Node v26.8.2. The runtime reported WordPress 6.8.3 and PHP 8.3.33. Playground used SQLite, not a production MySQL service. The downloadable source pins the WordPress and PHP major/minor choices in both the Blueprint and CLI arguments; reproduce the run and inspect the reported versions.
The synthetic fixture contained one published lesson post, a reader account at example.invalid, a plain-text upload and a custom user-meta value of 42. That value represents test data only: no course plugin or real student record was installed. The source uses a deliberately public local-only fixture password. Never use it on an exposed installation.
The backup and recovery point
After the setup process exited, we copied the complete WordPress directory into a new backup directory. It contained WordPress core, configuration, themes/plugins, uploads and wp-content/database/.ht.sqlite. The SQLite file was 397,312 bytes. There was no active application writer during this copy. A files-only copy that omitted the database would not capture the post or user state.
We then added a second post to the original source. The source retained that post, but the earlier snapshot could not restore it. This is a controlled example of why orders, enrollments and progress created after a recovery point need a separate reconciliation plan. Do not replay real payments or merge application tables casually.
An incomplete restore looked partly healthy
We copied the backup to a new destination while deliberately excluding restore-marker.txt. The WordPress process completed successfully. Content, core login and synthetic user meta passed; the upload check failed. The harness required this exact failure, so an unexpected outcome would stop the run.
We rejected that destination and retained it for diagnosis. For rollback, we copied the untouched known-good backup into another new directory and ran the same acceptance checks. The original source and failed destination were preserved. No existing live site was overwritten.
| Acceptance check | Incomplete copy | Complete snapshot |
|---|---|---|
| Expected post content | Passed | Passed |
| Expected upload bytes | Failed as intended | Passed |
| Core wp_signon authentication | Passed | Passed |
| Synthetic progress meta = 42 | Passed | Passed |
| Post-snapshot write absent | Confirmed | Confirmed |
Measured time and what it excludes
The complete backup copy took 0.563 seconds. Copying it and running the WordPress acceptance checks took 2.524 seconds total in this single local run. The initial fixture setup took 6.568 seconds and is excluded from recovery time. These are measured elapsed times for this fixture, not a distribution, service-level objective or customer recovery estimate.
This run used local storage and a small synthetic database. It did not measure network transfer, a host support queue, DNS, production load, email delivery, payment state or a remote backup product. It provides no Kinsta, WP Engine or Liquid Web performance evidence. Core wp_signon success also does not establish browser cookie navigation, protected lesson authorization or a real LMS progress calculation.
Reproduce the rehearsal
Download wordpress-restore-demo.mjs below. With Node 20.18 or newer, npm and internet access, run: node wordpress-restore-demo.mjs ./my-new-rehearsal. Choose a directory that does not exist; the source refuses an existing destination. It runs the pinned official npm package ephemerally without adding a runtime dependency to this publication.
The output contains report.json, each Blueprint, process logs and the source, backup, incomplete-restore and complete-restore directories. report.json records commands, runtime versions, elapsed times, backup hash and each check. Keep the installation directories private: they contain local WordPress configuration and synthetic authentication data. The published result file contains only the limited report, not the installation.
The restore operation is a recursive offline copy followed by run-blueprint with --wordpress-install-mode=do-not-attempt-installing. Inspect the downloaded source for the exact commands, comparison values and intentional upload omission. Each repetition creates a new destination; timings will differ.
Turn this into your own course-site acceptance test
Use the same acceptance pattern with your actual staging stack, then add checks this demonstration does not cover. The companion course-migration and cutover guides below help place recovery before the DNS decision. Keep customer mail, payment processing and scheduled jobs isolated during rehearsal.
| Additional check | Evidence to retain |
|---|---|
| Database and files at one recovery point | Snapshot timestamps and consistency method |
| Real LMS and membership state | Synthetic enrolled user, expected lesson progress and entitlement |
| Anonymous versus member access | Anonymous denial and authorized protected-page access |
| Browser login and media | Session navigation and representative restored files |
| Post-snapshot writes | Write freeze or application-owner reconciliation procedure |
| Provider recovery time | Queue, transfer, restore and verification measured separately |
Sources & verification
Product details and prices can change. Check the linked provider before buying.
- WordPress backup guidance Accessed 2026-09-14
- WordPress Playground CLI: official setup and database persistence documentation Accessed 2026-09-14
- Original local rehearsal: commands, measured times and check results Accessed 2026-09-14
- Next: protect course progress and payments during migration Accessed 2026-09-14
- Next: cutover acceptance and rollback checklist Accessed 2026-09-14
Sources link directly to providers. Product buttons may use separately labeled affiliate links. Read our disclosure.