The uncached load time of the homepage of a local Magento 2.1.5 shop dropped from 4.5 seconds to 2.6 seconds on average after I disabled all Magento 2 core modules which could be disabled. Disclaimer: Measurements were done with disabled caches and activated developer mode on my local machine.
Even though most pages will be delivered cached, there will always be requests where only parts of the pages can be cached. The general performance increase won’t be 40% on a live server, but it will still be noticeable. And during development, when cache is being cleared frequently, it makes a huge difference.
That should be reason enough to disable as many modules as possible, right?
As an additional benefit, the admin users won’t get distracted by configuration options and features which aren’t used in your project.
What did I do?
Magento 2 brings a mechanism to disable single modules, including core modules. You can do that using the integrated command line tool. The call could look like this:
1 |
bin/magento module:disable Magento_Marketplace |
Many core modules of Magento 2 cannot be disabled – you will get an error message because other modules depend on that module if you try to disable them. So I created a small tool which helps me find out which modules can be disabled easily.
New command line tool: info:dependencies:show-removable
You can find the module containing the new command on GitHub: https://github.com/avstudnitz/AvS_DisableModules/.
You can install the module via composer (“avstudnitz/disable-modules”) or by dropping the content of the repository into app/code/AvS/DisableModules/. More detailed installation instructed are provided on the GitHub page.
After installation, you’ll have a new command available:
1 |
$ bin/magento info:dependencies:show-removable |
This will give you an output like this:
1 |
Report successfully processed. File "modules-removable.csv" generated. |
The file modules-removable.csv contains content like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
"Modules without dependencies:" " =========================== " Magento_Weee Magento_WebapiSecurity Magento_Version Magento_Usps Magento_Ups Magento_TaxImportExport Magento_SwatchesLayeredNavigation Magento_Swagger Magento_Sitemap ... |
All those files can be safely deleted. Add the following code in front of each line and paste it into the shell:
1 |
bin/magento module:disable |
After you have disabled the modules, you can do a second run – new modules might show up which can now be disabled as they were only required by modules which you have just disabled.
Which modules should be disabled?
In a default Magento 2.1.5 CE installation, the following modules can be disabled – in some cases only after other modules from the list have been disabled:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
Magento_AdvancedPricingImportExport Magento_AdminNotification Magento_Authorizenet Magento_Braintree Magento_Bundle Magento_BundleImportExport Magento_CacheInvalidate Magento_Captcha Magento_CatalogRuleConfigurable Magento_CatalogWidget Magento_CheckoutAgreements Magento_ConfigurableImportExport Magento_ConfigurableProduct Magento_Cookie Magento_CurrencySymbol Magento_CustomerImportExport Magento_Deploy Magento_Dhl Magento_DownloadableImportExport Magento_EncryptionKey Magento_Fedex Magento_GoogleAdwords Magento_GoogleAnalytics Magento_GoogleOptimizer Magento_GroupedImportExport Magento_LayeredNavigation Magento_Marketplace Magento_Multishipping Magento_NewRelicReporting Magento_OfflinePayments Magento_OfflineShipping Magento_Paypal Magento_Persistent Magento_ProductVideo Magento_SalesInventory Magento_SendFriend Magento_Sitemap Magento_Swagger Magento_Swatches Magento_SwatchesLayeredNavigation Magento_TaxImportExport Magento_Ups Magento_Usps Magento_Vault Magento_Version Magento_Webapi Magento_WebapiSecurity Magento_Weee |
First rule: Don’t disable any modules whose functionality you need! (Obviously)
Second rule: Don’t rely on Magento’s modularity. This means: there may be hidden dependencies.
Hidden Dependencies
Dependencies are declared in the composer.json file of each module. This is a manual process – in some cases, not all dependencies have been declared by the Magento core team. A module might still require another module even if it doesn’t say so.
In our recent project, we disabled Magento_ConfigurableProduct as we were using Grouped Products and Simple Products only. At first, it looked okay, but then we got an error during indexing which led us to the conclusion that the indexer has a hidden dependency to the Configurable Products module.
So: Try out if everything (still) works in your project and observe the behaviour. If you have automatic tests available: perfect, they help you find hidden dependencies much faster.
Practical Example
In our current project, we disabled about 30 modules, which works out well so far. This is the list of modules, those which are disabled are marked with a “0” (from app/etc/config.php):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
<?php return array( 'modules' => array( 'Magento_Config' => 1, 'Magento_Store' => 1, 'Magento_Directory' => 1, 'Magento_AdvancedPricingImportExport' => 0, 'Magento_Backend' => 1, 'Magento_Theme' => 1, 'Magento_Eav' => 1, 'Magento_Backup' => 1, 'Magento_Customer' => 1, 'Magento_AdminNotification' => 0, 'Magento_BundleImportExport' => 0, 'Magento_CacheInvalidate' => 1, 'Magento_Indexer' => 1, 'Magento_Cms' => 1, 'Magento_CatalogImportExport' => 1, 'Magento_Catalog' => 1, 'Magento_Rule' => 1, 'Magento_Msrp' => 1, 'Magento_Search' => 1, 'Magento_CatalogUrlRewrite' => 1, 'Magento_Widget' => 1, 'Magento_Quote' => 1, 'Magento_CheckoutAgreements' => 1, 'FireGento_MageSetup' => 1, 'Magento_CmsUrlRewrite' => 1, 'AvS_ScopeHint' => 1, 'Magento_ConfigurableImportExport' => 0, 'Magento_SalesSequence' => 1, 'Magento_Contact' => 1, 'Magento_Cookie' => 1, 'Magento_Cron' => 1, 'Magento_CurrencySymbol' => 1, 'Magento_Payment' => 1, 'Magento_CustomerImportExport' => 1, 'Magento_Deploy' => 1, 'Magento_Developer' => 1, 'Magento_Dhl' => 0, 'Magento_Authorization' => 1, 'Magento_Downloadable' => 1, 'Magento_ImportExport' => 1, 'Magento_Bundle' => 0, 'Magento_Email' => 1, 'Magento_User' => 1, 'Magento_Fedex' => 0, 'Magento_Sales' => 1, 'Magento_CatalogInventory' => 1, 'Magento_GoogleAnalytics' => 1, 'Magento_Ui' => 1, 'Magento_GroupedImportExport' => 1, 'Magento_GroupedProduct' => 1, 'Magento_DownloadableImportExport' => 1, 'Magento_Checkout' => 1, 'Magento_Security' => 1, 'Magento_LayeredNavigation' => 1, 'Magento_Marketplace' => 0, 'Magento_MediaStorage' => 1, 'Magento_ConfigurableProduct' => 1, 'Magento_Multishipping' => 0, 'Magento_NewRelicReporting' => 1, 'Magento_Newsletter' => 1, 'Magento_OfflinePayments' => 1, 'Magento_SalesRule' => 1, 'Magento_PageCache' => 1, 'Magento_Captcha' => 0, 'Magento_Vault' => 1, 'Magento_Persistent' => 0, 'Magento_ProductAlert' => 1, 'Magento_ProductVideo' => 0, 'Magento_CatalogRule' => 1, 'Magento_Reports' => 1, 'Magento_RequireJs' => 1, 'Magento_Review' => 1, 'Magento_Rss' => 1, 'Magento_CatalogRuleConfigurable' => 0, 'Magento_Authorizenet' => 0, 'Magento_SalesInventory' => 1, 'Magento_OfflineShipping' => 1, 'Magento_GoogleAdwords' => 0, 'Magento_SampleData' => 0, 'Magento_CatalogSearch' => 1, 'Magento_Integration' => 1, 'Magento_SendFriend' => 0, 'Magento_Shipping' => 1, 'Magento_Sitemap' => 1, 'Magento_Paypal' => 1, 'Magento_Swagger' => 0, 'Magento_Swatches' => 0, 'Magento_SwatchesLayeredNavigation' => 0, 'Magento_Tax' => 1, 'Magento_TaxImportExport' => 0, 'Magento_GiftMessage' => 1, 'Magento_Translation' => 1, 'Magento_GoogleOptimizer' => 0, 'Magento_Ups' => 0, 'Magento_UrlRewrite' => 1, 'Magento_EncryptionKey' => 0, 'Magento_Usps' => 0, 'Magento_Variable' => 1, 'Magento_Braintree' => 0, 'Magento_Version' => 1, 'Magento_Webapi' => 1, 'Magento_WebapiSecurity' => 0, 'Magento_Weee' => 0, 'Magento_CatalogWidget' => 0, 'Magento_Wishlist' => 1, 'Staempfli_ImageResizer' => 1, 'Yireo_AutoFlushCache' => 1, ), ); |
Project specific modules have been stripped from the list. Feel free to take this module list as a starting point for your module.
Conclusion
Magento 2 is a big step forward regarding modularity, compared to Magento 1. On the other hand, some work still has to be done for even better modularity.
You can gain a much better performance by disabling the right modules. But be careful: some modules might be needed even if you don’t recognize that on first sight. Personally, I will start off new projects by disabling unneeded modules first from now on.

Author: Andreas von Studnitz
Andreas von Studnitz is a Magento developer and one of the Managing Directors at integer_net. His main areas of interest are backend development, Magento consulting and giving developer trainings. He is a Magento 2 Certified Professional Developer Plus and holds several other Magento certifications for both Magento 1 and Magento 2. Andreas was selected as a Magento Master in 2019 and 2020.
Thank you for this post! Just what I was looking for. Randomly trying which modules I could safely disable did not work well and I didn’t think there would be a show-removable!
To physically remove a module from the git repository just mention it in the “replace” section of the composer.json file:
The run composer update/install.
Above settings are from my current project. But be aware that the M2 unit/integration test suite might break because of its tight coupling 8-
AFAIK other modules cannot be physically removed due to the hidden hard coded dependencies in other classes of other modules 🙁
Thanks! That worked so far with all the 30 disabled modules. I don’t care for the core test suite, but for our own one it was necessary because disabled modules are only halfway disabled in the integration test environment.
Can this action potentially explode the project? or is it fairly safe?
It’s not safe. You have to thorougly test if you didn’t accidentily disable a module which one of the functionalities or external modules in your shop relies on.
I’m getting the following error:
Please check the path you provided. Removable Modules report generator failed with error: Module name for composer name “shipperhq/module-common” not found.
Where is this originating from? Where is the “path” being provided?
Thx for these tips here. When you deactivate Magento_Swatches you will probably have problems in the magento2 backend because of this issue here: https://github.com/magento/magento2/issues/20843
These issue will remove the possibility to save or change attributes in the backend. So this is not a good idea until magento solved the issue. And it looks like it is not solved in 2.3.
Just to let you know. Greetings.
It appears this was fixed about a month after you posted and pushed to 2.3.3 according to the git issue you linked.
Hi Andreas
It would be interesting to see how big the gains really are once productions mode is switched on and caches are on as well. The wording “still be noticeable” is a bit vage 😉
True to that. In reality this doesn’t give noticeable performance improvements on production mode, unless perhaps for specific cases where certain performance issues with said modules might be disabled this way.
Thanks for that list – I’m testing them just one at a time, so if there is any dependencies I can quickly activate the module again.
Looking forward to seeing the effect of the load times when finish.
How can I disable Negotiable quote. I am on Commerce and want to disable it. Its causing 25% of load time on cart page
Do not remove module-persistent. It won’t allow you to add configurable products to your cart in Magento 2.3.x