What is Laravel Prunable Trait?
The Laravel Prunable trait helps you automatically delete old data from your database. Think of it like a janitor that cleans up your database while you sleep!
Instead of manually deleting old records, Laravel does it for you based on rules you set.
Why Use Laravel Prunable Trait?
- Keep your database fast — Less data means faster queries
- Save storage space — Remove unnecessary old records
- Follow data privacy laws — Automatically delete personal data
- No manual work — Set it once, forget about it
Tips to Master Laravel Prunable Trait
Tip 1: Basic Setup (Start Here!)
First, add the Prunable trait to any model where you want automatic cleanup:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
class ActivityLog extends Model
{
use Prunable;
protected $fillable = ['user_id', 'action', 'created_at'];
// Delete logs older than 30 days
public function prunable()
{
return static::where('created_at', '<=', now()->subDays(30));
}
}
What this does: Automatically delete activity logs that are older than 30 days.
Tip 2: Run the Cleanup Command
After setting up your model, run this command to clean your database:
# Clean all models with Prunable trait
php artisan model:prune
# See what would be deleted (without actually deleting)
php artisan model:prune --pretend
Pro tip: Always use --pretend first to see what will be deleted!
Tip 3: Schedule Automatic Cleanup (Laravel 11+ Way)
In Laravel 11+, create a scheduled task in routes/console.php:
<?php
use Illuminate\Support\Facades\Schedule;
// Clean up every day at 2 AM
Schedule::command('model:prune')->daily()->at('02:00');
// Clean up during off-peak hours only
Schedule::command('model:prune')
->daily()
->at('03:00')
->when(function () {
// Only run on weekdays
return now()->isWeekday();
});
Why 2–3 AM? Most websites have low traffic during these hours.
Tip 4: Smart Conditions for Better Control
You can combine multiple conditions for smarter cleanup:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
class OrderLog extends Model
{
use Prunable;
protected $fillable = ['order_id', 'status', 'created_at'];
public function prunable()
{
return static::where(function ($query) {
// Delete completed orders older than 6 months
$query->where('status', 'completed')
->where('created_at', '<=', now()->subMonths(6));
})->orWhere(function ($query) {
// Delete failed orders older than 30 days
$query->where('status', 'failed')
->where('created_at', '<=', now()->subDays(30));
});
}
}
Smart logic: Different rules for different types of records.
Tip 5: Handle Large Tables with MassPrunable
If your table has thousands of records, use MassPrunable for better performance:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\MassPrunable; // Notice: MassPrunable, not Prunable
class BigDataTable extends Model
{
use MassPrunable;
// Same prunable() method
public function prunable()
{
return static::where('created_at', '<=', now()->subYear());
}
}
When to use MassPrunable:
- Tables with more than 10,000 records
- When you don’t need the
pruning()method - When speed is more important than individual record processing
Tip 06: Add Database Indexes for Speed
Add indexes to columns you use in pruning conditions:
// In your migration file
Schema::table('activity_logs', function (Blueprint $table) {
$table->index('created_at'); // Speed up pruning queries
});
Schema::table('notifications', function (Blueprint $table) {
$table->index(['read_at', 'created_at']); // Multiple columns
});
Why this matters: Indexes make your pruning 10x faster on large tables.
Tip 07: Monitor Your Pruning
Keep track of what’s being deleted:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
class MonitoredModel extends Model
{
use Prunable;
public function prunable()
{
return static::where('created_at', '<=', now()->subDays(30));
}
protected function pruning()
{
// Log what's being deleted
Log::info('Pruning record', [
'model' => self::class,
'id' => $this->id,
'created_at' => $this->created_at
]);
}
}
Check your logs to make sure pruning is working as expected.
Quick Setup Checklist
✅ Step 1: Add use Prunable; to your model
✅ Step 2: Add prunable() method with your cleanup rules
✅ Step 3: Test with php artisan model:prune --pretend
✅ Step 4: Run actual cleanup with php artisan model:prune
✅ Step 5: Schedule automatic cleanup in routes/console.php
✅ Step 6: Add database indexes for better performance
Troubleshooting Common Issues
Problem: Pruning is too slow
Solution: Add database indexes or use MassPrunable
Problem: Too many records deleted
Solution: Test your conditions with --pretend first
Problem: Files not deleted
Solution: Use the pruning() method for file cleanup
Problem: Nothing gets deleted
Solution: Check your prunable() method conditions
Conclusion
The Laravel Prunable trait is like having a smart assistant that keeps your database clean automatically. With these 12 simple tips, you can:
- Set up automatic cleanup in minutes
- Keep your database fast and lean
- Follow privacy laws automatically
- Never worry about manual data cleanup again
Start with one model, test it thoroughly, then expand to other models. Your future self (and your users) will thank you for a faster, cleaner application!
If you found this helpful, feel free to share or drop a comment. Happy coding with Laravel! 🧱✨
Free resources for this topic
Code snippets and fixes for this topic
Get one practical tip every week
New tutorials, fixes and free cheat sheets from DEV Talk, straight to your inbox. No spam, unsubscribe in one click.
Free download: Laravel interview questions (PDF)
Have a question about this post?
Ask the community: other developers and the author can answer.
Get notified about new articles
One click, no email needed. Turn it off anytime with the bell at the top.
Get new articles on your iPhone
Add DEV Talk to your Home Screen, open it, then tap the bell.
Enjoying the content?
If this article helped you, you can support the author with a coffee. It keeps new posts coming.
Comments 0
No comments yet
Be the first to share your thoughts.