Skip to main content

Configuration reference

Every key, its environment variable and the value shipped in the package. This page — not your published config/matomo-analytics.php — is the authoritative list, because a key your file does not contain still has its default. See configuration for why.

A key with an environment variable can be set either way. A key without one is a structure, and is edited in the file.

Connection and master switch

KeyEnvDefaultMeaning
enabledMATOMO_ENABLEDfalseMaster switch. Installing the package tracks nobody until you set this to true.
hostMATOMO_HOSTBase URL of your Matomo. Everything else is derived from it.
site_idMATOMO_SITE_IDThe Matomo site id.
site_id_resolvernullfn(): ?int — an invokable class-string or closure that may name the site for the hit being built. null, or anything that is not a positive int, falls back to site_id. For multi-tenant applications; see below.
require_tlsMATOMO_REQUIRE_TLSfalseRefuse to track over a plaintext host. With it on, an http:// host counts as unconfigured and nothing is tracked — the same no-op a missing host takes, never an exception. Off by default because Matomo on a private network without TLS is a legitimate deployment. What it protects: token_auth travels in the request body on every server-side hit.
tokenMATOMO_TOKENtoken_auth, server-side only. Needed for the real client IP, exact hit time, and the read side.
tracker_pathMATOMO_TRACKER_PATHmatomo.phpPath to the tracking endpoint, relative to host.
js_pathMATOMO_JS_PATHmatomo.jsPath to the JavaScript tracker.
timeoutMATOMO_TIMEOUT5Request timeout in seconds for tracking calls.

Tracking is a no-op while host or site_id is missing. See installation.

One site id per request

site_id_resolver is the seam for an application that tracks each tenant into its own Matomo site. It is called while the hit's payload is built, so it decides per hit rather than per process:

'site_id_resolver' => fn (): ?int => Tenant::current()?->matomo_site_id,

It takes no arguments on purpose — the tenant is a property of your own request context, which the callback already has.

A buffered batch may therefore carry hits for several sites, and that is fine. Each buffered hit holds its own idsite, and Matomo's Bulk endpoint accepts a mixed batch. This is why the seam is a resolver rather than a per-request connection: rebuilding the connection would not fix the buffer, and this does.

Anything other than a positive int falls back to site_idnull, a string, a negative, and a resolver that throws. Tracking never breaks the caller, and that has to include an extension point the package cannot see.

These seven values are read once and then held for the life of the process. In an ordinary request that is invisible, because the process ends with the response. In a long-lived one — a queue:work or matomo:work worker, or Octane — the values the process resolved first are the values it keeps, and changing the configuration underneath it does nothing until it restarts.

It matters in one shape: an application that repoints this package per request or per tenant, so that each tenant tracks into its own Matomo site. There the worker sends every tenant's hits to whichever site it saw first. The way to do it is a tracking gate plus custom dimensions, which read live configuration on every hit — not by swapping the connection under a running worker, which does not work for the reason the Octane guide sets out.

Transmission

KeyEnvDefaultMeaning
modeMATOMO_MODEqueuequeue, sync or batch.
schedule.run_in_backgroundMATOMO_SCHEDULE_BACKGROUNDtrueRuns both scheduled commands off your scheduler, so a slow Matomo never delays another task. Costs you the failure report: Laravel raises a scheduled command's non-zero exit only in the foreground, so a background one reaches neither ScheduledTaskFailed nor your exception handler. Set it to false when that report matters more than the wait.
queue.connectionMATOMO_QUEUE_CONNECTIONnullQueue connection; null uses the default.
queue.queueMATOMO_QUEUEmatomoQueue name. Your worker must serve it.
queue.tries5Delivery attempts before the batch is dead-lettered.
queue.backoff[30, 120, 300, 900]Seconds between retries, escalating.
queue.retry_until_minutes1440Outer bound on retrying. queue.tries normally ends the loop first.

See transmission modes.

Batch buffer

KeyEnvDefaultMeaning
batch.driverMATOMO_BATCH_DRIVERdatabaseBuffer store: database, redis, file or array.
batch.sizeMATOMO_BATCH_SIZE200Hits per Bulk request, and therefore how many requests a backlog costs — 2000 hits against a Matomo answering in 20ms take 1021ms at 50, 276ms at 200 and 125ms at 500. It is also the memory knob: a claimed batch is held at roughly 2.3 KB per hit.
batch.flush_intervalMATOMO_BATCH_INTERVAL60Seconds between passes of the matomo:work daemon.
batch.max_per_flush2000Cap on hits moved by a single flush pass.
batch.stale_after_minutes15Reclaim a claimed-but-unacknowledged batch after this long. Floored at one minute: at zero every claim expires the moment it is made, and at-least-once delivery becomes guaranteed double delivery.
batch.redis_connectionMATOMO_BATCH_REDISdefaultRedis connection for the redis driver.
batch.tablematomo_tracking_bufferTable for the database driver.
batch.pathMATOMO_BATCH_PATHnullSpool directory for the file driver; unset means storage/app/matomo-analytics.
batch.max_attemptsMATOMO_BATCH_MAX_ATTEMPTS25Consecutive failed flushes before a stuck batch is dead-lettered.
batch.dead_letter.enabledtrueMove undeliverable batches to the dead-letter store.
batch.dead_letter.retention_daysMATOMO_DEAD_LETTER_RETENTION_DAYS30Days a dead letter is kept before the daily prune deletes it. 0 keeps them forever.
batch.dead_letter.tablematomo_dead_lettersDead-letter table.

The max_attempts counter lives in the cache and therefore needs a persistent cache store — see reliability.

Resilience and alerting

KeyEnvDefaultMeaning
resilience.never_throwtrueTracking errors never bubble into the application.
resilience.connect_timeout2Connection timeout in seconds.
resilience.reporting.report_after_attempts3Report only after this many failures.
resilience.reporting.channelMATOMO_REPORT_CHANNELreportreport (exception handler plus log), log, or silent.
resilience.reporting.levelwarningLog level for a reported failure.
resilience.reporting.transient_levelnullLog level for each retry; null logs none.
resilience.reporting.throttle_minutes15Throttle window per error signature. 0 disables throttling.

Reporting (read side)

KeyEnvDefaultMeaning
reporting.pathMATOMO_REPORTING_PATHindex.phpPath to the Reporting API.
reporting.timeoutMATOMO_REPORTING_TIMEOUT10Request timeout in seconds for report calls.
reporting.default_periodMATOMO_REPORTING_PERIODdayPeriod used when a call omits one.
reporting.default_dateMATOMO_REPORTING_DATEtodayDate used when a call omits one.
reporting.segments[]Named-segment registry: key to Matomo segment definition.
reporting.cache.enabledtrueCache report responses.
reporting.cache.storeMATOMO_REPORTING_CACHE_STOREnullCache store; null uses the default.
reporting.cache.prefixmatomo-analytics:reportCache key prefix.
reporting.cache.ttl.live60Seconds for realtime counters.
reporting.cache.ttl.today300Seconds for periods covering today.
reporting.cache.ttl.recent900Seconds for yesterday and recent ranges.
reporting.cache.ttl.historical3600Seconds for fully archived past periods.

See reporting and queries and segments.

Visitor identity

KeyEnvDefaultMeaning
visitor.rotatedailyCookieless salt rotation: daily, weekly or never.
visitor.user_idnullauth attaches the authenticated user id as the Matomo User ID; null attaches none.
anonymize_iptrueTruncate the client IP before sending it.
ip_headerMATOMO_IP_HEADERnullForwarding header carrying the real client IP; the first address in the chain is used. Trusted without verification — read the warning.

Tracking gate

KeyEnvDefaultMeaning
tracking.environmentsnullRestrict tracking to these environments; null or [] means all.
tracking.track_authenticatedtrueTrack logged-in users.
tracking.except_abilities[]Skip users who pass any of these Gate abilities.
tracking.except_ips[]Skip these client IPs or CIDR ranges.
tracking.except_routes['horizon*', 'telescope*', 'nova*', 'up', 'health*', 'livewire/*']Skip these request-path patterns.
tracking.gatenullInvokable class-string or closure for full control.

See the tracking gate.

Privacy

KeyEnvDefaultMeaning
privacy.honor_dnttrueSkip tracking on DNT: 1 or Sec-GPC: 1.
privacy.cookielesstruePush disableCookies in the client snippet.
privacy.consentnoneClient consent posture: none, cookie or full.
privacy.opt_out.respecttrueHonor the first-party opt-out cookie.
privacy.opt_out.cookiematomo_opt_outName of that cookie.
privacy.redact.enabledtrueStrip secrets and PII from tracked URLs.
privacy.redact.replacementREDACTEDValue a redacted parameter is replaced with.
privacy.redact.query_paramsA list of token, password, secret, signature and session parameter namesParameters whose value is replaced; the key is kept. Matched case-insensitively.
privacy.redact.patterns[]Regular expressions applied to the URL.
privacy.redact.keys['url', 'urlref', 'link', 'download']Which payload fields are redacted.

See consent and redaction for the full shipped parameter list and how to extend it.

Bots

KeyEnvDefaultMeaning
bots.trackfalseRecord bots and crawlers instead of excluding them.
bots.detect_ai_crawlerstrueUse the maintained AI/LLM crawler token list.
bots.detect_generictrueUse the generic crawler signals.
bots.allow[]User-Agent tokens always treated as human. Overrides every other layer.
bots.deny[]User-Agent tokens always treated as bots.
bots.detectornullExtra invokable class-string or closure, consulted last.

See bots and AI crawlers.

AI chatbot telemetry

KeyEnvDefaultMeaning
ai_chatbots.trackfalseMaster switch for AI-chatbot telemetry.
ai_chatbots.autofalseAuto-register the matomo.chatbots middleware on the web group.
ai_chatbots.rec_mode11 records bots only (Matomo discards non-bots); 2 lets Matomo decide.
ai_chatbots.sourceLaravelLabel identifying this collector.
ai_chatbots.user_agentsnullRecognized fetchers; null uses the built-in on-demand list.

See AI assistants.

Page-view middleware

KeyEnvDefaultMeaning
middleware.autofalseAuto-register the page-view middleware on the web group.
middleware.only_gettrueTrack GET requests only.
middleware.only_successfultrueTrack delivered pages only: 2xx and 304.
middleware.skip_livewiretrueSkip Livewire update requests.
middleware.strip_queryfalseDrop the query string from the tracked URL.
middleware.performancefalseStamp the server generation time onto the page view.

See server-side tracking.

Client-side snippet

KeyEnvDefaultMeaning
js.enabledMATOMO_JS_ENABLEDtrueRender the client snippet at all. Governs both @matomoScript and the <noscript> pixel.
js.hostMATOMO_JS_HOSTnullSeparate asset host for the tracker script; tracking stays on host.
js.tag_managernullFull Tag Manager container URL. When set, the container renders instead of the tracker.
js.enable_link_trackingtrueTrack outbound links and downloads.
js.performancetruefalse pushes disablePerformanceTracking.
js.custom_dimensions[]Map of dimension id to value, set on every page view.
js.content_trackingfalsefalse, 'all' or 'visible'.
js.heartbeat15Heartbeat timer in seconds; 0 disables it.
js.noscripttrueRender a <noscript> tracking pixel.
js.dns_prefetchtrueEmit a dns-prefetch hint for the Matomo origin.

See client-side tracking.

SPA

KeyEnvDefaultMeaning
spa.enabledMATOMO_SPAfalseRecord a virtual page view on each soft navigation.
spa.adapters['livewire', 'inertia']Which adapters to attach: livewire, inertia, generic.
spa.performancetrueForward an app-provided timing object per virtual page view.

See SPA and soft navigation.

Web Vitals

KeyEnvDefaultMeaning
web_vitals.enabledfalseEnable the ingest route and the directive.
web_vitals.pathmatomo-analytics/web-vitalsRoute path for the beacon endpoint.
web_vitals.categoryWeb VitalsMatomo event category the samples are recorded under.
web_vitals.metrics['LCP', 'CLS', 'INP', 'FCP', 'TTFB']Accepted metrics. Also the allowlist the route validates against.
web_vitals.throttle60,1Route throttle, "requests,minutes". null disables it; an absent key falls back to the shipped value rather than to no limit.
web_vitals.middleware[]Extra middleware for the ingest route. Empty by default, because the browser beacons it with sendBeacon() and that carries no CSRF token — which also means no session is started there, so tracking.track_authenticated and tracking.except_abilities see a guest on this path. Add ['web'] if you need them to apply, and exempt this one route from CSRF on your side.
web_vitals.librarynullScript URL for the web-vitals library; null means your app provides it.

See Web Vitals.

Annotations

KeyEnvDefaultMeaning
annotations.releaseMATOMO_ANNOTATE_RELEASESfalseEnable matomo:annotate --release.
annotations.starredfalseStar release annotations.
annotations.release_prefixDeployedRelease note is the prefix followed by the version.

See release annotations.

Events

KeyEnvDefaultMeaning
eventstrueFire the package's Laravel events.

See events.

Keys your published config may still carry

These keys are gone from the shipped config file. If you published the config in an earlier version, your copy still has them — and they do nothing. Deleting the lines changes nothing:

  • resilience.durability (and its MATOMO_DURABILITY variable) — never read by any code path; removed from the shipped config in 0.19.0
  • bots.record_ai_dimension — removed earlier

They are listed here rather than quietly dropped, because a reference that omits a key you can see in your own file is worse than one that explains it. Publishing the config again with --force gives you the current set, but overwrites your edits.

Every environment variable

MATOMO_ENABLED=true
MATOMO_HOST=
MATOMO_SITE_ID=
MATOMO_TOKEN=
MATOMO_TRACKER_PATH=matomo.php
MATOMO_JS_PATH=matomo.js
MATOMO_TIMEOUT=5

MATOMO_MODE=queue
MATOMO_REQUIRE_TLS=false

MATOMO_QUEUE_CONNECTION=
MATOMO_QUEUE=matomo

MATOMO_BATCH_DRIVER=database
MATOMO_BATCH_SIZE=200
MATOMO_BATCH_INTERVAL=60
MATOMO_BATCH_REDIS=default
MATOMO_BATCH_PATH=
MATOMO_BATCH_MAX_ATTEMPTS=25
MATOMO_DEAD_LETTER_RETENTION_DAYS=30

MATOMO_SCHEDULE_BACKGROUND=true

MATOMO_REPORT_CHANNEL=report
MATOMO_REPORTING_PATH=index.php
MATOMO_REPORTING_TIMEOUT=10
MATOMO_REPORTING_PERIOD=day
MATOMO_REPORTING_DATE=today
MATOMO_REPORTING_CACHE_STORE=

MATOMO_IP_HEADER=
MATOMO_JS_ENABLED=true
MATOMO_JS_HOST=
MATOMO_SPA=false
MATOMO_ANNOTATE_RELEASES=false

Only MATOMO_HOST and MATOMO_SITE_ID have no usable default — everything else can be left unset. MATOMO_ENABLED has a default, but it is false, so it is the one you must set to start tracking.

MATOMO_URL is not read. It was accepted as an alias until 0.16.0, which meant an application configuring its own, separate Matomo integration through that key was activating this package as well.