ARTICLE

Sanitized Production Database Copies for Magento Staging: Masking Customer Data With n98-magerun2 and GdprDump

Sanitized Production Database Copies for Magento Staging: Masking Customer Data With n98-magerun2 and GdprDump

To copy a Magento production database to staging safely, dump it with personal data removed or replaced. Use n98-magerun2 db:dump strip groups to empty logs, sessions, and admin tables, and Smile GdprDump to replace names, emails, addresses, and order details with fake values. Then reset base URLs, email sending, payment sandbox flags, and search hosts before anyone logs in.

Most teams know they should not restore raw production data on a staging box. Fewer have a repeatable process for it, so the shortcut wins on deadline day. This guide lays out a process you can script once and run every time: what to strip, what to anonymize, which tool does which job, and the post-import checklist that stops a staging site from emailing real customers or charging real cards.

Why raw production copies are a real risk

A Magento database holds customer accounts, password hashes, addresses, phone numbers, order histories, payment metadata, admin users, and integration tokens. Staging and development environments usually have weaker access controls than production: more people with SSH, shared credentials, laptops with local copies, and third-party contractors.

Regulators do not treat test environments as exempt. GDPR and CCPA compliance checklists count development and staging environments as part of your regulated footprint, and card data rules point the same way, which is covered in our PCI DSS 4.0.1 runbook for Adobe Commerce.

There is also a practical risk that has nothing to do with regulators. A staging site restored from production still has production’s email settings, payment keys, and cron jobs. One forgotten setting and staging sends order emails to real customers or pushes test orders into your ERP.

Strip versus anonymize: two different jobs

The single most useful idea in this whole topic is that “sanitizing” covers two different operations, and you usually need both.

  • Strip means keep the table structure but drop all rows. It is fast and safe, and right for logs, sessions, caches, and admin data. It is wrong for customers and orders if your QA team needs to test account pages, order history, returns, or reorder flows, because those pages will be empty.
  • Anonymize means keep the rows but replace personal fields with fake or hashed values. It is slower, but it gives testers realistic data volumes and relationships without real identities.
Approach Data left in staging Speed Good for Weak spot
Raw copy Everything, including PII Fastest Nothing you should allow Compliance and accidental emails
Strip only (n98-magerun2) Catalog, CMS, config; empty customer and order tables Fast Frontend and catalog work No customer or order data to test with
Anonymize only (GdprDump) All rows, personal fields replaced Slower Full QA of account and order flows Larger dumps, config still needs resetting
Strip plus anonymize Realistic customers and orders, no logs or sessions Moderate Most teams Needs a maintained config

A common split: strip logs, sessions, admin, OAuth, and search history, and anonymize customers, quotes, and sales.

n98-magerun2 db:dump and its strip groups

n98-magerun2 is the standard command-line toolbox for Magento 2, and its db:dump command wraps mysqldump (or mydumper) with Magento-aware table groups. The key options:

  • --strip keeps structure and drops data for tables or groups, space-separated and wildcard-friendly.
  • --exclude drops a table entirely, including its structure.
  • --include overrides an exclude pattern for a specific table.
  • --compression supports gzip, lz4, and zstd.
  • --human-readable writes one insert per row with column names, which is handy for diffing.
  • --no-tablespaces avoids needing the MySQL PROCESS privilege, which managed database services often do not grant.

Single-transaction mode is on by default so the dump does not lock writes. The project’s documentation marks turning it off as not recommended.

A typical development dump looks like this:

n98-magerun2.phar db:dump --strip="@development" --compression="gzip" staging.sql.gz

What the groups actually contain

Group names are easy to misremember, and older blog posts list outdated contents. In the current configuration file in the project repository:

  • @development combines @admin, @oauth, @trade, @stripped, @search, @2fa, and @aggregated.
  • @trade combines @customers, @sales, @quotes, @klarna, and @mailchimp.
  • @stripped covers @log, @sessions, @dotmailer, @newrelic_reporting, @temp, @ee_changelog, @indexer_batches, and the system config snapshot table.
  • @customers covers customer entity and address tables, the customer grid, newsletter subscribers, product alerts, vault payment tokens, wishlists, B2B company tables, gift card accounts, store credit, and reward points. The project notes it should not be used without @sales.
  • @sales covers orders, invoices, shipments, credit memos and their sequence tables, PayPal agreement and transaction tables, inventory reservations, RMA, and sales grid archives.
  • @quotes covers quote tables and B2B negotiable quotes.
  • @admin covers admin tables, admin action logs, UI bookmarks, and authorization roles and rules.

That warning on @customers matters. Stripping customers while keeping orders leaves orders pointing at customers that no longer exist, which breaks admin grids and account pages in confusing ways.

Note that @development includes @trade. If you plan to anonymize customers and orders instead, do not use the @development shortcut. List the groups you want to strip explicitly.

The admin lockout gotcha

Because @admin strips authorization roles and rules, a dump stripped with it can leave you unable to create an admin user on staging. n98-magerun2’s db:import handles this, and the db:add-default-authorization-entries command repairs it after the fact. Put that command in your import script so nobody spends an afternoon debugging a blank admin role.

Custom modules need custom groups

Strip groups only know about core and a handful of well-known vendors. Your loyalty extension, your ERP connector’s log table, or a custom quote request module may all store personal data. n98-magerun2 lets you define your own table groups in app/etc/n98-magerun2.yaml, so add one for project-specific tables and include it in every dump.

Smile GdprDump for realistic anonymized data

Smile GdprDump is a PHP replacement for mysqldump that rewrites data as it dumps. It works with MySQL, MariaDB, and Percona, and the maintained 5.x line requires PHP 8.1 or later. The project is open about the trade-off: it gives you anonymization at the cost of performance compared with a plain dump.

You describe what to do in a YAML file. The useful part for Magento teams is that GdprDump ships a magento2 template you extend instead of starting from nothing:

extends: 'magento2'
version: '2.4.8'
database:
  host: '%env(DB_HOST)%'
  user: '%env(DB_USER)%'
  password: '%env(DB_PASSWORD)%'
  name: '%env(DB_NAME)%'

The template sets requires_version, so you must declare your Magento version. Run it with gdpr-dump.phar config.yaml > dump.sql and pipe the output through gzip. The --dry-run flag validates your config without dumping.

What the Magento template already handles

The bundled template truncates session, cache, log, visitor, password reset, newsletter queue, and admin logging tables, plus tables matching patterns like *_log, *_tmp, *_idx, *_replica, and *_cl. It converts personal fields in admin users, customers, customer addresses, the customer grid, newsletter subscribers, integrations, quotes and quote payments, sales orders and payments, sales grids, shipment tracking, reviews, gift registry, RMA, and B2B company and negotiable quote tables.

For example, customer emails are randomized with a uniqueness constraint so the login field stays valid, dates of birth are anonymized, and order IP addresses are replaced with fake ones.

Converters and table options

Beyond the template, you can add rules for your own tables. GdprDump’s converters include randomizing and anonymizing text, emails, numbers, and dates; generators like setNull and setValue; transformers such as hash and regex replace; and advanced options for JSON and serialized fields and for Faker-generated values. Table-level options let you truncate a table, limit rows, filter with a where clause, or skip conversion when a condition matches.

Two practical tips:

  1. Limit big tables. If staging only needs recent orders, filter sales tables by date. Smaller dumps restore faster, which matters on large stores. Our article on Magento database bloat covers why table size drives restore time.
  2. Keep internal test accounts recognizable. Use skip_conversion_if for staff accounts on your own email domain so QA can still log in as known users.

The project wiki warns that if you mark a converter as unique, every converter sharing the same cache key also needs the unique flag, or the run can loop forever. Read that page before you get creative with shared cache keys.

Other tools you will see mentioned

You will find older guides recommending Masquerade, which rewrote the target database in place. Its repository is archived and marked abandoned, with a pointer to GdprDump. There is also dbanon, a Go tool that anonymizes a mysqldump stream from stdin to stdout and needs an EAV mapping step for Magento 2. GdprDump is the most complete Magento-aware option today.

Adobe Commerce Cloud: dumps, downtime, and encryption keys

On Commerce Cloud, the documented way to create a dump is php vendor/bin/ece-tools db-dump, described on Adobe’s Commerce Cloud database dump page. Read that page carefully before running it on production, because the command switches the application to maintenance mode, stops consumers, and disables cron while it runs. Adobe recommends running it off-peak. On Pro Production it dumps from one of the three high-availability nodes, and the docs warn that writes to other nodes during the dump can be missed. The dump lands in the var directory unless you set a dump directory, and the docs say not to use public web directories such as pub/media or pub/static.

Adobe’s dump page covers mechanics, not privacy. Treat the ece-tools dump as raw production data: move it straight into a controlled environment, run your anonymization there, and delete the raw file.

One more Cloud-specific detail: encrypted config values are tied to the source environment’s encryption key. If you import into a project with a different key, those values cannot be decrypted. For staging, that is often what you want for payment credentials, but plan for it rather than discovering it as a stream of decryption errors.

The post-import reset checklist

This is the step nearly every guide skips, and it is the one that prevents real damage. After importing, update these values before anyone opens the staging site. Adobe’s sensitive and system-specific configuration reference lists many of these paths, and putting them in env.php or config.php per environment keeps them from being overwritten by the next import.

Setting Config path Staging value
Base URLs web/unsecure/base_url, web/secure/base_url Staging hostname
Cookie domain web/cookie/cookie_domain Staging domain
Disable email system/smtp/disable 1, or route to a mail catcher
PayPal sandbox paypal/wpp/sandbox_flag 1
Braintree keys payment/braintree/merchant_id and keys Sandbox credentials
Carrier sandbox carriers/fedex/sandbox_mode, carriers/ups/is_account_live Test mode
Search host catalog/search/opensearch_server_hostname Staging OpenSearch
Analytics google/analytics/account Blank or a test property
Custom admin URL admin/url/use_custom Match staging setup

Also check:

  • Cron and integrations. Disable jobs that push orders, inventory, or customers to an ERP, CRM, or marketplace, or point those integrations at sandbox endpoints.
  • Integration and OAuth tokens. Revoke or regenerate anything that could call production APIs.
  • Admin users. Create staging-only admin accounts and remove former staff.
  • Indexes and caches. Reindex and flush cache after the reset, not before.

A good release process automates all of this. If your team runs a CI/CD pipeline for Magento and Hyva, add the refresh as a scheduled job with the config reset baked in.

Pseudonymized is not the same as anonymous

A legal nuance worth knowing: under GDPR Recital 26, pseudonymized data that can be linked back to a person is still personal data, while truly anonymous data falls outside the regulation. Hashing an email with a known algorithm, or leaving order totals, dates, and postcodes intact so a person can be re-identified, may still count as personal data. Random replacement is safer than reversible transformation for anything that identifies a person. Talk to your privacy counsel about where your data lands; this article is a technical guide, not legal advice.

A repeatable refresh workflow

  1. Take a dump from production or a read replica during low traffic.
  2. Strip logs, sessions, admin, OAuth, 2FA, and search history.
  3. Anonymize customers, quotes, sales, reviews, and custom module tables with GdprDump.
  4. Transfer only the sanitized file to staging, and delete any raw copy.
  5. Import, then apply the config reset from environment files.
  6. Repair admin authorization entries and create staging admins.
  7. Reindex, flush cache, and run a smoke test.
  8. Spot-check with SQL: sample customer emails, addresses, and order names should be fake.

Getting help

Database refreshes touch infrastructure, privacy, and every integration you run, which is why they tend to drift. Bemeir’s Magento and Adobe Commerce development team sets up refresh pipelines like this as part of ongoing support, and our Hyva development services team relies on realistic staging data to test frontend changes properly. We work alongside the hosting and tooling vendors listed among our technology partners.

The same discipline applies on other platforms: teams running custom apps around Shopify, BigCommerce, or Shopware need masked test data too, even when the platform hosts the core store. Read more about Bemeir or start from the Bemeir homepage.

FAQ

Is it legal to copy a production Magento database to staging?

Staging environments are within the scope of GDPR and similar laws, so copying real personal data there needs the same protection as production. The safer approach is to strip or anonymize personal data before the copy leaves production. Confirm your specific obligations with privacy counsel.

What does n98-magerun2 db:dump –strip do?

It keeps the table structure but leaves out the rows for the tables or groups you name. Groups like @log, @sessions, @admin, and @trade bundle related Magento tables. Stripping is fast, but it empties those tables, so it is not a substitute for anonymization when testers need customer and order data.

Should I use n98-magerun2 or GdprDump?

Use both. n98-magerun2 is the quick way to drop logs, sessions, and admin data. GdprDump keeps customer and order rows while replacing personal fields with fake values. Many teams strip with one and anonymize with the other in a single scripted refresh.

What should I change after importing a production database into staging?

Update base URLs and cookie domain, disable or redirect email, switch payment and shipping integrations to sandbox mode, point search at the staging cluster, clear analytics IDs, disable production integrations and cron jobs, and create staging-only admin users. Then reindex and flush cache.

Let us help you get started on a project with Sanitized Production Database Copies for Magento Staging: Masking Customer Data With n98-magerun2 and GdprDump and leverage our partnership to your fullest advantage. Fill out the contact form below to get started.

more articles about ecommerce

Read on the latest with Shopify, Magento, eCommerce topics and more.