Over time your database tables can grow significantly, impacting performance and increasing storage costs. Laravel provides two pruning traits to help you clean up old records: Prunable and MassPrunable.
Prunable Trait
The Prunable trait loads each model before deleting it. This fires the deleting/deleted model events and calls the pruning() method, which is useful when you need to clean up related resources before deletion.
The prunable() method must return an Eloquent Builder query that selects which records should be deleted:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
class AuditLog extends Model
{
use Prunable;
/**
* Get the prunable model query.
*/
public function prunable(): Builder
{
return static::where('created_at', '<=', now()->subDays(90));
}
/**
* Prepare the model for pruning.
*/
protected function pruning(): void
{
// Clean up related resources before deletion
logger("Pruning audit log ID: {$this->id}");
}
}MassPrunable Trait
The MassPrunable trait is identical to Prunable, except it deletes records using a bulk DELETE query. This is much faster for large tables but skips the pruning() method and doesn't fire model events.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\MassPrunable;
class FailedJob extends Model
{
use MassPrunable;
/**
* Get the prunable model query.
*/
public function prunable(): Builder
{
return static::where('failed_at', '<=', now()->subDays(30));
}
}Running Pruning
Add the pruning command to your scheduler:
$schedule->command('model:prune')->daily();Or call it manually:
php artisan model:prune --model=AuditLogTips
-
Test your pruning queries first - Run this to see how many records will be deleted:
AuditLog::where('created_at', '<=', now()->subDays(90))->count(); -
Consider soft deletes - If you're using soft deletes, soft deleted records matching the prunable query will also be permanently deleted.
-
Choose the right trait - Use Prunable when you need to run cleanup logic via events. Use MassPrunable for better performance on large tables.
Pruning is essential for maintaining database performance, especially for tables that accumulate logs, analytics, or historical data.