Editor’s note: this post is quite technical. If you are a shop owner familiar with the steamy innards of Magento or if you are yourself a Magento developer, you might find it interesting and helpful. Otherwise, please know that this post gets “a little nerdy with it”.
Magento 2.3 released with a number of additions and improvements. One of the biggest updates was the long-awaited Magento Inventory Management (also known as MIM, and previously known as MSI, or Multi-Source Inventory). This feature was designed to manage inventory in multiple locations so that merchants have more accurate reflections of their inventory without relying on 3rd party extensions.
The MIM system provides native support for inventory sources and inventory stocks.
An inventory source represents a physical location where inventory is located. An inventory stock is a mapping of a sales channel (a Magento website) to an inventory source.
With the new Magento Inventory Management system, you might have a single product assigned to multiple sources, and after purchase of a product the quantity value would not change (unlike prior to MIM, where stock would decrease immediately after purchase). Stock values in the MSI system would only change after shipment was created, which essentially would more accurately reflect when the inventory count of a product would actually decrease in the real world.
MIM comes with the Magento 2.3.X upgrade, so we encountered it first when upgrading a Magento 2.2.7 site to 2.3.3. MIM is installed disabled by default, but we found some complications right away when we started reviewing the upgrade.
Magento Inventory Management: Issues with Transactions
The first issue we encountered during testing was that transactions were failing due to Magento not finding a “Saleable Quantity” during checkout. A Saleable Quantity is simply the number of products that the website calculates that you have available to sell.
We thought this was unusual, but we were unable to discover a method that would not throw this error without enabling MIM. Due to being on a tight timeline (not unusual for Magento eCommerce development) we decided to use the Magento MIM system using its default settings (one default Source, one default Stock). This eliminated the transaction issue, but we would soon encounter more gremlins.
Magento Inventory Management & the Big Performance Problems
One of the major issues we (and the rest of the Magento community) ran into right away was that site performance took a huge nose dive with MIM running. Magento 2.3.3 shipped with MIM database queries at checkout. That caused huge performance problems, compounded greatly by the size of the catalog on the site. The subsequent versions of MIM reduced the number of queries by a factor of 3 (approximately).
The worst performance impact during this time was at the most important stage: checkout. For some reason, MIM ran a huge number of redundant MySQL queries that were so taxing on the server that it would occasionally grind the server to a halt. Magento corrected this in the next release, but it was a painful couple of weeks. We had constant monitors on various aspects of the server’s performance in order to keep the site running smoothly despite the incredible unnecessary performance load on the database because of MIM bugs.
We were in a period of limbo between Magento 2.3.3 and 2.3.4 due to extension compatibility between the two versions of Magento, but fortunately we were able to eventually move to Magento 2.3.4 and resolve the performance issues permanently. But the MIM gremlins were not yet sated…
Magento Inventory Management: Issues with Stock
One of the biggest challenges we had to deal with was Saleable Quantities. With one of our Magento 2 sites, backorders were disabled. This client never wanted to provide the opportunity for a purchase of an out of stock item. We noticed that Saleable Quantity values increased over the default quantity of some products with MIM enabled.
Stranger yet was that we were seeing negative Saleable Quantity values, which was worrying to us and of course to our clients; was the system allowing backorders even when backorders were disabled?
We tried a number of novel solutions and even tried removing ‘reservation’ entries (reservations are increases or decreases in salable quantity based on orders, shipping, etc) from the database. But this didn’t tame the Magento Inventory Management errors since it didn’t allow us to correctly manage stock counts. So we were stuck trying to determine why stock counts were so wonky with large daily sales volume. Not a fun predicament.
Note: we are still examining what the strangeness of the stock values originated from, and my theory is that it was related to store views, of which there were 5 store views on one site we were experiencing these problems with.
Magento Inventory Management does ship with 2 command line tools that are designed to help resolve inconsistencies with the MIM stock counts. Turns out there were some oddities there as well…
Magento’s Command Line Tools for MIM: Strangeness
Magento Inventory Management comes with 2 command line tools that are intended to help with stock inconsistencies (list-inconsistencies, and create-compensations). The idea is that during normal site operation there may be stock inconsistencies that don’t resolve for whatever reason (say, something is ordered but never shipped, or some other order inconsistency) and these tools are designed to find them and create ‘compensation’ for them, to keep the stock counts accurate.
Good news: We found the list-inconsistencies tool was pretty good at finding the products with the inconsistent stock (and in Magento 2.3.4, was actually performant enough to not crash!).
Bad news: We found the create-compensation command bore no relationship to logic.
The create-compensation command is run by sending it the list-inconsistencies data, and then it loops through the data and creates the compensation. Simple, right? When we used this command, it looped endlessly, and for pretty much all inconsistent stock products just made the problem worse.
What is even more irritating is that the documentation for these tools is essentially just one page and truly lacking in useful information. We abandoned using this particular MIM tool altogether.
I mentioned earlier that we did try to simply remove the usage of the ‘reservation’ database table, but that ultimately didn’t help with stock counts so we were back to square one. Ultimately we identified an extension that helped make sense of the chaos (if you’re interested in the extension details, please drop us a line).
In practice, the extension removes MIM, but also restores the ‘legacy’ system of reducing stock on purchase rather than on shipment. With these two features deployed the stocks made much more sense.
There are still some quirks (namely with stock restoration during refund) but these are much easier to live with than the saleable quantity strangeness running wild.
Everyone was excited when we realized the potential strength of using a more modern inventory management system, until we used it. Then we were deflated and left struggling to resolve some uncharacteristically buggy behavior for a production branch release.
The ultimate takeaway here is that Magento Inventory Management needs rigorous testing before being deployed in the wild. If you have questions about this blog post or about Magento 2’s inventory system, we’d like to hear from you.