mage-os / mageos-async-events

mage-os/mageos-async-events

An event-driven flexible async events module that allows you to process any event asynchronously.

magento2-module Compatibility: 2.4.7-2.4.9 Code Quality: Fail Tests: Fail Security: Pass MIT

Magento Asynchronous Events

Integration Test
REST

A framework for reliably handling asynchronous events with Magento.

  • Asynchronous: The module uses RabbitMQ (or DB queues) to leverage asynchronous message delivery.
  • Flexible: Decoupling events and dispatches provide greater flexibility in message modelling.
  • Scalable: Handles back pressure and provides an asynchronous failover model automatically.

Installation

$ composer require mage-os/mageos-async-events

Install the module:

$ bin/magento setup:upgrade

Usage

Define an asynchronous event

Create a new async_events.xml under a module's etc/ directory.

<?xml version="1.0"?>
<config
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:module:MageOS_AsyncEvents:etc/async_events.xsd"
>
    <async_event name="sales.order.created">
        <service class="Magento\Sales\Api\OrderRepositoryInterface" method="get"/>
    </async_event>
</config>

Create a Subscription

[!TIP]
To view all available event sinks, check out Async Event Sinks

HTTP

curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "asyncEvent": {
        "event_name": "sales.order.created",
        "recipient_url": "https://example.com/order_created",
        "verification_token": "supersecret",
        "metadata": "http"
    }
}'

Amazon EventBridge

Requires the AWS Sinks package

curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "asyncEvent": {
        "event_name": "sales.order.created",
        "recipient_url": "arn:aws:events:ap-southeast-2:ACCOUNT_ID:rule/BUS_NAME",
        "verification_token": "supersecret",
        "metadata": "eventbridge"
    }
}'

Dispatch an asynchronous event

use \MageOS\AsyncEvents\Model\AsyncEventPublisher;

// ...

public function __construct(private readonly AsyncEventPublisher $asyncEventPublisher) {}

public function execute(Observer $observer): void
{
    /** @var Order $order */
    $order = $observer->getData('order');

    // arguments are the inputs required by the service class in the asynchronous
    // event definition in async_events.xml
    // e.g: Magento\Sales\Api\OrderRepositoryInterface::get
    $message = ['id' => $order->getId()];

    $this->asyncEventPublisher->publish('sales.order.created', $message);
}

Ensure the following consumers are running

bin/magento queue:consumer:start event.trigger.consumer
bin/magento queue:consumer:start event.retry.consumer

Features

Trace

All events are logged at the individual subscription level with a UUID.

All information from the first delivery attempt to the latest attempt is presented as a trace table. The event payload
is also available to view for investigation purposes.

[image: Event Trace Page]

Retries

Events are automatically retried with quadratic back off. The default retry limit is 5. The maximum backoff is
60 seconds.

[!IMPORTANT]
RabbitMQ is required for retries with back off. If you are using DB queues then quadratic back off is
not available, and you will have to implement your own \MageOS\AsyncEvents\Api\RetryManagementInterface

The quadratic backoff is calculated as min(60, pow($deathCount, 2));

Attempt Backoff
1 1 second
2 4 seconds
3 9 seconds
4 16 seconds
5 25 seconds

To change the default retry limit visit Admin > Stores > Settings > Configuration > Advanced > System > Async Events and
update Maximum Deaths.

[image: Retry Limit Config Page]

Replays

An event can be replayed independent of its status. This is useful to debug or replay an event when all retries are
exhausted.

Replays start a new chain of delivery attempts and will respect the same retry mechanism if they fail again.

Lucene Query Syntax

All events are indexed in Elasticsearch by default. This allows you to search through events including the event
payload!

The module supports Lucene Query Syntax to query event
data like attributes.

The following attributes are available across all asynchronous events.

log_id
uuid
event_name
success
created

The following attributes differ between asynchronous event types.

data

Examples

Assuming you have the following events configured

customer.created
customer.updated
customer.deleted
sales.order.created
sales.invoice.created
shipment.created
shipment.updated
shipment.deleted

You can query all customer events by using a wildcard like event_name: customer.* which matches the following events

customer.created
customer.updated
customer.deleted

You can query all created events like *.created which matches the following events

customer.created
sales.order.created
sales.invoice.created
shipment.created

You can further narrow down using the other available attributes such as status or uuid.

The following query returns all customer events which have failed. customer.* AND success: false

You can combine complex lucene queries to fetch event history and then export them via the admin grid as a csv if you
wish.

Searching inside event payloads

Searching an event payload depends on what event you are searching on.

For the following example event payload, four properties are indexed as attributes. Therefore, you can query on
data.customer_email, data.customer_firstname, data.customer_lastname and data.increment_id.
Properties inside array at any level are not searchable.

{
    "data": {
        "customer_email": "[email protected]",
        "customer_firstname": "Veronica",
        "customer_lastname": "Costello",
        "increment_id": "CK00000001",
        "payment_additional_info": [
            {
                "key": "method_title",
                "value": "Check / Money order"
            }
        ]
    }
}

Search all events where the customer email is [email protected]

data.data.customer_email: [email protected]

[image: Lucene Example 1]

Search all events with the order increment id starting with CK and status success

data.data.increment_id: CK* AND success: true

[image: Lucene Example 2]

To turn off asynchronous event indexing visit Admin > Stores > Settings > Configuration > Advanced > System >
Async Events and disable Enable Asynchronous Events Indexing.

Support

Async Events Magento 2.3.x >= Magento 2.4.0 <= Magento 2.4.3 >= Magento 2.4.4
2.x :white_check_mark: :white_check_mark: :x:
3.x :x: :x: :white_check_mark:
4.x :x: :x: :white_check_mark:

No changelog yet

The vendor hasn't published a changelog. Tagged releases appear in the Versions tab.

Versions
Version Stability QA Status Compatibility Released
v4.0.7 stable Fail Magento 2.4.7-2.4.9 Details 2026-03-19 02:14:27
v4.0.6 stable Not tested Not yet tested Details 2025-09-30 06:35:08
v4.0.5 stable Not tested Not yet tested Details 2025-05-06 01:16:01
v4.0.4 stable Not tested Not yet tested Details 2025-01-23 09:58:42
v4.0.3 stable Not tested Not yet tested Details 2025-01-02 22:58:31
v4.0.2 stable Not tested Not yet tested Details 2024-12-17 13:57:58
v4.0.1 stable Not tested Not yet tested Details 2024-07-12 08:49:22
v4.0.0 stable Not tested Not yet tested Details 2024-06-27 11:49:56
v4.0.0-beta beta Not tested Not yet tested Details 2024-04-27 09:22:32
v3.3.0 stable Not tested Not yet tested Details 2024-03-04 09:17:03
v3.2.0 stable Not tested Not yet tested Details 2024-01-10 08:36:20
v2.6.0-beta beta Not tested Not yet tested Details 2024-01-10 08:35:15

Requires 3

Package Constraint
cloudevents/sdk-php ^1.1
magento/framework *
php >=8.1

Requires-dev 2

Package Constraint
magento/magento-coding-standard *
squizlabs/php_codesniffer ~3.5

Compatibility

Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.

Compatibility matrix (Magento × PHP)
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 Pass Pass
2.4.8 Pass Pass
2.4.9 Pass Pass

Code Quality

Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge — a phpcs finding can't make a module incompatible.

Static analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

Static analysis results
Tool Status Findings Summary
PHPCS Warning 3 3 warnings (ruleset: Magento2)
PHPMD Warning 5 5 rule violations (UnusedFormalParameter:3, UnusedLocalVariable:1, MissingImport:1)
Cpd Pass 0
Composer validate Info 1 valid; 1 advisory note (composer validate --strict)

PHPStan

Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases. Cell → details modal.

PHPStan results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 25 25
2.4.8 25 25
2.4.9 25 25

Tests

Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.

Unit tests

Unit tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Integration tests

Integration tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 2 2
2.4.8 not tested not tested
2.4.9 2 2

Security

Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.

Security results
Tool Status Findings Summary
Composer audit Pass 0
Malware scan Pass 0
License
MIT

More from mage-os

View vendor
Make it pay

Turn an existing module into recurring revenue.

If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.