Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Stats Laravel Package

spatie/laravel-stats

Lightweight Laravel package to track stat changes in your app over time. Create a stats class, call increase/decrease on events (e.g., subscriptions), then query totals, increments, decrements, and differences grouped by day/week/month for any date range.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Use Case Alignment: Ideal for tracking time-series metrics (e.g., subscriptions, cancellations, user growth) in Laravel applications where historical trend analysis is required. Fits well in analytics-heavy or subscription-based SaaS products.
  • Lightweight Design: Stateless, query-based approach avoids heavy database migrations or complex event systems, making it suitable for low-overhead tracking.
  • Extensibility: Inherits from BaseStats, allowing customization for domain-specific metrics (e.g., RevenueStats, FeatureUsageStats).
  • Query Flexibility: Supports granular time-based grouping (groupByWeek, groupByMonth) and range filtering, enabling ad-hoc reporting.

Integration Feasibility

  • Laravel Native: Built for Laravel’s Eloquent/Query Builder, reducing friction in adoption. Works seamlessly with existing database schemas.
  • Minimal Boilerplate: Requires only:
    • A BaseStats subclass per metric.
    • increase()/decrease() calls in business logic.
    • Optional: Custom StatsQuery extensions for advanced aggregations.
  • Database Agnostic: Uses Laravel’s query builder, supporting MySQL, PostgreSQL, SQLite, etc., but relies on standard SQL functions (e.g., DATE_TRUNC for grouping).

Technical Risk

  • Performance at Scale:
    • Risk: High-frequency increase()/decrease() calls could bloat the underlying table (e.g., stats table with 1 row per event).
    • Mitigation: Use batch inserts or asynchronous queues (e.g., Laravel Queues) for high-volume metrics.
  • Query Complexity:
    • Risk: Custom groupBy logic may require raw SQL for non-standard time buckets (e.g., fiscal quarters).
    • Mitigation: Extend StatsQuery or use Laravel’s DB::raw() for edge cases.
  • Data Retention:
    • Risk: No built-in TTL or archiving; old data may accumulate.
    • Mitigation: Implement partitioning or scheduled cleanup (e.g., Laravel Scheduler).

Key Questions

  1. Metric Granularity: Should stats track per-user, per-tenant, or global aggregates? (Affects table design.)
  2. Real-Time vs. Batch: Will stats be queried in real-time (e.g., dashboards) or batch-processed (e.g., nightly reports)?
  3. Concurrency: Are increase()/decrease() calls idempotent? (Race conditions possible without locks.)
  4. Custom Aggregations: Are advanced metrics (e.g., moving averages, percentiles) needed beyond basic counts?
  5. Database Schema: Will the default stats table conflict with existing schemas? (Consider naming conventions.)

Integration Approach

Stack Fit

  • Laravel Ecosystem: Optimized for Laravel’s service containers, Eloquent, and query builder. Integrates cleanly with:
    • Laravel Queues: Offload increase()/decrease() calls to background jobs.
    • Laravel Scout: Combine with search for metric-based filtering.
    • Laravel Nova/Vue: Surface stats in admin panels via custom resources.
  • PHP Version: Requires PHP 8.0+ (check compatibility with legacy apps).
  • Database: Works with MySQL 5.7+, PostgreSQL 10+, SQLite 3.8+. Avoids ORM-specific features.

Migration Path

  1. Pilot Phase:
    • Start with 1–2 critical metrics (e.g., UserSignups, Revenue).
    • Instrument increase()/decrease() in high-impact endpoints (e.g., checkout, signup flows).
  2. Infrastructure Setup:
    • Publish the stats migration (php artisan vendor:publish --tag=stats-migrations).
    • Configure database indexes on statable_type, statable_id, and created_at.
  3. Query Optimization:
    • Test groupBy performance with large time ranges (e.g., 1M+ rows).
    • Add materialized views or caching (e.g., Redis) for frequent queries.
  4. Rollout:
    • Gradually add metrics; monitor query performance and table growth.

Compatibility

  • Laravel Version: Tested with Laravel 9+. May require adjustments for older versions (e.g., use statements).
  • Dependencies: No hard dependencies beyond Laravel core; conflicts unlikely.
  • Customization:
    • Extend BaseStats for multi-dimensional stats (e.g., SubscriptionStats::increase($planId)).
    • Override getTable() to use custom table names (e.g., tenant_stats).

Sequencing

Phase Task Dependencies
Discovery Identify 3–5 key metrics to track. Business stakeholders
Setup Install package, publish migration, configure .env. Laravel project running
Instrument Add increase()/decrease() calls to business logic. API endpoints or event listeners
Query Test StatsQuery for reporting needs. Initial data populated
Optimize Add indexes, caching, or batching for scale. Usage patterns observed
Monitor Set up alerts for table growth or query latency. Production deployment

Operational Impact

Maintenance

  • Low Overhead:
    • No external services; maintenance aligns with Laravel updates.
    • Upgrade Path: Minor versions are backward-compatible; major versions require testing.
  • Monitoring:
    • Track stats table size (e.g., via Laravel Telescope or custom health checks).
    • Monitor increase()/decrease() call latency (e.g., with Laravel Debugbar).

Support

  • Troubleshooting:
    • Common issues: missing indexes, timezone mismatches in queries, or race conditions in high-concurrency apps.
    • Debug with StatsQuery::toSql() to inspect generated queries.
  • Documentation:
    • Spatie’s README is comprehensive but lacks advanced use cases (e.g., multi-tenant stats).
    • Internal Docs Needed: Define metric ownership (e.g., "Who owns UserCancellations?").

Scaling

  • Horizontal Scaling:
    • Stateless Design: Scales horizontally with Laravel’s queue workers.
    • Database: Partition stats table by created_at for large datasets (PostgreSQL: CREATE TABLE stats (created_at TIMESTAMP) PARTITION BY RANGE (created_at)).
  • Performance Bottlenecks:
    • Write-Heavy: Batch increase() calls (e.g., 100 calls → 1 DB write).
    • Read-Heavy: Cache frequent queries (e.g., StatsQuery::get() results in Redis with TTL).

Failure Modes

Risk Impact Mitigation
Database Locks High concurrency on stats table. Use DB::transaction() for batches.
Query Timeouts Large time ranges or groups. Limit default query ranges (e.g., 1 year max).
Data Corruption Manual INSERT/UPDATE conflicts. Use only increase()/decrease().
Retention Bloat Unbounded table growth. Implement TTL (e.g., soft-delete old rows).
Schema Conflicts Custom statable_type collisions. Use namespaced types (e.g., app.UserSignups).

Ramp-Up

  • Developer Onboarding:
    • Time: 1–2 hours to instrument a new metric.
    • Skills Needed: Basic Laravel/Eloquent knowledge.
  • Training:
    • Workshop: Demo StatsQuery for reporting teams.
    • Cheat Sheet: List of all tracked metrics and their statable_type values.
  • Adoption Barriers:
    • Resistance: Teams may prefer existing analytics tools (e.g., Mixpanel). Solution: Highlight cost savings and data ownership.
    • Complexity: Custom aggregations require SQL knowledge. Solution: Provide templates for common queries.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport