Control plugin execution order in Magento

Let us look at how Magento decides the order of plugin execution, which becomes really important when multiple plugins interact with the same class or method.

M Bytes Newsletter
Get the developer newsletter

    Fresh bytes every Thursday. No spam, ever. Unsubscribe anytime.

    Join 9,000+ developers and get three free video lessons every week.

    When multiple plugins interact with the same class or method in Magento, the order they execute in becomes really important. Let's look at how Magento decides this order.

    Magento uses two main factors to determine plugin execution order:

    1. sortOrder: This is an explicit number you can set to control when your plugin runs
    2. Module names: If plugins have the same sortOrder (or none at all), Magento falls back to alphabetical module names

    You can use any positive or negative integer for the sortOrder in your plugin definition:

    <plugin name="early_plugin" ... sortOrder="-10" />
    <plugin name="middle_plugin" ... />
    <plugin name="late_plugin" ... sortOrder="10" />

    Tip: When you don't specify a sortOrder, Magento sets it to 0 by default. This means multiple plugins without a sortOrder will have equal priority, and Magento will use their module names to break the tie.

    Let's look at a real-world example that shows both sortOrder and module name ordering in action:

    <!-- Vendor_Alpha/etc/di.xml -->
    <type name="Magento\Catalog\Model\Product">
        <plugin name="vendor_alpha_product"
                type="Vendor\Alpha\Plugin\Product"
                sortOrder="20"/>
    </type>
     
    <!-- Vendor_Beta/etc/di.xml -->
    <type name="Magento\Catalog\Model\Product">
        <plugin name="vendor_beta_product"
                type="Vendor\Beta\Plugin\Product"
                sortOrder="-10"/>
    </type>
     
    <!-- Vendor_Charlie/etc/di.xml -->
    <type name="Magento\Catalog\Model\Product">
        <plugin name="vendor_charlie_product"
                type="Vendor\Charlie\Plugin\Product"
                sortOrder="-10"/>
    </type>

    These plugins will execute in this order:

    1. vendor_beta_product (has sortOrder="-10", and "Beta" comes before "Charlie" alphabetically)
    2. vendor_charlie_product (same sortOrder as Beta, but "Charlie" comes after alphabetically)
    3. vendor_alpha_product (runs last with sortOrder="20")

    When deciding whether to use sortOrder, you have two main options:

    If you're the first one adding a plugin to a class, it's often best to skip the sortOrder. This gives other developers more flexibility as it allows them to easily work around your plugin by defining a sortOrder on their plugins if needed.

    If you're adding a plugin to a class that already has plugins, or if the execution order is critical for your code to work, you may want to explicitly set a sortOrder to ensure your plugin runs exactly when you need it to.