Skip to content
How-to guide

Verify a migrated App

Verify the target with representative production data before changing public DNS.

Open Deploys and confirm that the target serves the intended Git revision or captured Workspace content. Resolve failed or incomplete deploys before testing application behavior.

Use a temporary hostname or controlled preview path. Test the highest-value journeys for the App, including:

  • sign-in and account actions;
  • browse, search, cart, checkout, or form submission;
  • administrative changes;
  • file upload and download;
  • transactional email and external callbacks;
  • scheduled and background work.

Use test payment and messaging credentials where the provider supports them. Don’t create unintended production transactions.

Compare source and target counts for business-critical records, running the same queries on both sides. On the target, run them from the managed shell, where the MySQL client and the platform-provided DATABASE_* variables are already available. A Team owner or admin must first grant the shell or database access these commands use.

Table-level SQL counts are the import parity check. Both frameworks support a table prefix, and a migrated database keeps the prefix its source used — confirm it first (wp db prefix on WordPress, or SHOW TABLES LIKE '%sales_order'; on Magento) and use it in the queries:

Count table rows from the managed shell
# Prefixed install? Use the prefixed names, e.g. myshop_sales_order.
mysql -h "$DATABASE_HOST" -u "$DATABASE_USER" -p"$DATABASE_PASSWORD" \
"$DATABASE_NAME" -e \
"SELECT COUNT(*) AS posts FROM wp_posts;
SELECT COUNT(*) AS orders FROM sales_order;
SELECT COUNT(*) AS customers FROM customer_entity;
SELECT MAX(created_at) AS newest_order FROM sales_order;"

WP-CLI counts answer a different question — published content, not import parity. wp post list --format=count counts published posts of one type and excludes drafts, revisions, and attachments, so it is legitimately lower than the wp_posts table count. Compare WP-CLI output only with WP-CLI output from the source, and list the post types your App actually uses first — a count for a type that doesn’t exist returns 0 rather than an error, which reads as data loss:

Count published WordPress content from the managed shell
wp post-type list --field=name
wp post list --post_type=post --format=count
wp user list --format=count
wp comment list --format=count

Run the matching queries against the source with its own credentials and compare the results. The newest-record timestamps catch a copy taken from a stale export even when the counts happen to match. Sample recent records and verify relationships, timestamps, status values, and media links.

For a large App, define acceptable comparison tolerances before the test — counts on a busy source drift between export and comparison. Any unexplained difference blocks cutover, because the next step freezes the source against exactly these numbers.

Check:

  • error responses and application logs;
  • recent request traces whose method and request URL match the tested journeys; check each cache result and ranked hotspot, then open the waterfall and confirm the php-fpm, mysql or mariadb, redis, opensearch, and rabbitmq spans that apply to the App;
  • resource usage during representative load;
  • scheduled-job run history;
  • domain and redirect behavior;
  • cache and search freshness;
  • write access to required persistent paths.

Open Backups and confirm that the target reports current protection before cutover. Know which recovery point you would use if the final data copy or post-cutover verification fails.

Keep a checklist with the tester, time, result, and evidence for each critical journey. Resolve every blocking item, repeat the affected test, and obtain cutover approval from the people responsible for the application.

Continue with Cut traffic over.