SwiftMigrate – Site-to-Site Migration
SwiftMigrate is a server-to-server migration plugin for WordPress. Install it on both sites, paste a one-time key from the new site into the old one, and the whole site streams across in parallel, checksummed chunks. Every chunk is verified on the destination before the switch-over, and the switch itself is atomic with a one-click rollback.
by SwiftMigrate · github.com/qaziwebsitewala/swiftmigrate · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/qaziwebsitewala/swiftmigrate/archive/refs/heads/main.zipMove a complete WordPress site — database and every file — directly from one server to another. Nothing is downloaded to your computer, nothing is lost on the way.
SwiftMigrate is a server-to-server migration plugin for WordPress. Install it on both sites, paste a one-time key from the new site into the old one, and the whole site streams across in parallel, checksummed chunks. Every chunk is verified on the destination before the switch-over, and the switch itself is atomic with a one-click rollback.
Features
Fast
- Parallel transfer streams (4 by default, up to 16)
- Thousands of small files packed into a single request; large files of any size split into chunks
- Fast gzip for text, code and SQL; already-compressed media is sent as-is
- Database export by primary-key ranges, so huge tables stay fast
- Chunk size negotiated automatically from the destination's upload and memory limits
Nothing gets lost
- SHA-1 checksum on every file and chunk; the destination rejects anything that doesn't match
- After the transfer, the destination confirms every chunk; missing or damaged data is resent automatically (up to 3 repair passes) before a restore is allowed
- Binary-safe SQL export (BLOBs, BIT columns, generated columns handled), statement size adapted to
max_allowed_packet - Resumable: close the browser tab at any time, come back, press Resume. Only unfinished chunks are sent again
Safe restore
- Database imported into temporary tables first, then all tables swapped in one atomic
RENAME TABLE - Serialization-safe search & replace for URLs and server paths, including nested serialized, JSON-escaped and URL-encoded data, plus your own custom find/replace pairs
- Different table prefixes between the two sites handled automatically (roles and user meta included)
- Write-ahead journal for file moves, plus a rollback copy of the destination's previous files and database
- One-click Rollback or Delete rollback copy from either site
Secure
- Every request signed with HMAC-SHA256, time-limited and single-use (replay protection)
- Keys expire (24 h by default) and are revoked when the plugin is deactivated
- Failed-authentication throttling
- Working data stored in a protected directory that blocks direct web access
wp-config.php,.htaccess,.user.ini,php.iniandweb.configon the destination are never overwritten
Works on ordinary hosting
- Every server step is time-sliced and stays below
max_execution_time - Receiving endpoint boots WordPress in
SHORTINITmode, so it stays fast and independent of other plugins; falls back to a front-end route if the direct endpoint is blocked - Firewall-friendly mode (text encoding) for hosts or security plugins that block binary uploads
- No external services: data goes only between your two servers
How it works
Old site (source) New site (destination)
┌──────────────────┐ signed, checksummed ┌──────────────────────┐
│ scan files + DB │ ───────────────────────▶ │ staging area │
│ parallel workers │ chunks (N streams) │ verify every chunk │
│ resume bitmap │ ◀─── missing chunks ──── │ import → replace URLs │
└──────────────────┘ │ atomic table swap │
└──────────────────────┘
- Scan: builds a job list of database ranges, file batches and large-file chunks
- Transfer: parallel workers send jobs; progress is checkpointed continuously
- Verify: the destination confirms every job; anything missing is resent
- Restore: import, search & replace, move files, atomic database swap
Usage
- Install and activate SwiftMigrate on both sites.
- On the new site: SwiftMigrate → Receive a site → Generate migration key → Copy key.
- On the old site: SwiftMigrate → Send this site, paste the key, click Connect.
- Review the pre-flight check and choose what to move: database, uploads, themes, plugins, WordPress core, other root files.
- Confirm and click Start migration.
- When everything is verified, click Restore on destination (or enable Restore automatically).
- Log in to the new site with the old site's username and password.
- Check the site, then Delete rollback copy, or Roll back if something is wrong.
Admin pages
| Page | Purpose |
|---|---|
| Overview | Server environment check and recent migrations |
| Send this site | Connect, pre-flight check, live progress (speed, ETA, files), restore |
| Receive a site | Generate/revoke key, watch incoming migration, rollback/purge |
| Settings | Streams, chunk size, excludes, skipped tables, safety and connection options |
| History & logs | Every migration with full, downloadable log |
Settings
| Setting | Default | Notes |
|---|---|---|
| Parallel streams | 4 | 8–12 on VPS/dedicated servers |
| Maximum request size | 8 MB | Auto-capped by destination limits |
| Small files per request | 1500 | |
| Database rows per chunk | 2000 | Lower for very large rows |
| Work per server request | 20 s | Kept below max_execution_time |
| Compress transfers | On | |
| Skip transients / spam / revisions | On / On / Off | |
| Keep a rollback copy | On | Needs extra disk space on destination |
| Verify SSL certificates | On | |
| Firewall-friendly mode | Off | ~35% slower, avoids WAF blocks |
| Key lifetime | 24 h |
Excludes accept content:path (relative to wp-content), abs:path (relative to the WordPress root) and wildcard patterns such as *.log or */node_modules. Common cache and backup folders are excluded by default.
Requirements
- WordPress 5.8+
- PHP 7.4+ with
mysqli(zlib recommended) - MySQL 5.7+ / MariaDB 10.3+
- Both sites reachable from each other over HTTP(S)
- Writable
wp-contenton the destination
Limitations
- Multisite networks are not supported
- Files that exist only on the destination are left in place
- Changes made on the source while a migration runs may not all be captured; avoid editing during the transfer
- Symlinked directories are not followed
Troubleshooting
- HTTP 403 / 406 during transfer: enable Firewall-friendly mode, or whitelist
/wp-content/plugins/swiftmigrate/endpoint.phpin your security plugin - Timeouts: lower Parallel streams and Maximum request size
- Self-signed certificate on destination: disable Verify SSL certificates
- Anything else: check History & logs; every step is logged on both sites
Project structure
swiftmigrate/
├── swiftmigrate.php Plugin bootstrap
├── endpoint.php Fast SHORTINIT receiving endpoint
├── uninstall.php Removes settings, working data, staging/rollback tables
├── includes/
│ ├── class-source.php Scan, job log, DB export, transfer, verify
│ ├── class-receiver.php Staging, verification, restore state machine, rollback
│ ├── class-search-replace.php Serialization-safe search & replace
│ ├── class-security.php Keys, HMAC signing, nonces, throttling
│ ├── class-packer.php Wire format (header + payload, gzip, checksums)
│ ├── class-client.php Signed HTTP client
│ ├── class-api.php Request routing on the destination
│ ├── class-db.php mysqli wrapper, binary-safe escaping
│ ├── class-storage.php Protected working directory, atomic JSON state
│ ├── class-settings.php, class-logger.php, class-plugin.php
├── admin/views/ Admin pages
└── assets/ admin.css, admin.js (vanilla JS orchestrator)
License
GPLv2 or later.