← Blog

Magento

Magento 2.4.7 pre-migration audit: a 90-minute checklist

It is Friday afternoon at a Dutch wholesaler doing €11M a year on Magento 2.4.7. Their CTO wants a fixed-price migration quote by Monday. We open the audit checklist.

Jacob Molkenboer· Founder · A Brand New Company· 15 Jun 2026· 8 min
Open leather ledger, brass key on cream card with green tag, rubber stamp, ink pad, red shipping tag on ivory paper.

It is Friday afternoon at a Dutch wholesaler doing €11M a year on Magento 2.4.7. Their CTO wants a fixed-price migration quote by Monday morning. The board has narrowed the target to Shopware 6 or Shopify Plus, and the deciding factor is whether we can run the new stack in parallel without breaking the B2B quote workflow that 60% of their revenue depends on.

We do not start by writing the quote. We open the audit checklist. It takes about 90 minutes of read-only SSH and another two hours of analysis. By Monday we know whether the migration is a four-month project or a fourteen-month one, and the client knows why.

This is that checklist.

Why a pre-quote audit beats a discovery sprint

The standard alternative is a paid two-week discovery. We have done plenty of those. They are honest work but they front-load risk onto the client at the exact moment they are least able to absorb it: before they have decided whether the project is worth doing at all. A short structured audit answers the three questions that actually move the number on the quote.

  • What is the blast radius of every third-party module we have to keep, port, or rebuild?
  • How much EAV bloat is hiding in the catalog, and does it cost a week of data cleaning or three months?
  • Which Hyvä frontend overrides are load-bearing for a B2B flow the target platform handles differently?

The audit does not produce a design. It produces a defensible number. That is the whole point.

Step 1: Third-party module bus-factor

The first SSH session goes straight to app/code/ and the composer.lock. We are not reading code yet. We are scoring each module on three axes: how dead is the vendor, how deep is the integration, and how replaceable is the function.

This is the read-only command we run first, after taking a fresh DB dump for safety.

cd /var/www/html
bin/magento module:status --enabled \
  | grep -v '^Magento_' \
  | grep -v '^None$' \
  | sort -u > /tmp/third-party-modules.txt

# Composer-tracked modules and their last-release date
jq -r '.packages[] | select(.type=="magento2-module") | "\(.name) \(.time)"' \
  composer.lock | sort -k2 > /tmp/module-ages.txt

Now we score. A module is high bus-factor if its vendor has shipped a release in the last six months, ships its own Hyvä compatibility module, and has a public issue tracker with closed tickets in the last month. A module is low bus-factor if its vendor's last release was 2023, the GitHub repo is archived, or the module shows up in the wild as a fork that nobody owns. Mirasvit, Amasty, Aheadworks tend to score high. The €49 marketplace finds usually score low.

We pay particular attention to modules that touch the quote, checkout, and pricing flow. A dead "request a quote" module on a B2B site is not a portability problem; it is the migration's critical path.

Warning

If the client runs any module from a vendor that merged with another vendor in the last 18 months (the Magento extension market has consolidated heavily during the Adobe-to-Mage-OS uncertainty), assume the support contract is hollow. Verify it by opening a real support ticket during the audit window, not by reading the vendor's website.

Step 2: EAV attribute bloat, measured not eyeballed

Magento's EAV catalog is famous for one thing: agencies that left it open for ten years. Every per-product field added for a campaign in 2018 stayed. The result is a catalog_product_entity_* tableset the migration target will refuse to model cleanly.

We measure it before we quote. Two queries, run against a read replica or a dump restored locally.

-- How many product attributes do they actually use?
SELECT
  ea.attribute_code,
  ea.backend_type,
  COUNT(DISTINCT cpe.entity_id) AS products_with_value
FROM eav_attribute ea
JOIN catalog_eav_attribute cea ON cea.attribute_id = ea.attribute_id
LEFT JOIN catalog_product_entity_varchar cpe
  ON cpe.attribute_id = ea.attribute_id
WHERE ea.entity_type_id = 4
GROUP BY ea.attribute_code, ea.backend_type
ORDER BY products_with_value DESC;

-- How many user-defined attributes carry data on under 1% of the catalog?
SELECT COUNT(*) AS dead_attributes
FROM eav_attribute ea
JOIN catalog_eav_attribute cea ON cea.attribute_id = ea.attribute_id
WHERE ea.entity_type_id = 4
  AND cea.is_user_defined = 1;

On a typical sub-€20M Dutch estate we see 180 to 400 user-defined product attributes, of which 30 to 60 carry real data on more than 5% of the catalog. Everything else is migration cost. Shopware 6 maps the live ones to its custom_field system cleanly. Shopify Plus maps them to metafields and a tax on every storefront query that touches them. The number of live attributes is therefore one of the largest single drivers of the platform recommendation we end up writing.

Step 3: Hyvä overrides that will bite during cutover

Hyvä Themes is the right answer for almost every Magento estate that wants to stay on Magento for another two years. It is a problem to audit, though, because every override the client paid for is now a piece of business logic the migration target has to inherit.

The pattern we look for is overrides under app/design/frontend/<Vendor>/<theme>/Magento_Checkout/, Magento_Quote/, and Magento_NegotiableQuote/. On a B2B site the dangerous ones are not the visual changes. They are the ones that intercept the cart payload before it hits the quote endpoint.

# Find every override of a checkout or quote component
find app/design/frontend -type f \
  \( -path '*Magento_Checkout*' -o -path '*Magento_Quote*' \
     -o -path '*Magento_NegotiableQuote*' \) \
  \( -name '*.phtml' -o -name '*.js' -o -name '*.xml' \) \
  | xargs -I{} sh -c 'echo "=== {} ==="; head -5 "{}"'

We list every override and ask the client one question per file: "If we throw this file away tomorrow, who calls support?" If the answer is "the procurement manager at our biggest customer", that file becomes an acceptance-test fixture for the new platform, not a port-it-or-not decision. We have seen six-line phtml files that silently encode "if customer group is wholesale and order total exceeds €5k, route through the negotiable quote endpoint instead of the standard checkout." That is the kind of thing the migration target has to learn before parallel run, not during.

Takeaway

The Hyvä overrides that will break a B2B cutover are the ones nobody can describe in a single sentence. Find those first.

Step 4: The parallel-run cutover plan, in three columns

Once the first three steps are done we draw a simple table. Three columns: flow, source of truth during parallel run, reconciliation cadence. For most sub-€20M B2B sites the answer is the same shape.

  • Catalog: source of truth moves to the new platform on day one. Magento becomes a read-only mirror, fed by a nightly export.
  • Orders: source of truth stays on Magento for the first four weeks. Orders placed on the new platform replicate back into Magento via a webhook into a custom REST endpoint. Finance keeps reconciling against one ledger.
  • Quotes: this is where it goes wrong. The B2B quote flow carries too much customer-specific logic to dual-write reliably. The honest answer is to freeze new quote creation on Magento at cutover hour zero and route every new quote through the new platform from minute one, with a 72-hour rollback window.

The audit checklist does not produce that plan in its final form. It produces enough evidence that we know, at quote time, whether the freeze-and-route is a one-weekend exercise or a six-week change-management project.

Step 5: The version-and-security sanity pass

Last column on the checklist: where is the estate actually sitting on the Magento 2.4.7 patch line? Adobe shipped 2.4.7 in March 2024 and the patch cadence has been steady since. We check the running version, the PHP version, the OpenSearch version, and whether the estate has ever applied the security-only patches.

bin/magento --version
php -v
curl -s "$ES_HOST:9200" | jq .version.number
composer show magento/product-community-edition | grep versions

If we find a 2.4.7-p0 on PHP 8.2 with no security patches applied since release, the migration quote includes a "stabilise first" line item. You do not migrate off a burning platform; you put out the fire and then migrate calmly. We walked away from one project this year because the client wanted to skip that line item and we did not want to own the outcome.

What the audit costs us, and what it saves the client

The 90-minute audit plus the two-hour write-up costs us half a day of senior engineering time per prospect. Roughly one in three audits leads to a project. The other two thirds either confirm the client should stay on Magento for another release cycle, or they reveal a problem that means the migration is not commercially viable yet. Both of those outcomes are fine. The audit is not a sales tool; it is a filter that keeps us from quoting work we cannot deliver to a price we cannot honour.

When we built the Shopware 6 migration for a Rotterdam-based building-supplies wholesaler, the audit caught a Mirasvit module that was load-bearing for their VAT-shifted EU exports and had no Shopware equivalent. We spent the first two sprints porting that logic into a Shopware plugin before touching the storefront. That is the kind of decision the audit exists to surface. If you are sitting on a Magento estate of your own and want a second opinion before you write the RFP, this is one slice of our legacy migration work.

The one-page version

If you only do one thing today, open an SSH session against your staging environment and run the two SQL queries in Step 2. The number of product attributes carrying data on more than 5% of your catalog is, by itself, the most useful migration-readiness number you can produce in ten minutes.

Key takeaway

The hardest part of a Magento migration is not the catalog; it is the six-line Hyvä override that silently routes wholesale orders through a custom quote endpoint.

FAQ

How long does the pre-migration audit actually take?

About 90 minutes of read-only SSH access plus two hours of write-up. The output is a defensible fixed-price quote, not a discovery deliverable.

Why score third-party modules by vendor bus-factor instead of by feature?

A feature you can rebuild on the new platform is a sprint. A feature whose original vendor disappeared with the only knowledge of how it works is a quarter.

Is Shopware 6 always a better target than Shopify Plus for B2B?

No. Shopware wins when EAV attributes are heavy and quote workflows are complex. Shopify Plus wins when the catalog is shallow and the team prefers managed infrastructure.

Can we parallel-run Magento and the new platform indefinitely?

You can, but you pay for two platforms and your finance team will hate you. Plan a four to eight week parallel window and a hard cutover date.

magentomigrationlegacy sitese-commercearchitecturephp

Building something?

Start a project