Magento 2

Magento fundamentals: what are the differences between events and plugins?

5 minutes reading

Plugins are the brand new way of extending Magento 2 and, as often happens according to the law of the instrument, if all we have is a hammer, everything looks like a nail.

This article will see the main differences between the good old events and plugins and when it still makes sense to use events instead of plugins to hook our customizations.

Soft v hard dependencies

The very first difference is that events are soft dependencies while plugins are hard dependencies.

Let me explain. If our observer depends on an event triggered by a module that is disabled, our functionality stops working gracefully. In other words, nothing apparently breaks.

Of course, since our observer is not called, something won’t work as expected, but the platform doesn’t throw an exception, and the storefront navigation won’t be affected.

This behavior makes an event a soft dependency.

Conversely, if a plugin depends on a class that could not be found by the system, a runtime exception will be thrown, revealing to the world that something doesn’t work as expected.

This behavior makes a plugin a hard dependency.

It’s important to know this difference because it can guide us in deciding whether to use an event or a plugin to hook our customizations.

Let’s make a couple of examples; they are trivial, but it’s just to give an idea.

  • If we need to determine whether to show a notice in the cart page that tells us the amount we need to reach to have free shipping, we may use an event (e.g., sales_quote_collect_totals_after). If the event is not triggered, we don’t want the storefront to crash just because of a missing notice, albeit an important one. Thus an event could be the right choice.

  • If we need to prevent users from placing an order unless the quote reaches a certain margin, we could choose to use a plugin. If the plugin breaks, the storefront will break as well, and that guarantees us that the users won’t be able to place an order. It’s not a good thing to have a broken storefront, but it can be worse for merchants to receive orders at a loss. Thus, a plugin could be a better choice.

Scope of applicability

There are some limitations in the scope of applicability of events and plugins that are worth mentioning.

Since Magento 1, we know that we can’t observe an event that is not triggered. It means that if there isn’t any event fired where we could hook our customization, we can’t rely on this mechanism.

There are plenty of useful events triggered by the Magento core but rest assured that we will miss one sooner or later.

Plugins are more flexible: they allow to hook any public method of any class, preferably annotated as @api.

☝ Classes annotated as @api guarantees that their public interface won't change until a major or minor update occurs.
To learn more about it: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/versioning/codebase-changes.html

There are three types of plugins:

  • before plugins: allow us to intercept the beginning of a method call and change its parameters;

  • after plugins: allow us to intercept the outcome of a method call, access its parameters. and change the return value;

  • around plugins: allow us to control the method, deciding whether to prevent its execution and that of additional plugins.

I don’t want to explain plugins in more detail; the official documentation covers them exhaustively.

I want to focus on some aspects related to performance.

About performance

Both plugins and events affect performance because they increase the call stack but some kinds of plugins take more CPU time.

Let’s see a benchmark that shows the differences between all of them.

☝ I used Blackfire (highly recommended) to profile the execution of an observer and of three plugins; they just add a sleep(1) statement, to force Blackfire to highlight those calls as bottlenecks.

Observer: 225 µs of CPU time

Before plugin: 1.53 ms of CPU time

After plugin: 645 µs of CPU time

Around plugin: 17.7 ms of CPU time

As we can see, around plugins are at least an order of magnitude slower than the others.

The problem is that they are are often misused: if we don’t need to prevent the execution of the original method and subsequent plugins, around plugins don’t give us more power than the other types, just less performance. In this case, better choose a more appropriate and performant kind of plugin.

I know that a few milliseconds (or microseconds) seem a little thing, but let’s consider that there are hundreds of calls to observers and plugins in a vanilla Magento installation, not to mention the ones added by third-party code.

The total time taken by all these executions can have a relevant impact on the overall performance, especially when they are misused.

☝ Necessary clarification: events can also affect performance negatively if we don't adopt the recommended best practices. To learn more, refer to the official documentation.

Conclusion

We’ve seen the main differences between events and plugins, and that plugins are not all of the same kind.

Carefully choosing the right approach when developing with the Magento framework can make a difference in performance.

Let’s keep in mind that events are still first-class citizens for Magento and let’s take them into account next time we need to modify the behavior of our application.

Post of

COO | Reggio Emilia

Alessandro works at Bitbull as an experienced technical leader devoted to software design, development, and mentoring.
Honored three times with the title of Magento Master and listed among the top 50 contributors in the last years, he is also an active Magento Community Maintainer since 2018 and member of the Magento Association content committee since 2020.