Fire-and-forget server-side tracking events with Matomo

tl;dr Use give-notice package to send non-blocking tracking requests to Matomo.

Matomo is a popular open-source analytics platform. Besides the well-known JavaScript tracker, Matomo provides a Tracking HTTP API to track events server-side.

I use this API whenever I need to track events that don't have a frontend at all - CLI scripts, background jobs, API endpoints, or webhooks. No JavaScript tracker available here, but the Tracking API works just fine.

The challenge with server-side tracking is that HTTP requests can block your app. If the analytics server is slow or unavailable, your users shouldn't have to wait. Depending on your use case it may be acceptable to send request asynchronously in the background, or even drop tracking requests entirely in such cases.

pixelbrackets/give-notice is a PHP library I wrote for exactly this use case a while ago: simple fire-and-forget HTTP notifications.

Matomo Event Tracking

There is no setup required in Matomo itself. For basic event tracking you don't need any API user or token, it accepts anonymous requests by default. You only need a token if you want to pass sensitive parameters like a custom visitor IP or event timestamps. Since these are server-side requests, you can push from any server - no CORS restrictions apply.

The Tracking API accepts GET requests with query parameters. The required parameters are:

  • idsite - Your Matomo site ID
  • rec - Must be set to 1
  • url - The complete URL being tracked

For event tracking you may also use:

  • action_name - Page title (shows as page view in visitor log)
  • e_c - Event category
  • e_a - Event action
  • e_n - Event name

If you use the action_name Matomo records the request as a page view, which then shows up as a visited page in the visitor log. If you only use the event parameters (e_c, e_a, e_n) instead, it shows up as an event action only, without a page view entry.

For CLI scripts or background jobs I typically use action_name to see each execution as a "page" in the visitor log. This is easier to analyze than pure events, which are only visible in the event reports. For tracking specific actions within an app (like a download or form submission), events are the better choice.

A complete tracking URI may look like this:

https://matomo.example.com/matomo.php?idsite=1&rec=1&send_image=0&url=https%3A%2F%2Fmyapp.example.com%2Fworker%2F&action_name=worker-job

As you can see you have the URL-encode the parameters properly.

Bonus: The send_image=0 parameter tells Matomo not to return a tracking pixel - saves some bandwidth since we don't need the response anyway.

Send discardable requests with Give Notice

Install the give-notice package:

composer require pixelbrackets/give-notice

Set an environment variable with your Matomo tracking URI:

export GIVENOTICE_URI='https://matomo.example.com/matomo.php?idsite=1&rec=1&send_image=0&url=https%3A%2F%2Fmyapp.example.com%2Fworker%2F&action_name=worker-job'

Then push it with a single line in your app code:

\Pixelbrackets\GiveNotice\Notification::push();

When you need to track different events from the same app, you can prepare different tracking URLs and pass them directly of course:

\Pixelbrackets\GiveNotice\Notification::push($trackingUrl);

Update: The latest version of the give-notice package now collects multiple requests and sends them all at once at script shutdown. So your code continues immediately without waiting for the Matomo server to respond, until eventually at the end of the script execution all requests are sent in the background.

⌛ Warning! This post is old. The information may be outdated.

No comments on this notepad. If you would like to add something, then don't hesitate to contact me via E-Mail, Mastodon or other social profiles.