logo
  • Product
  • Solutions
  • Developers
  • Resources
  • AI
  • Pricing
  • Log in
  • Create a store
  • Product

  • AI
  • Pricing
  • Try for free
  • Log In
  • Merchandising

  • Operations

  • Building

  • Integrations

  • Products

    Powerful modeling and versatile presentation of your entire catalog.

  • Subscriptions

    Sell recurring physical and virtual products alongside one-time offerings.

  • Discounts

    Get the sale with coupons, BXGY promotions, and automatic discounts.

  • Wholesale

    Sell B2B like it's DTC, along with volume pricing, customer groups, and invoicing.

  • Content

    Manage all your products content through the admin dashboard.

  • Users

    Multi-store admin accounts and role-based permission controls.

  • Customers

    Manage customer info, generate reports, and see buyer activity.

  • Orders

    Edit orders anytime and get the right information for smooth fulfillment.

  • Fulfillment

    Ship from multiple locations, track inventory, and split shipments.

  • Reporting

    Monitor your store's performance to ensure you have visibility across the business.

  • Storefronts

    Swell storefronts are fully customizable, allowing you to create just the right experience.

  • Checkouts

    Use our hosted checkout, integrate with a partner, or build a custom flow.

  • Payments

    Connect multiple gateways simultaneously, store cards, and split payments.

  • Internationalization

    Go global with region-specific languages, pricing, and payment methods.

No-code integrations

Connect with 40+ services for marketing, payments, fulfillment, automation, and more.

See all integrations →

Use Cases

  • Direct-to-consumer

    Tell your story and give customers a unique shopping experience

  • Subscriptions

    Sell personalized subscription bundles, memberships, and one-time items together

  • B2B/B2C

    Support retail and wholesale customers from one catalog and dashboard

  • Marketplaces

    Create a B2B or B2C marketplace with multi-vendor carts and split payouts

Customer Stories

  • Spinn Coffee

    A coffee revolution sparked by a connected machine and marketplace

  • Smashing magazine

    Global tax and shipping for complex product bundles

  • Infinitas Learning

    Delievering leading educational experiences in Europe

All customer stories →

Documentation

  • Quickstart

  • Backend API reference

  • Frontend API reference

  • Guides

  • Core concepts

  • Storefronts

Community

  • GitHub

  • Discussion forum

  • Changelog

  • API status

Resources

  • Help Center

    The latest industry news, updates and info.

  • Customer stories

    Learn how our customers are making big changes.

  • Become a partner

    For agencies creating innovative commerce experiences.

Latest blog posts

  • deep-dive-app-functions
    Nov 06, 2025

    Build smarter workflows with App Functions

  • storefronts-v2-and-the-future-of-swell-apps
    Oct 22, 2025

    Storefronts V2 and the future of Swell Apps

  • Changelog

  • API Status

  • Contact us

Blog

Migrating from Magento Open Source to Swell: A Complete 2026 Guide

A technical migration guide for self-hosted Magento Open Source: flattening the EAV schema, mapping every entity to Swell models, redirects, cutover and effort bands.

Swell Team | October 02, 2026

Magento Open Source 2.4.9 shipped on May 12, 2026, and that release line is patched until May 31, 2029. On the free, self-hosted edition, those dates read differently than they do on the licensed one. Nobody sends an invoice for Magento Open Source, and nobody applies the patch either. The upgrade is a line on your own roadmap, staffed by your own engineers, on servers you rent yourself.

This guide is written for brands on that edition, and it is deliberately not the Adobe Commerce story. Leaving a licensed Adobe Commerce contract is a business case about what the paid product costs, and that argument already has its own guide here. Magento Open Source carries no licence fee at all, so a case built on licensing spend is the wrong case for this reader. The real cost sits in the hosting bill, the DevOps hours, and a major-version upgrade no vendor performs on your behalf. Complaints both editions share, such as monolithic PHP, cache-tier complexity and extension quality variance, are catalogued in Adobe Commerce limitations and are not repeated below.

What follows is a procedure, and most of it is one problem. A Magento product is not a row in a table. It is one row in `catalog_product_entity` plus scattered typed value rows, scoped per store view, governed by an attribute set. Turning that into flat records is the migration. Redirects, payment cutover and testing all matter, but they are short sections. The entity-attribute-value decomposition is where the weeks go.

Key Takeaways

  • Magento Open Source and Adobe Commerce ship from the same codebase on the same release clock, but Adobe's three-year support window is written for Adobe Commerce customers: the dates apply to your codebase, the support entitlements do not. 2.4.6 left the window on August 11, 2026 and 2.4.9 runs to May 31, 2029.
  • Reconstructing one product means joining `catalog_product_entity` to six typed value tables, resolving its attribute set to know which attributes even apply, and collapsing store-scoped rows where store ID 0 is the default scope.
  • Magento's admin export tool covers six entity types, and orders are not one of them, which is why direct MySQL extraction is usually the honest answer at scale.
  • Password hashes in `customer_entity` use Argon2ID13 by default and cannot be verified anywhere else, so every cutover ships a password reset at launch.
  • Effort tracks attribute sets and store views far more closely than SKU count: 40,000 SKUs on one attribute set and one store view is a smaller job than 3,000 SKUs across nine attribute sets and five store views.
  • The `url_rewrite` table is the redirect map, historical rewrites included, and the single largest URL transformation is stripping the configurable `.html` suffix Magento appends to product and category URLs.

The Edition You Are Actually Running

Both editions run the same core code, admin, module system and release calendar. The difference is what wraps around it: Adobe Commerce adds licensed B2B and merchandising features plus a support contract, and Magento Open Source adds nothing and charges nothing. Three consequences of the free edition shape the migration.

The stack you agreed to operate

Adobe publishes the third-party versions it has tested against each release. For 2.4.8-p5 that list is PHP 8.4 or 8.3, MySQL 8.4 or MariaDB 11.4 or 11.8, OpenSearch 3 or Elasticsearch 8, RabbitMQ 4.3, Valkey 8.1, Composer 2.10, nginx 1.30 and Varnish 8. That is eight independent services, each with its own upgrade path, security advisories and configuration surface, plus the compatibility matrix between them. On a managed cloud product somebody else owns most of that list. Here you own all of it.

The support clock runs whether or not you paid

That lifecycle policy gives each 2.4.x line three years of standard support from general availability. In practice, 2.4.4 left standard support in April 2025, 2.4.5 in August 2025, and 2.4.6 on August 11, 2026. Adobe's one extra year on 2.4.6 and 2.4.7 is offered to Adobe Commerce customers, so on the free edition the standard-support date is the whole of it. Version 2.4.7 runs to May 31, 2027, 2.4.8 to May 31, 2028, and 2.4.9 to May 31, 2029. Nothing about running the free edition slows that clock.

Falling off it has a compliance edge. Adobe's end-of-support FAQ, written for Adobe Commerce but describing the same codebase, states that a version past end of support is no longer PCI compliant, and that responsibility for patches and re-certification moves to the merchant. PCI DSS v4.0.1 requirement 6.3.3 expects critical and high-security patches installed within one month of release. A free licence does not come with a slower obligation, only with fewer people to call.

Magento 1 is the precedent, and it belongs to this reader

In September 2018, Magento announced that Magento Open Source 1 would receive security patches through June 2020. The same announcement put maintenance of extensions, customisations and standards compliance including PCI squarely on the merchant. Moving to Magento 2 was never an upgrade. It was a migration, run through a separate data migration tool covering Magento Open Source 1.6.x through 1.9.x, which left themes, extensions and admin accounts behind. Open Source merchants absorbed that hardest, because no account team scheduled the project and no licence renewal forced the conversation. Anyone planning around 2.4.x today is planning the same shape of event with a later date on it.

The Export Path, and Exactly Where It Stops

Three routes lead out of a Magento database, and each stops somewhere useful to know about in advance.

The admin export tool

System > Data Transfer > Export writes CSV into `var/export`, and its entity type list covers Advanced Pricing, Products, Customer Finances, Customers Main File, Customer Addresses and Stock Sources. Orders are not on that list, so order history never leaves this way. The product export is also lossy by design: complex structures are packed into single delimited columns, with variant data crammed into a `configurable_variations` field and custom attributes into `additional_attributes`. That format round-trips into another Magento instance. It does not describe the catalogue well enough to rebuild it somewhere else without re-parsing.

The REST API

The Commerce REST API returns clean JSON per entity and supports `searchCriteria` paging through `pageSize` and `currentPage`, and returns every match when `pageSize` is omitted. It is the right tool for a few thousand products, for a delta sync during a freeze window, or wherever you want Magento's own business logic applied to the output. It is a poor tool for a large catalogue: you pay PHP object hydration for every record, page by page, against a production server, and store-scoped values arrive already resolved rather than exposed as a hierarchy you can inspect.

Direct MySQL extraction

At scale, reading the database directly is the honest answer. It is faster by orders of magnitude, it runs against a restored dump instead of the live store, and it is the only route that shows the store-scope hierarchy rather than silently flattening it. The cost is that you take on the EAV decomposition yourself, in SQL. Teams who have run the equivalent on other self-hosted PHP platforms, such as WooCommerce or Shopware, should expect this step to be substantially larger here.

Decomposing EAV: Where the Weeks Actually Go

Adobe's own documentation is blunt about the shape of the problem. Catalogue data is stored across multiple tables under the entity-attribute-value model, and because product attributes are stored in many tables, SQL queries are sometimes long and complex. That is the entire reason the flat catalog indexer exists. Naming EAV is easy. Reconstructing a product out of it is the job.

One product, ten tables

`catalog_product_entity` holds only what is true of every product regardless of attribute set: `entity_id`, `attribute_set_id`, `type_id`, `sku`, `has_options`, `required_options`, `created_at` and `updated_at`. Everything a merchant would call product data lives elsewhere, in typed value tables defined in the catalog module schema:

  • `catalog_product_entity_varchar` for names, URL keys, meta titles and most short text
  • `catalog_product_entity_int` for status, visibility, tax class and dropdown option IDs
  • `catalog_product_entity_decimal` for price, special price, cost and weight
  • `catalog_product_entity_text` for descriptions and other long text
  • `catalog_product_entity_datetime` for special price windows and custom date attributes
  • `catalog_product_entity_gallery` and `catalog_product_entity_media_gallery` for image records

The five scalar value tables carry the same five columns: `value_id`, `attribute_id`, `store_id`, `entity_id` and `value`. The gallery tables do not. `catalog_product_entity_gallery` adds a `position` column, and `catalog_product_entity_media_gallery` carries no `entity_id` and no `store_id` at all: it holds `value_id`, `attribute_id`, `value`, `media_type` and `disabled`, joins to products through `catalog_product_entity_media_gallery_value_to_entity`, and keeps per-store label, position and disabled flags in `catalog_product_entity_media_gallery_value`. A product with 60 populated attributes is therefore 60 or more rows across the five scalar tables, and nothing in those rows says what any attribute means. `attribute_id` is a foreign key, and resolving it is step two.

Resolving the attribute set

The EAV module schema holds the dictionary. `eav_attribute` maps each `attribute_id` to an `attribute_code`, an `entity_type_id`, a `backend_type` that tells you which value table to read, and a `frontend_input` that tells you what the merchant saw in the admin. `eav_attribute_set` and `eav_attribute_group` define which attributes apply to which products, joined through `eav_entity_attribute`. For select and multiselect attributes the stored value is an option ID, and the human-readable label sits in `eav_attribute_option_value`, keyed from `eav_attribute_option`.

This is why attribute set count drives effort. Each set is a different column shape. A store on a single Default set exports as one wide table. A store with nine sets, where Apparel carries 40 attributes and Electronics carries 70 with a dozen overlapping codes meaning different things, is nine mapping exercises plus a reconciliation pass. Two attributes both named `material` in different sets, with different option lists, have to become one decision.

Collapsing store scope

Every value row carries a `store_id`, and store ID 0 is the default scope used when no store-specific row exists. A store view row overrides the default for that view only. So for any attribute on any product there may be one row, two rows or six, and the value a customer saw depended on which store view they were browsing.

Flattening forces a decision per attribute, per product:

  • If only a `store_id = 0` row exists, take it. This is the majority case.
  • If a store view row exists and differs, decide whether it is a translation, a market-specific value, or a legacy override nobody meant to leave.
  • If the overrides are translations, they belong in localised content, not squashed into one flattened value.
  • If the overrides are pricing or availability by market, they belong in currency and catalogue configuration, not the product record.

One store view makes the scope pass a `WHERE store_id = 0` filter. Five store views across three languages means auditing every attribute for whether its per-view rows carry meaning, and keeping a decision log you can defend six months later.

The shape of the flattening step

The practical pattern is not one enormous join, but a staged build against a restored dump:

  • Build an attribute dictionary: one row per `attribute_id` with `attribute_code`, `backend_type`, `frontend_input`, and for select types a resolved option ID to label map.
  • Build an attribute-set membership map, so you know which codes are legitimate for each product.
  • For each backend type, extract that type's value table once with an inner join to the dictionary, producing long-format rows of `entity_id`, `attribute_code`, `store_id`, `value`.
  • Union the typed extracts into one long table, then resolve scope by ranking rows per `entity_id` and `attribute_code` with the chosen store view ahead of store 0.
  • Pivot long to wide: one row per product, one column per attribute code, using the dictionary to cast values back to sensible types.
  • Reconcile. Any product whose wide row carries an attribute outside its set is a source data bug, and there will be some.

That output, a wide table keyed on `sku`, is what everything downstream depends on. Build it as a script, not a one-off query session, because you will run it at least three times: to scope the work, for the staging load, and against a fresh dump on cutover day.

The pieces that live outside the typed tables

Several things a merchant thinks of as product data are not EAV at all and need their own extraction:

  • Configurable products. The parent carries no variant data of its own. `catalog_product_super_attribute` records which attributes generate the variation axes, and `catalog_product_super_link` maps each child simple product to its parent. Those children are full products with their own EAV rows.
  • Category assignment. `catalog_category_product` holds product-to-category rows with position. Categories are EAV entities too, with their own `catalog_category_entity_*` value tables and store scoping.
  • Tier and group pricing. `catalog_product_entity_tier_price` holds quantity and customer-group price rules, separate from the decimal attribute table.
  • Inventory. `cataloginventory_stock_item` holds `qty`, `is_in_stock`, `backorders` and `manage_stock`, alongside `use_config_*` flags meaning inherit the global setting, which must be resolved before any of those numbers mean anything.
  • Media. `catalog_product_entity_media_gallery` stores relative file paths and roles; the binaries sit on disk under the media directory, and the two can disagree. Audit both.
  • URLs. `url_rewrite` holds `request_path`, `target_path`, `redirect_type`, `entity_type` and `store_id`, including every historical rewrite Magento generated when a URL key changed. This table is your redirect map, and it is the most valuable thing in the database for SEO continuity.

Mapping the Flattened Result to Swell

With a wide product table in hand the target shape is straightforward, because Swell's product model is a document rather than a decomposition. What took six tables in Magento is a handful of fields.

Products

  • `sku` to `sku`, keeping `entity_id` as a custom attribute so you can cross-reference during reconciliation
  • `name` to `name`, and `url_key` to `slug`
  • `description` to `description`, and `short_description` to `summary`
  • `price` to `price`, `special_price` to `sale_price` with `sale` set true, and `cost` to `cost`
  • `status` (1 or 2) to `active` as a boolean; `visibility` has no single equivalent and resolves into `active` plus category assignment
  • `weight` to `shipment_weight`
  • `meta_title`, `meta_description` and `meta_keyword` to `meta_title`, `meta_description` and `meta_keywords`
  • `catalog_product_entity_tier_price` rows to the `prices` array: `qty` becomes `quantity_min`, `customer_group_id` becomes `account_group`, and `percentage_value` has to be resolved to an absolute price. Magento has no upper quantity bound, so `quantity_max` is yours to set, and `website_id` scoping has to be collapsed the same way store scope is
  • `cataloginventory_stock_item` to `stock_level`, `stock_tracking` and `stock_backorder`, after resolving the `use_config_*` flags
  • media gallery paths to `images`, uploaded as files rather than referenced by path

Custom attributes

This is the mapping that repays care. Magento's custom EAV attributes become Swell attributes, defined once and assigned to products, with a `type` covering short_text, long_text, select, boolean, number, date, tags, image and more, a `values` list for select options, and `filterable`, `searchable`, `visible` and `required` flags. A `variant` flag marks an attribute as variant-defining.

The translation is clean but not mechanical. Magento's `frontend_input` maps roughly onto Swell's `type`: dropdown to select, multiselect to select with multiple values, textarea to long_text, date to date, price to currency. Attribute sets have no target equivalent, and that is the point. An attribute exists once globally and is assigned where relevant, so the nine-sets problem resolves into one deduplicated attribute list.

Variants, categories, customers and orders

  • Configurable parents plus `catalog_product_super_attribute` become one Swell product with `options` where `variant` is true, and a generated `variants` array. Child simple products stop existing separately, which usually shrinks the reported catalogue count considerably.
  • Categories map to the Swell category model: `name`, `slug`, `parent_id` for the tree, `description`, `images`, `sort` and `active`. Magento's anchor and display-mode settings have no direct equivalent and become storefront logic.
  • Customers map to accounts: `email`, `firstname` to `first_name`, `lastname` to `last_name`, `telephone` to `phone`, and customer group to `group`. Rows from `customer_address_entity` become account addresses. Custom customer attributes are EAV as well, in `customer_entity_varchar` and its siblings, and need the same flattening pass.
  • Orders map to the Swell order model: `sales_order` to the order record with `number`, `account_id`, `billing`, `shipping` and totals, `sales_order_item` to `items`, and `sales_order_payment` to `payments`. Load products, then customers, then orders, since each references the one before it.

What Does Not Survive

Some of this is common to any replatform and is covered in the WooCommerce migration guide. The Magento-specific losses are worth naming precisely:

  • Password hashes. `customer_entity.password_hash` stores Argon2ID13 output with its salt and version. No other platform can verify it, so a password reset at launch is the only option.
  • Admin users and permissions. `authorization_role` and `authorization_rule` encode an ACL tree describing Magento's own admin resources, so there is nothing to map them onto. Rebuild admin access by hand and treat it as a chance to prune.
  • Extension tables. Every module that added tables takes that data with it when the module stops existing. Inventory those tables first and decide, per extension, whether the data becomes a custom attribute, moves to a third-party service, or gets archived.
  • CMS content. `cms_block` and `cms_page` rows, widget instances and layout XML have no equivalent, because they describe Magento's own rendering pipeline. Content moves as content; the layout instructions are discarded.
  • Layered navigation addressing. Filtering still works on the new storefront, but the URLs that expressed it do not survive in Magento's format, which feeds into the redirect plan.

Redirects for Magento URL Shapes

The shared discipline, server-side 301s for every URL individually, kept live well past launch, with no blanket redirect to the homepage, is covered in the WooCommerce migration guide and applies here unchanged. What is Magento-specific is the set of URL shapes you have to enumerate:

  • The suffix. Magento appends a configurable URL suffix, conventionally `html`, to product and category URLs. Nearly every legacy URL ends in `.html` and no new one will. That single transformation covers most of the catalogue.
  • `url_rewrite` as the source of truth. Export the whole table, not only current URLs. Rows where `redirect_type` is 301 or 302 are old paths Magento is already redirecting, and they still carry links and rankings. Point them at the new destination directly rather than through the old hop.
  • Category-path product URLs. If category paths in product URLs were ever enabled, the same product has several legacy paths, one per category. All of them need a target, and all should land on one canonical new URL.
  • Store code prefixes. If Add Store Code to URLs was set to Yes, every path carries a store code segment and each store view needs its own redirect set.
  • Layered navigation parameters. Legacy filtered URLs carrying attribute query parameters should resolve to the unfiltered category page rather than 404, unless a filtered page earned rankings worth reproducing deliberately.

Payments, Subscriptions and Testing

Payment cutover follows the same rules as any replatform. Tokens live at the gateway, so continuity depends on keeping the same gateway account. The WooCommerce migration guide covers those mechanics in full.

Subscriptions are the Magento-specific wrinkle. Magento Open Source core has no recurring billing, so a store selling subscriptions runs that logic in an extension, with its own tables, schedule records and relationship to the gateway. There is nothing standard to port, because there is no standard shape to port from. Swell handles recurring billing in the core API rather than through an installed app, with billing schedules, trials, statuses and recurring line items on the subscription record. Rebuild the plans from the extension's tables, reconcile every active subscriber's next billing date by hand before cutover, and run a full billing cycle in test first.

A testing checklist aimed at the failures specific to this migration:

  • Attribute parity. Pick 30 products spanning every attribute set and diff every value against the source, not only name and price.
  • Scope parity. For each store view, confirm overridden values still differ where they should and match where they should not.
  • Variant integrity. Confirm every child of every configurable resolves to a purchasable variant, and no orphaned child products were imported as standalone products.
  • Option label resolution. Confirm no product shows a numeric option ID where a label belongs, the classic symptom of a missed `eav_attribute_option_value` join.
  • Redirect coverage. Crawl the old sitemap and confirm every URL returns a single 301 to a live page, no chains and no soft 404s.
  • Price rules. Verify tier and group prices apply at the right quantities and account groups in a real cart.
  • Inventory. Confirm `use_config_*` inheritance was resolved, not copied.

Effort Bands by Attribute Set and Store View

SKU count is the wrong estimator here. Once the flattening script exists, 5,000 products and 50,000 differ mainly in runtime. What differs in human time is how many distinct column shapes you design and how many scope decisions you make. The bands below assume one experienced developer plus a merchandiser validating output, and cover extraction through a validated staging load, not the storefront build. Broader replatforming timelines and failure rates are collected in migration statistics.

  • Band A, one attribute set and one store view, any catalogue size. The flattening script takes 2 to 4 days, and extraction through validated staging load runs 1 to 2 weeks.
  • Band B, two to four attribute sets, one or two store views. Extraction and mapping alone take 1 to 2 weeks, and 3 to 5 weeks gets you to a validated staging load. Overlapping attribute codes across sets are the main time sink.
  • Band C, five or more attribute sets, or three or more store views, or localised attribute values. Extraction and reconciliation take 3 to 5 weeks, and 8 to 12 weeks gets you to a validated staging load. Add roughly a week per additional language, because each one turns scope resolution into a translation review.
  • Add to any band: heavy extension data, bundle or grouped products in volume, or a catalogue already carrying the scars of a Magento 1 to Magento 2 migration. That last one is common, and shows up as orphaned attributes and option values nothing references.

Reality Check: Costs, Constraints and What Breaks

The old store stays live throughout. Product images are referenced by URL during import, so Magento keeps serving media until the new store's files are uploaded and verified. Budget for running both, including the hosting bill you are trying to escape, for the project plus a validation period after launch.

The target is not flat-priced either. Swell's plans are revenue-tier based: each tier carries a revenue ceiling and a percentage overage above it, plus usage charges for API requests and storage. Model your actual trailing revenue against the tier you would land on before comparing the number to a hosting invoice.

The storefront is a rebuild, not a conversion. No path turns a Luma or Hyva theme into a Swell storefront: template logic, layout XML and PHTML all assume Magento's rendering pipeline. Whether you launch hosted or go straight to headless, the frontend is new work and should be scoped as such.

Extension parity is where projects stall. Inventory every installed module and settle its replacement before the catalogue work, because the answer occasionally changes the plan.

Choosing Your Path

Not every Magento Open Source store should leave, and the decision usually resolves itself once the attribute audit is done.

  • Stay on Magento Open Source if you already have in-house PHP and DevOps capacity, a heavily customised checkout encoding real competitive logic, and a catalogue whose complexity genuinely needs attribute sets. The software is free, capable and mature, and its ecosystem is deep.
  • Move to Swell if the platform work your team does is integration and storefront work rather than core PHP, if you want the database, the patch cadence and the stack compatibility matrix to stop being your problem, or if subscriptions and account-group pricing sit at the centre of the business. What makes the EAV work land cleanly here is that attributes are a global model rather than a set-scoped schema, and the target shapes are documents a flattened export maps onto directly.
  • Look elsewhere if what you want is an off-the-shelf storefront with minimal engineering involvement. Swell is API-first and expects a developer in the loop; a fully hosted, theme-driven product is a different category of tool, and needing one is a legitimate answer.
  • Delay if you are heading into peak season, or if nobody on the team can read the source database. The best predictor of a bad EAV migration is starting the import before anyone has audited the attribute sets.

Frequently Asked Questions

Is Magento Open Source different from Adobe Commerce for migration purposes?

The code you are extracting from is identical, so the EAV decomposition is the same work on both. What differs is everything around it: no licence fee, no Adobe support contract, no account team, and self-hosting, so the infrastructure and patching burden is entirely yours. The business case for moving is about operations and ownership rather than licensing spend.

Can I migrate using CSV exports alone?

For a small, single-store-view catalogue on one attribute set, sometimes yes. For anything larger, no. The admin export tool does not export orders at all, and it packs variant and custom attribute data into delimited single columns, so you end up parsing Magento's export format instead of reading the database. Once you are parsing anyway, direct extraction is less work and more accurate.

What happens to my Magento product URLs?

Export the `url_rewrite` table in full and treat it as the redirect map, historical rewrites included. The transformations covering most of a catalogue are stripping the `.html` suffix, mapping `url_key` onto the new slug, and collapsing category-path duplicates onto one canonical product URL. Filtered layered-navigation URLs generally redirect to the unfiltered category page.

How long does a Magento Open Source migration take?

Count attribute sets and store views before anything else, because SKU count barely moves the number. Extraction through a validated staging load runs roughly 1 to 2 weeks for a single set and store view, 3 to 5 weeks for a few sets, and 8 to 12 weeks for a multi-set, multi-store-view catalogue with localised values. Storefront build runs separately, usually in parallel.

Do customers have to reset their passwords?

Yes. Magento stores Argon2ID13 hashes that no other platform can verify, and no export changes that. Plan the reset email as a launch communication rather than an error state: explain why, send it at a time you can staff support, and make the reset link the primary call to action.

What about my Magento extensions?

Assume none transfer. Extension code is Magento module code, and extension data lives in extension-owned tables that disappear with the module. Audit them early into four buckets: replaced by core platform features, replaced by a third-party service, rebuilt as a custom integration, or retired.

Is a Magento migration harder than migrating from another self-hosted platform?

Generally yes, and EAV is the reason. A WooCommerce or Shopware product is close to a row you can read, so extraction is mostly a mapping exercise. A Magento product has to be reconstructed from typed value tables, an attribute dictionary and a scope hierarchy before mapping can even start. Budget for that reconstruction as its own phase with its own deliverable.

Next-level commerce for everyone.

X.comGitHubLinkedIn

Subscribe to our newsletter for product updates and stories

Resources

Help CenterDeveloper CenterCommunityAgenciesChangelogLearn

Use cases

SubscriptionsB2B WholesaleMarketplaceOmnichannelDirect-to-consumerEnterprise

Explore

FeaturesPricingIntegrationsCustomer stories

Developers

OverviewDocumentationGuidesStorefrontsHeadlessSwell Apps

Company

BlogAbout usPartnersContact us

© 2026 Swell. All rights reserved.

Privacy PolicyTerms of Service