The complete WordPress site, nothing left behind
Files, database, media, plugins, themes, wp-config, cron jobs, redirects and email settings, all copied with checksums.
A worked example of your brief, using a made-up client: Saltwick Inn & Table, a 13-room harbor inn and restaurant in Annapolis, Maryland. Its WordPress site moves to a hardened VPS, its data moves to PostgreSQL, and a new reservation system goes live. A tested rollback is ready at every step.
Each part of your post maps to one step with a result you can check. Click any card to open the details.
Files, database, media, plugins, themes, wp-config, cron jobs, redirects and email settings, all copied with checksums.
Ubuntu 24.04 · Nginx · PHP 8.3
Types, keys and relationships mapped, then verified table by table.

Rooms and dinner tables, live availability, confirmations and an admin board.
tables verified · SSL A+ · restore tested
Deploy, rollback and renewal steps, written down.

The old server stays running and untouched for 14 days. One DNS switch takes you back.
The 3D view stays in place while you scroll through the five steps. Drag it to rotate. Staging gets a full copy first, and production moves only once.
Host snapshot, mysqldump and an uploads archive, copied off-site, with a test restore on a scratch server before anything else happens.
mysqldump --single-transaction | gzip
rsync with checksums, then a search-replace of the URLs. Staging is password-protected and kept out of search engines.
rsync -azh --checksum
Schema types cast, foreign keys rebuilt, sequences reset. Legacy bookings move into a proper reservations table.
pgloader mysql://… postgresql://…
Row counts and checksums are compared table by table, then every page and plugin gets a smoke test on staging.
./scripts/compare-checksums.sh
Read-only notice → final delta sync → DNS switch. Health checks are green before the switch, and the rollback script is ready.
./scripts/dns-switch.sh --back
This is the runbook you get, played back in order, so any engineer can repeat it later.
| Table | MySQL | Postgres |
|---|
WordPress core officially supports only MySQL and MariaDB, and many plugins write raw MySQL queries. So there are two paths. Both are tested on staging, and you choose.
Business data (reservations, guests, payments, leads) moves to PostgreSQL 16 behind the new Next.js API. WordPress content runs on MariaDB on the same VPS.
WordPress itself runs on Postgres through a translation layer (the PG4WP drop-in), which rewrites MySQL queries on the fly. Every plugin has to pass on staging first.
| Plugin (sample audit) | Uses raw SQL? | Path A | Path B (PG4WP) | Action |
|---|---|---|---|---|
| Yoast SEO | Some (indexables) | Works | Re-index | Rebuild indexables after the move |
| Contact Form 7 + Flamingo | No | Works | Works | Leads also copied to Postgres |
| Old booking plugin | Yes (custom tables) | Replaced | Replaced | Data migrated into the new system |
| WooCommerce (gift cards) | Yes (HPOS) | Works | Fails | Keep on MariaDB or use Stripe links |
| Elementor | Little | Works | Partial | Regenerate CSS, test every template |
| WP Mail SMTP | No | Works | Works | Re-authorize with Google Workspace / SES |
01Snapshot, off-site backup, plugin and cron list, DNS TTL lowered to 300s.
Ubuntu 24.04, Nginx, PHP 8.3, Postgres 16, MariaDB, UFW, fail2ban.
03staging.saltwickinn.com, password-protected, kept out of search engines.
pgloader run, checksums matched, plugin fixes applied and logged.
Booking flow, availability rules, email confirmations, admin board.
Mobile + desktop tests, Let's Encrypt, a backup restored to prove it works.
5-min read-only window, DNS switch, 48h watch, docs delivered.
$140 fixed · 7 working days
Every image and gallery in the current WordPress media library moves over and is checked against the original. Filter the gallery, and hover to play the video clips.
Both screens on the right are the real demo, not pictures. A booking on the phone appears on the admin board right away. In production the same calls go to /api/reservations on PostgreSQL.
Rooms & dinner tablesLive availability by night and seating time. The same room can't be booked twice.
Clear totals in USDNightly rate, estimated taxes and a confirmation code.
Basic adminArrivals, check-in, cancel, search, occupancy and CSV export.
Harbor View Kingfrom $289 / night · 4 roomsBook →


The old server stays untouched and running until the new one has worked for 14 days. If anything looks wrong, DNS points back within minutes.
Full host snapshot, database dump and uploads archive, with a test restore.
So the final switch, and any switch back, spreads within minutes.
Bookings pause with a friendly notice, the last changes sync, and counts are re-checked.
SSL is already issued and health checks are green before the switch.
1-minute uptime checks, error logs, booking test emails. Roll back if needed.
Only after you confirm. A final archive is kept for 90 days.
To switch back to the old server. Bookings made in the meantime are exported and re-entered, so none are lost.
Each item is ticked in the handover document with the exact command or setting.
Password and root login off. PasswordAuthentication no
UFW allows only 22, 80 and 443. Databases listen on localhost only.
Blocks brute-force attempts on SSH and wp-login.php.
Let's Encrypt with auto-renew, HSTS, TLS 1.2+.
pg_dump + files to off-site storage, kept 30 days.
A backup is restored to a scratch database and checked.
unattended-upgrades. WordPress updates go to staging first.
1-minute checks, with email/SMS if the site or API is down.
7 working days · USD
Migration, VPS setup, the conversion (Path A), the reservation system and documentation. If you choose Path B and many plugins fail, the extra fixes are listed and agreed before any work starts.