awssat/laravel-visits
Laravel Visits lets you track and count visits to Eloquent models, pages, or any item with a simple, cache-friendly API. It supports unique visits, IP and user-agent filtering, custom events, and fast stats for dashboards and analytics.
Architecture fit. awssat/laravel-visits is a tactical Laravel package for attaching visit counters to Eloquent models via a trait, with Redis or Eloquent as the backing store and optional tags, IP de-duplication/protection, and caching. It fits a standard Laravel monolith or modular monolith where the product need is “engagement/popularity counting” — article views, listing impressions, profile visits, resource popularity — not audited analytics, billing, or funnel analysis. The package’s model-polymorphic design maps well to existing Eloquent entities; its Redis mode fits read-heavy, high-write counters; its Eloquent mode fits lower-volume correctness-first use cases. It is a weak fit for multi-tenant isolation, cross-region consistency, unique-visitor analytics, or any metric that must be reconcilable to an external source of truth without additional engineering.
Integration feasibility. Integration is mechanically simple: Composer install, publish config and migrations, add the trait to selected models, choose Redis or Eloquent per environment, and configure tags/IP behavior. The main feasibility work is not code; it is deciding metric semantics (raw views vs. unique visits, tag taxonomy, retention, bot filtering), privacy handling for IP data, and whether Redis is allowed to be the system of record for counts. A TPM should treat this as a bounded pilot on one non-critical model before broader adoption. The low opportunity score (2.06) reinforces that this is an accelerator, not a strategic platform bet.
Technical risk. Risks are moderate and mostly operational rather than architectural: counter drift under concurrency, Redis eviction or loss making counts unrecoverable, Eloquent counter row contention on hot models, unbounded polymorphic table and tag-key growth, cache staleness, and privacy exposure if IP handling is not verified. The package is MIT and community-supported, so there is no vendor SLA; release cadence and Laravel-version compatibility must be checked. The future-dated release metadata should be validated against the repository’s actual tags and changelog. Avoid using this package where counts influence money, ranking with contractual SLAs, or regulatory reporting unless an internal reconciliation layer exists.
Key questions.
VisitCounter interface to reduce lock-in and enable a later swap?Stack fit. Confirm Composer constraints against the target Laravel and PHP versions before committing. The package should sit alongside standard Laravel cache, queue, and database components; Redis mode requires an approved Redis topology and client (phpredis or Predis) consistent with the platform. Eloquent mode requires a migration and index review on the polymorphic visit table. If the application uses morph maps, tenant scoping, or read replicas, validate that keys and model types are namespaced and routed correctly. For Redis Cluster, verify key design is cluster-safe; if not, isolate to a non-clustered Redis instance or add a shim.
Migration path. Start with one low-risk model and a feature flag. Publish config and migrations in staging, run the package against a copy of production-like data, and compare counts with the existing counter or analytics source. Prefer Eloquent mode first if correctness and rollback simplicity matter; prefer Redis first if write volume would overwhelm the database. If an existing counter exists, backfill once and dual-read during the pilot — do not dual-write until idempotency and reconciliation are proven. Rollback should be: disable feature flag, stop writing via the package, retain tables/keys for audit, and fall back to the prior counter path. Wrap package calls in an internal service so the trait is not scattered across models.
Compatibility. Validate Laravel major-version support, PHP version, Redis version, cache store behavior, and database migration compatibility. Check whether the package’s caching layer uses the default cache store; if that store is Redis, separate counter Redis from cache Redis where possible to avoid eviction coupling. Confirm IP-protection behavior under the chosen cache and Redis drivers. Confirm tag naming rules and whether tags are indexed or Redis key segments; tag explosion is a schema and operations concern. For multi-tenant applications, enforce a tenant prefix in config or a wrapper before any production use.
Sequencing.
Maintenance. The package is small and MIT-licensed, so code maintenance is low, but dependency maintenance is not zero. Pin the version, track releases, and assign an owner for Laravel upgrade compatibility. Expect occasional config or migration review when Laravel majors change. If the project becomes abandoned, the fallback is to fork or replace the adapter implementation; the internal wrapper limits blast radius. Budget ongoing effort for schema/index review, Redis key hygiene, and count reconciliation rather than feature development.
Support. There is no vendor SLA. Support is community-driven plus internal on-call. Create a runbook covering driver configuration, Redis failure behavior, how to rebuild counts, how to disable counting via feature flag, and who owns privacy questions. Train application support to distinguish “counter unavailable” from “application unavailable.” Because the package is not a strategic platform, escalation should route to the owning application team, not a central analytics team, unless the metric becomes business-critical.
Scaling. Redis mode scales well for increments but is sensitive to hot keys, tag cardinality, and memory eviction. Eloquent mode does not scale for high-write hot models because of row contention and table growth; reserve it for low-volume or correctness-first counters. The polymorphic visits table will grow with every tracked model and tag; plan indexes, archival, and retention. IP de-duplication sets can grow unbounded if TTLs are not enforced. Caching improves read performance but introduces staleness; define acceptable lag. For very high volume, consider queue-based aggregation or a dedicated counting service rather than scaling this package beyond its design.
Failure modes. Redis outage or eviction can silently lose counts if Redis is the source of truth; define whether the application should fail open (no count), fail closed (error), or fall back to Eloquent. Eloquent mode can deadlock or contend under concurrent increments. Cache invalidation can serve stale counts. Migration locks can affect large tables. Tag or key explosion can exhaust Redis memory. Bot traffic can inflate counts without filtering. IP handling can create privacy exposure if raw addresses are retained. Package incompatibility after a Laravel upgrade can break counting at runtime. Mitigate with health checks, circuit breakers, reconciliation jobs, retention policies, and a documented disable path.
Ramp-up. A Laravel developer can complete a basic integration in under a day. Production hardening is roughly one developer-week for a single model, including privacy review, adapter, observability, load testing, and runbook. TPM effort should focus on metric definition, privacy sign-off, driver selection, and acceptance criteria — not package mechanics. Expect low training burden for engineers and modest training for support. Treat the package as an accelerator for non-critical engagement counters; revisit build-vs-buy if the metric becomes ranking-critical, multi-tenant, or auditable.
How can I help you explore Laravel packages today?