pushery/matomo-analytics-for-laravel
A Laravel wrapper for Matomo Analytics that lets you track page views, events, and goals server-side through a clean, configurable API. Keep tracking code out of your views and respect visitor consent.
Package context. This is a Laravel package (v0.35.0) that integrates Matomo analytics with a Laravel application, and it clearly carries non-trivial asynchronous machinery: a queue with attempts/tries, a retry window, claimed batches with a staleness reclaim timer, and a dead-letter table with retention pruning. That is a data-pipeline package, not a thin API wrapper, and it should be evaluated as such.
Architecture fit. The package follows the Laravel conventions we want: config published to config/, migrations published to database/migrations/, environment-driven configuration, and an artisan-scheduled prune job for dead letters. The v0.35.0 additions push three previously code-level tunables (queue.tries, queue.retry_until_minutes, batch.stale_after_minutes) into environment variables, which is exactly the right direction for a package we intend to run across multiple environments (local, staging, production workers) without config-file drift.
Integration feasibility. High. The release is additive plus one narrow behavior change plus one static-analysis fix. Nothing requires a rewrite of host-application code. The migration fix is the most immediately valuable item for us: MatomoAnalytics\Support\TableLookup is now public API, which means our Larastan/PHPStan run will stop flagging published migrations as calls into internal classes — a class of error our teams historically "fixed" by hand-editing published migration files, which is a maintenance trap we want to avoid. That alone removes a recurring papercut from our CI.
Technical risk.
MATOMO_DEAD_LETTER_RETENTION_DAYS disabled the daily prune (same as 0). Now negatives fall back to the shipped 30 days, and only 0 disables pruning. Any environment where the value was set to -1 as a "disable" idiom — or where a templating/secret layer emitted a negative number — will start silently deleting dead letters after 30 days. This is a data-loss-shaped change, not merely an error-shaped one. It is low probability but high impact, and it is not detectable by tests because it is a config interpretation change.MATOMO_QUEUE_TRIES=three), but it means a misconfigured value degrades to defaults silently rather than failing fast. For queue tries and retry windows, a silent fallback to a shipped default could mask an intended capacity change. We should treat these as observability requirements, not just config.TableLookup to public API is a fix, but it also freezes a support class into our compatibility contract. Future refactors of that class are now semver-relevant to us.Key questions for the maintainer.
config:clear and worker restart.)TableLookup now covered by the package's backward-compatibility promise, and does that promise extend to its method signatures?0.Stack fit. Standard Laravel package: composer install, publish config and migrations, schedule the prune command, run queue workers. No framework-version or infrastructure surprises indicated by this release. The env-var surface aligns with our 12-factor deployment model and with how we template per-environment config in our orchestrator.
Migration path.
composer.json and record the pre-upgrade config snapshot from every environment — specifically the value of MATOMO_DEAD_LETTER_RETENTION_DAYS and whether any environment sets a negative value..env templates, Helm/K8s values, and secret-manager entries. Convert any intentional "disable pruning" to 0. Any accidental negative value should be corrected to the intended positive number or removed.config:clear, then re-run static analysis (Larastan/PHPStan) and confirm the published-migration internal-class errors disappear. Do not republish migrations unless the maintainer confirms it is required.Compatibility. No API or schema changes are stated. The only externally observable change is the retention semantics. Config keys (queue.tries, queue.retry_until_minutes, batch.stale_after_minutes) already existed; the release only adds an env-var path to them, so applications currently setting these in config/matomo-analytics.php continue to work. Teams that already set the config value and also set the env var should confirm precedence (env typically wins) before enabling both.
Sequencing.
0 still disables pruning. Read logs for silent coercion warnings.Maintenance. Low ongoing burden, but the release shifts a meaningful amount of behavior into environment variables. That moves configuration out of code review and into deployment manifests, which is generally good for us but means config changes now require the same review rigor as code changes. We should add the three new variables and the retention variable to our documented config surface with their valid ranges and fallback rules.
Support. Two support-relevant behaviors to document for on-call:
MATOMO_DEAD_LETTER_RETENTION_DAYS no longer means "keep forever." If someone reaches for that idiom from older documentation or habit, dead letters will be pruned at 30 days. This is the single most likely source of a confusing post-upgrade support ticket ("our dead letters vanished"), and it should be called out in the internal changelog.Scaling. The new tunables are directly relevant to scaling the queue under load: queue.tries and queue.retry_until_minutes govern how long a struggling downstream (Matomo API) can be retried before a job is abandoned to the dead-letter table, and batch.stale_after_minutes governs how quickly a crashed worker's claimed batch is reclaimed by another worker. Being able to raise staleness reclaim in production during a worker-scaling event without a code deploy is a genuine operational win — but the converse is also true: a too-aggressive stale_after_minutes will cause two workers to process the same batch, and the release makes that mistake a one-line env change away. Recommend a documented floor for this value and monitoring on duplicate-batch symptoms.
Failure modes.
| Failure mode | Trigger | Detection | Mitigation |
|---|---|---|---|
| Unintended dead-letter deletion | Negative retention value carried over | Absence of expected rows; no error raised | Pre-upgrade audit; convert negatives to 0 |
| Silent config fallback | Typo or non-integer env value | None by default — behavior just reverts to shipped default | Set values explicitly; add a config assertion or startup log check |
| Double batch processing | MATOMO_BATCH_STALE_AFTER_MINUTES set too low |
Duplicate ingestion in Matomo; increased API calls | Conservative floor value; monitor batch claim counts |
| Long-running retry storms | queue.retry_until_minutes raised without adjusting tries |
Queue depth growth, worker saturation | Alert on queue depth and dead-letter rate |
| Static-analysis regressions post-refactor | Future changes to TableLookup |
CI fails on Larastan/PHPStan | Pin version; treat the class as a tracked API dependency |
Ramp-up. Minimal. This release requires no new developer knowledge to install. The knowledge investment is on the operations side: the team needs a short internal note covering (a) the retention semantics change, (b) the new env vars and their fallback behavior, and (c) the TableLookup public-API status so nobody hand-edits a published migration again. Estimate half a day of engineering for the upgrade and audit, plus a brief runbook update. Recommend pinning to ~0.35.0 rather than floating, given the pre-1.0 cadence and the demonstrated willingness to change config semantics in a point release.
How can I help you explore Laravel packages today?