Skip to content
Pro Analyzer — Available with ShieldCI Pro

Data Retention Policy Analyzer

Analyzer IDCategorySeverityTime To Fix
data-retention-policy✅ ReliabilityMedium15 minutes

What This Checks

Validates that data retention policies prevent unbounded growth. Checks for:

  • Log channels using single driver (single file grows forever)
  • Accumulating models without Prunable or MassPrunable trait
  • Missing queue:prune-failed scheduling (failed_jobs table growing unbounded)
  • Missing queue:prune-batches scheduling when Bus::batch() / Batchable is actively used
  • Telescope installed without pruning scheduled
  • Horizon installed without purging configured

Why It Matters

  • Disk Exhaustion: Unbounded log files and database tables eventually fill the disk, causing outages
  • Performance Degradation: Large tables slow queries, even with indexes
  • Compliance: GDPR and other regulations require data retention limits
  • Cost: Cloud storage and database costs grow with unchecked data accumulation

How to Fix

Quick Fix (5 minutes)

Switch from single to daily log driver with rotation:

php
// config/logging.php
'channels' => [
    'daily' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'level' => env('LOG_LEVEL', 'debug'),
        'days' => 14, // Keep 14 days of logs
    ],
],

Proper Fix (15 minutes)

1. Add Prunable trait to accumulating models:

php
use Illuminate\Database\Eloquent\Prunable;

class AuditLog extends Model
{
    use Prunable;

    public function prunable(): Builder
    {
        return static::where('created_at', '<=', now()->subDays(90));
    }
}

2. Schedule model pruning:

php
// routes/console.php (Laravel 11+)
Schedule::command('model:prune')->daily();

// Or in app/Console/Kernel.php (Laravel 10-)
$schedule->command('model:prune')->daily();

3. Schedule job cleanup:

Always schedule failed job pruning when you use queues:

php
Schedule::command('queue:prune-failed --hours=168')->daily();

If your application uses Laravel job batches (Bus::batch() / Batchable trait), also schedule batch pruning:

php
Schedule::command('queue:prune-batches --hours=168')->daily();

TIP

The job_batches table is created by Laravel's default scaffold migration even in apps that don't use batching. The analyzer only flags missing queue:prune-batches when it detects actual batch usage (Batchable trait on a job or a Bus::batch() call).

4. Schedule Telescope/Horizon cleanup:

php
Schedule::command('telescope:prune --hours=48')->daily();
Schedule::command('horizon:purge')->daily();

References