Matomo's System Check has started nagging you: "You should set up a crontab to run core:archive." Maybe the dashboard got slower too, or a report timed out while a client was watching. Those are the same problem wearing two faces. Out of the box, Matomo builds ("archives") your reports the moment someone opens a dashboard. That's browser-triggered archiving, and it's fine on a fresh install with a few hundred visits. As traffic grows, every dashboard load turns into a heavier query, the UI stalls, and Matomo starts telling you to move archiving onto a schedule. The fix is to turn off the browser trigger and run Matomo's archiver from cron instead. Here's how to do it right on Matomo 5.x.
First, confirm you're actually tracking data
Before you touch cron, open Visitors → Visits Log. This sounds obvious, but it's the most common false alarm there is: people wire up the cron job, see an empty log and no reports, and decide cron is broken. The real reason is usually that no visits have been tracked yet. No visits means nothing to archive, and that looks identical to a job that isn't running. Confirm you have traffic first, then carry on.
Step 1: disable browser-triggered archiving
In Matomo, go to Administration (⚙) → System → General Settings and set:
- Archive reports when viewed from the browser:
No - Archive reports at most every X seconds:
3600
The first option stops dashboards from triggering archiving on demand. The second caps how often a report can be recomputed, so even an edge case can't hammer your database. For ordinary day, week, month, and year reports, the dashboard now reads prebuilt archives instead of building them on the fly. Custom segments and custom date ranges are the exception: they can still archive on request, so if you want to close that gap too, keep reading.
Worth knowing: the UI toggle doesn't cover every path. Custom segments can still trigger archiving, and someone could flip the setting back on from the interface. To enforce the off state, including for segment-triggered archiving, add this to config/config.ini.php under the [General] section:
[General]
browser_archiving_disabled_enforce = 1Step 2: find your three values
You need three things to write the command:
- The PHP CLI path. Run
which php. It's usually/usr/bin/php, but it varies by host, so check rather than assume. - The Matomo path: the directory that holds the
consolefile, like/var/www/matomo. - Your Matomo domain: the base URL of the install, like
https://analytics.example.org.
One thing trips people up: console is Matomo's command-line entry point. It isn't matomo.php (that's the tracking endpoint) and it isn't index.php. Point the archiver at the wrong file and you'll get HTML back, including the giveaway line "This file is the endpoint for the Matomo tracking API." That message means you aimed at the tracker by mistake.
Step 3: test the command by hand first
Run the archiver by hand before it ever goes into cron, and run it as the same user your web server runs as, usually www-data. That keeps the file permissions in Matomo's tmp/ cache consistent with what the web UI expects:
sudo -u www-data /usr/bin/php /path/to/matomo/console core:archive --url=https://analytics.example.org/--url tells the archiver the base URL of your install. Give it the whole thing, including the subdirectory if Matomo doesn't sit at the root: --url=https://example.org/matomo/. You'll also see --matomo-domain in some guides. That one is a console-wide option that takes only the host (analytics.example.org) and discards any path you hand it, so it works as a shorthand for a bare-domain install but breaks a subdirectory one. When in doubt, use --url; it covers both. If you want to see exactly which options your version accepts, run ./console help core:archive on the server.
You should see it loop through your sites and periods and report what it processed. An error or an "invalid response from the API" message means something's wrong; sort it out now, because cron will only hide the output. A "Processed 0 archives" summary is different. It's often normal, since the archiver only does work when there are new visits or invalidated reports to rebuild. Treat it as a problem only if you have recent traffic and the System Check still says archiving has never run. We've written a full companion post on those failures: why Matomo's archiver returns "invalid response" or processes 0 archives. This post is about getting the job set up; that one is about why a set-up job comes back empty.
Step 4: schedule it
There are two ways to install the cron line, and mixing them up is the number-one source of "it just doesn't run." The only difference that matters is whether the line includes a user field.
Option A: system cron (you have root; Debian/Ubuntu). Create /etc/cron.d/matomo-archive:
MAILTO="you@example.com"
5 * * * * www-data /usr/bin/php /path/to/matomo/console core:archive --url=https://analytics.example.org/ > /var/log/matomo/archive.log 2>&1Files in /etc/cron.d/ require a user field. That's the www-data sitting in the sixth position, before the command. This one runs every hour at five past.
Option B: user crontab (shared hosting, no root). Run crontab -e and add the same line, minus the user field, because a personal crontab already runs as you:
5 * * * * /usr/bin/php /path/to/matomo/console core:archive --url=https://analytics.example.org/ > /var/log/matomo/archive.log 2>&1Two details cause most of the grief here:
- The user field belongs only in
/etc/cron.d/files. Putwww-datain acrontab -eline and it breaks; leave it out of/etc/cron.d/and it breaks the other way. - Log somewhere the cron user can write and the web server can't serve. The
> ... 2>&1redirect sends every line of output to a file, and that output can include install details, so keep it out of the web root./var/log/matomo/archive.logis a good default; create the directory and make sure the cron user can write to it. If you'd rather log inside Matomo's own folder, first confirm the file returns 403 or 404 from a browser. And don't point the log at/home/youruser/...while the job runs aswww-data: you'll get an empty or missing log, which once again looks exactly like cron not running.
Step 5: verify it ran
After the first scheduled run:
- Re-open Administration → System → General Settings; it shows when archiving last completed.
- Check the log file from Step 4 for a clean run.
- Re-run the System Check under Administration → Diagnostics. The crontab warning clears once a scheduled run has succeeded.
No cron on your host? Use the web-cron
Some shared hosts don't expose cron at all. Matomo can still be archived over HTTP. Point an external scheduler, or your host's URL-based "cron" tool, at the archive endpoint:
https://analytics.example.org/path/to/matomo/misc/cron/archive.php
POST the super user's token_auth to that URL. On Matomo 5, new auth tokens are POST-only by default, so a token sitting in a GET query string will usually be rejected outright. And even when a GET does work, the token ends up in access logs and proxy logs along the way. If your scheduler can only send GET requests, create a token that's explicitly allowed for GET and accept that exposure.
One more thing to watch: the web-cron endpoint has to be reachable over HTTP. (The console command itself usually archives through internal CLI processes and only falls back to curl over HTTP when it can't.) So if your web cron starts failing with gateway errors behind a reverse proxy, that's a proxy-config problem rather than an archiving one. See fixing 502s on a reverse-proxied Matomo.
How often, and what happens as you grow
Hourly (5 * * * *) is the standard recommendation, and it's cheaper than it looks. core:archive works out for itself which sites and periods actually need reprocessing, so most runs do very little. Want fresher reports? Run it every 15–30 minutes. Once you're archiving dozens of sites, or a couple of very busy ones, a single hourly pass can get heavy. That's the point where you split low- and high-traffic sites onto separate schedules and start tuning concurrency and memory, which we get into in scaling Matomo archiving CPU and memory.
What we'd actually do
Disable the browser trigger, find your three values, and run the command by hand once before it goes anywhere near cron. That one manual run is the difference between a five-minute setup and an afternoon of guessing; it shows you the real output cron would otherwise swallow. Then install the line with the right user-field rule for where it lives, log to a file outside the web root, and re-run the System Check to confirm.
Martez connects Matomo with Meta Ads and Google Ads so ROAS, CLV, and attribution sit next to your web analytics instead of in a separate spreadsheet. It's in private beta. Join the waitlist if that's relevant.
Get the archiver onto cron once, and the warning goes away. So do the slow dashboards.