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 and summarize database stat changes over time. Create a stats class, call increase/decrease on events, then query totals and deltas over ranges grouped by day/week/month for easy reporting.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Lightweight & Modular: The package is designed for simplicity, requiring minimal configuration (inheriting BaseStats) and leveraging Laravel’s service container. It aligns well with Laravel’s ecosystem, avoiding heavy dependencies or complex abstractions.
  • Event-Driven Tracking: The increase/decrease/set methods are ideal for tracking business metrics (e.g., subscriptions, orders) in real-time or batch processes. The ability to backdate events (increase(1, $timestamp)) enables historical data correction.
  • Query Flexibility: The StatsQuery builder supports granular time-based aggregation (minute/year) and custom grouping, making it adaptable to analytics dashboards or reporting tools.
  • Extensibility: Supports custom models, relationships (e.g., HasMany), and attributes, enabling multi-tenant or segmented analytics (e.g., per-tenant stats).

Integration Feasibility

  • Laravel-Centric: Built for Laravel (v9–13), with seamless integration via service providers, migrations, and Eloquent. No external services or APIs required.
  • Database Agnostic: Supports MySQL, PostgreSQL, SQLite (via migrations), and likely others (e.g., SQL Server). Schema is straightforward (single table for stats).
  • Event-Driven Hooks: Can be triggered via:
    • Business Logic: Direct calls in controllers/services (e.g., SubscriptionStats::increase() in a SubscriptionCreated event handler).
    • Observers/Listeners: Automate tracking (e.g., created() observer for User model).
    • Jobs/Queues: Decouple tracking from user-facing requests (e.g., TrackSubscriptionJob).
  • Third-Party Sync: The set() method allows external data sources (e.g., Stripe webhooks) to update stats directly.

Technical Risk

  • Schema Dependencies: Requires a dedicated stats table. Migration conflicts could arise if the table name is customized or conflicts with existing tables.
  • Performance at Scale:
    • Write Operations: High-frequency increase/decrease calls (e.g., per-request) may impact DB performance. Mitigation: Batch writes or queue jobs.
    • Query Complexity: Grouping by small intervals (e.g., minute) over large datasets could strain queries. Indexing the stats table on statistic, period_start, and period_end is critical.
  • Backward Compatibility: Major version upgrades (e.g., 1.x → 2.x) introduced breaking changes (e.g., StatsQuery method renames). Test thoroughly during adoption.
  • Custom Use Cases: Advanced features (e.g., multi-dimensional grouping, custom aggregations) may require extending the package or writing raw queries.

Key Questions

  1. Data Granularity: What time intervals (e.g., daily vs. hourly) are needed for analytics? This dictates query performance and storage growth.
  2. Concurrency: Will stats be updated concurrently (e.g., from multiple microservices)? Race conditions on increase/decrease could require transactions or locks.
  3. Retention Policy: How long should stats be retained? Archiving old data (e.g., to cold storage) may be needed to manage DB size.
  4. Multi-Tenancy: If tracking per-tenant stats, how will the statistic column differentiate tenants? (Options: Prefix with tenant ID, use a tenant_id column.)
  5. Auditability: Are immutable snapshots needed for compliance? The package doesn’t natively support versioning; consider adding a version column or shadow table.
  6. Testing Strategy: How will stats be validated? Unit tests for increase/decrease logic and integration tests for query accuracy are essential.

Integration Approach

Stack Fit

  • Laravel Ecosystem: Optimized for Laravel apps using Eloquent, Events, and Queues. Works alongside:
    • Observers/Listeners: Automate tracking (e.g., UserCreated event → UserStats::increase()).
    • Jobs: Decouple tracking from requests (e.g., TrackUserActivityJob).
    • APIs: Sync external data (e.g., set() via Stripe webhook).
  • Database: Compatible with MySQL, PostgreSQL, SQLite. Ensure the stats table is indexed on:
    ALTER TABLE stats ADD INDEX idx_statistic_period ON (statistic, period_start, period_end);
    
  • Frontend/Analytics: Query results can be consumed by:
    • Laravel Views: Pass stats to Blade templates for dashboards.
    • APIs: Expose via Laravel API routes (e.g., /stats/subscriptions?group=week).
    • Third-Party Tools: Export to Google Data Studio, Metabase, or custom dashboards.

Migration Path

  1. Assessment Phase:
    • Audit existing metrics tracking (e.g., manual logs, custom tables).
    • Define scope: Which metrics (e.g., users, orders) and granularity (e.g., daily/weekly).
  2. Setup:
    • Install via Composer:
      composer require spatie/laravel-stats
      php artisan vendor:publish --provider="Spatie\Stats\StatsServiceProvider" --tag="stats-migrations"
      php artisan migrate
      
    • Create BaseStats subclasses (e.g., UserStats, OrderStats) in app/Models/Stats.
  3. Implementation:
    • Option A: Direct Integration Replace manual tracking (e.g., incrementing a counter in a model) with:
      // Before: $user->increment('count');
      // After: UserStats::increase();
      
    • Option B: Event-Driven Use Laravel Events/Listeners to automate:
      // app/Listeners/TrackUserCreation.php
      public function handle(UserCreated $event) {
          UserStats::increase();
      }
      
    • Option C: Batch Processing For historical data, use a job to backfill:
      // app/Jobs/BackfillUserStats.php
      public function handle() {
          User::chunk(100, function ($users) {
              UserStats::set($users->count());
          });
      }
      
  4. Validation:
    • Write unit tests for increase/decrease logic.
    • Test queries with sample data:
      $stats = UserStats::query()
          ->start(now()->subMonth())
          ->groupByWeek()
          ->get();
      
    • Compare results with existing metrics (if applicable).

Compatibility

  • Laravel Versions: Supports v9–13. Test thoroughly if using v10+ (PHP 8.2+ features).
  • Database Drivers: Confirmed support for MySQL, PostgreSQL, SQLite. Test with your DB driver.
  • Customizations:
    • Table Name: Override via config/stats.php (if needed).
    • Period Formatting: Extend StatsQuery for custom date formats.
    • Additional Fields: Add columns to the stats table (e.g., metadata JSON field) via migrations.

Sequencing

  1. Phase 1: Core Metrics
    • Implement 2–3 critical stats (e.g., users, orders) to validate the package.
  2. Phase 2: Automation
    • Add event listeners/jobs for passive tracking.
  3. Phase 3: Advanced Use Cases
    • Extend for relationships (e.g., Tenant::orderStats()).
    • Optimize queries for dashboards.
  4. Phase 4: Monitoring
    • Set up alerts for abnormal stat changes (e.g., sudden drops in UserStats).

Operational Impact

Maintenance

  • Schema Management:
    • Monitor stats table growth. Consider partitioning by period_start for large datasets.
    • Backup strategy: Include stats table in regular DB backups.
  • Dependency Updates:
    • Watch for Laravel/PHP version support (e.g., Laravel 14 compatibility).
    • Update the package during minor version releases (e.g., 2.x → 2.y).
  • Logging:
    • Log errors from increase/decrease calls (e.g., DB connection issues).
    • Example:
      try {
          UserStats::increase();
      } catch (\Exception $e) {
          Log::error("Failed to track user stat", ['error' => $e]);
      }
      

Support

  • Troubleshooting:
    • Common issues:
      • Missing Data: Verify increase/decrease calls are triggered (add logging).
      • Query Errors: Check time ranges and grouping intervals (e.g., groupByMinute() over large datasets).
      • Performance: Optimize queries with indexes or reduce granularity.
    • Debugging tools:
      • DB::enableQueryLog(); to inspect queries.
      • php artisan tinker to test stats manually.
  • Documentation:
    • Maintain a runbook for:
      • How to add new stats (e.g., ProductStats).
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai