I Hate Magento

Sometimes I think I hate Magento for being so overly complex, slow, resource-intensive, and feature-poor yet bloat-rich that only Adobe could be interested in it. Then I think of the poor people paying me to maintain and write extensions for it.
— Comment seen on hacker news

I’ve inherited the maintenance duties for a retail shop’s website which is powered by some open-source PHP software called Magento. (Magento was purchased by Adobe a few years ago and they offer value-added commercial and hosted versions called Adobe Commerce). According to the marketing copy, “Magento is a feature-rich eCommerce platform solution that offers merchants complete flexibility and control over the functionality of their online channel. Magento’s search engine optimization, catalog management, and powerful marketing tools give merchants the ability to create sites that provide an unrivaled shopping experience for their customers.” And according to Wikipedia, “More than 100,000 online stores have been created on this platform. The platform code has been downloaded more than 2.5 million times, and $155 billion worth of goods have been sold through Magento-based systems in 2019. Two years ago, Magento accounted for about 30% of the total market share.”

I’ve now had time to work with this Magento site from several perspectives over the span of a few years (including a less-than-smooth migration from Magento 1.9 to Magento 2.3) — as a consultant managing product data via the Admin interface, as a sysadmin deploying and hosting a Magento-based site, as a developer making minor modifications and fixes as needed by my client, as a user of the customer-facing site — and it has continually impressed me: I’ve never before used software that provides such a poor experience to administrators, developers, and users alike.

Where I’d expect an eCommerce framework to provide a simple frontend interface that implements basic shopping cart functionality as a starting point to build on, Magento provides a default theme with a product description page which requests over 4MB of HTML/CSS/JS including 200+ JavaScript files (really). Modifying the theme, like all Magento customization (see below), is cumbersome to an unreasonable degree. As far as I can tell, the only sane way to have a performant and maintainable Magento website would be to write a complete frontend using a modern framework and communicate with Magento solely through its REST API. In fact the general rule of successful Magento deployment seems to be to use as little of Magento as possible.

Where I’d expect a catalog management interface with an emphasis on importing and exporting product data, Magento provides a painfully slow product browser and editor for torturing copywriters and an anemic and convoluted product export tool unsuitable for any real reporting or feed generation. My solution lately has been to write programs which get data from the REST API to update reports in Google Sheets rather than trying to use or extend the Admin panel. (Magento’s product import tool is fine.)

Where I’d expect a “feature-rich eCommerce platform solution that offers merchants complete flexibility and control over the functionality of their online channel” to have an ergonomic and well-documented extension interfaces, Magento provides an over-engineered and convoluted plugin system wired together with XML files (with little reference documentation) and PHP code generated from classes you provide which interact with the core system’s classes (which have no reference documentation).

Where I’d expect to find at the morally murky nexus of a commercial online retail platform that barely works out of the box, preoccupation with marketing and “SEO”, and the extraction of labour from programmers in developing countries (including under the guise of “open source”) an ecosystem of commercial plugins that are both expensive and risky to install, Magento delivers. So if the base install of Magento seems too stable, secure, and inexpensive to you, you could always head over to the Magento Marketplace and find any extension you need written by software developers questioning their career choices.

I don’t mean to denigrate the hard work of the open-source contributors who have helped create Magento. In fact while I don’t understand what motivates them, I admire, in some ways, the sheer tenacity and self-denial it must take to continue to spend time on such a project. From what I can tell by browsing github and the Magento StackExchange (which — and I know this is going to sound hyperbolic — is probably the lowest quality stackexchange site I’ve seen), many developers are Indian or otherwise work outside of North America, so I’m guessing the fragility of Magento has created some demand for affordable PHP developers. And I know it is some sort of broken windows fallacy, but if Magento’s convoluted architecture can provide some paying gigs or job security to those developers I guess that’s something positive, at least.

I think most of Magento’s issues — including its poor performance, poor security record, and high cost to customize and maintain — stem from two core defects: a lack of documentation and a fundamentally flawed software architecture.

If Magento had good documentation, then almost no matter how terrible its design, developers would be able to figure out to make it do what they need. Now, the organization of its documentation has improved since Adobe took over (see https://devdocs.magento.com/). But from the perspective of a PHP developer, what is documented is severely lacking. Lots of mostly useless high level descriptions, a few code examples, but no real documentation of the Magento source code and the classes/interfaces it provides.

Unlike the documentation, which Adobe could improve if they cared (but if they did, then I think they would have by now), the architecture of Magento cannot even be fixed. The entire framework is based around convoluted (which makes its lack of documentation hit harder) XML configuration files and a dynamic dependency injection system. The way it works is that plugins declare dependencies on PHP interfaces and then the Magento code generator (the bin/magento setup:di:compile command) generates the actual plugin code with the dependencies instantiated. It’s the sort of overkill system that makes large enterprise Java applications, developed by teams using a statically typed language with excellent tooling, difficult to reason about and maintain; to adopt that architecture for a PHP shopping cart application is utter madness.

I have not taken the time to investigate its performance bottlenecks, and I hope I never do, but the generated PHP code which supports such a dynamic plugin system no doubt contributes to how slow Magento is. And Magento is slow. Behind an asynchronous reverse proxy on an over-sized ec2 instance, I’m pretty sure my client’s website could be DoS’d by any mischievous kid with a cable modem if it weren’t for Cloudflare. Even with Cloudflare’s firewall a single malicious bot can bring the site to a crawl.

The ‘solution’ Magento offers to its performance problems is more and more layers of cache. First, the administrator must generate static files (CSS, etc.) with the bin/magento setup:static-content:deploy command. Then there is a cache system for various bits of data Magento calculates and which often, inexplicably, needs to be manually refreshed. But it is still slow so it is usually recommend that you also run Magento behind a caching reverse-proxy like Varnish and/or a dedicated key-value cache based on redis. It would be funny if it weren’t real software that I have to maintain.

Worse, the unnecessary complexity makes it more difficult both to understand code execution paths and to make changes to the code base: a recipe for security vulnerabilities.

There are some good things about Magento, of course. Its one saving grace, in my opinion, is its Swagger-based REST API which makes it possible to implement most required functionality outside of Magento itself. And Swagger/OpenAPI is self-documenting, so the Magento devs are not able to make it as difficult as they’ve made the PHP API. But even that has been a source of suffering. In fact my main use-case for it, reporting on current inventory quantity for all products, is not even possible by default because the /V1/products endpoint does not return stock information despite what the documentation claims. That bug has been reported several times (eg #24418), but the response from the maintainers is that the correct way to get stock information is to make a call to /V1/products and then make an additional http request for each returned product (thousands or tens of thousands in my case). (Luckily there are some workarounds. I wrote cristoper/mage_qtyext, a very simple plugin which adds a “qty” field to the product results; I also found menacoders/Stock-Info-API-searchCriteria which adds all stock information to the results.) There are also SOAP and GraphQL APIs which I’ve not investigated (except to find out that the GraphQL API by default also does not offer a way to get stock information for the entire inventory).

Personally, the prospect of developing solutions for my Magento-bound client confronts me as a depressing time sink. I’m convinced Magento will never be anything but expensive to maintain, slow, and insecure. I don’t recommend it for new projects.

I found this 2015 article from the Magento 1 days which complains about mostly the same things: Magento: why complex doesn’t mean good

See also for Spotify users: Magento 2 Rage Tracks