Manage SEO and track how your site performs and appears in search engine results. 

X

🧹 Laravel Model Pruning In Laravel 12 — Automatically Clean Up Old Records

Published on November 2, 2025 by

🧹 Laravel Model Pruning in Laravel 12 — Automatically Clean Up Old Records

🧹 Laravel Model Pruning in Laravel 12 — Automatically Clean Up Old Records

Keeping your database lean and healthy is essential for performance and maintainability. Over time, tables fill up with old logs, expired sessions, or temporary uploads — data you don’t really need anymore.

Instead of writing custom cleanup scripts, Laravel gives you a simple, elegant solution: Model Pruning. Let’s explore how the Prunable and MassPrunable traits work in Laravel 12, with real-world examples and best practices.


🚀 What Is Model Pruning?

Model pruning is a built-in Laravel feature that automatically deletes old or unnecessary records from your database.

You simply:

  1. Add the Prunable or MassPrunable trait to your Eloquent model
  2. Define which records should be deleted
  3. Schedule the model:prune Artisan command to run periodically

Laravel takes care of the rest. 👌


🧩 Example 1: Auto-Delete Temporary Uploads After 7 Days

Imagine you have a table for temporary file uploads. You want to delete both the file and its record after 7 days.

app/Models/TemporaryUpload.php

namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Support\Facades\Storage;
 
final class TemporaryUpload extends Model
{
use Prunable;
 
public function prunable()
{
// Delete records older than 7 days
return static::where('created_at', '<=', now()->subDays(7));
}
 
// Called before deleting each record
protected function pruning(): void
{
if ($this->file_path) {
Storage::delete($this->file_path);
}
}
 
// Called after deletion (optional)
protected function pruned(): void
{
\Log::info("Pruned upload #{$this->id}");
}
}

Schedule the prune command

// routes/console.php
<?php
 
declare(strict_types=1);
 
use Illuminate\Support\Facades\Schedule;
 
Schedule::command('model:prune')->daily();

Done! Every day, Laravel will:

  • 🕓 Find uploads older than 7 days
  • 🗑️ Delete their files
  • 💾 Remove their database records

⚡ Example 2: Pruning Millions of Old Logs (Fast!)

If you’re cleaning up huge tables like activity_logs, you don’t want to delete records one by one. That’s where the MassPrunable trait comes in — it deletes in bulk.

app/Models/ActivityLog.php

namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\MassPrunable;
 
final class ActivityLog extends Model
{
use MassPrunable;
 
public function prunable()
{
return static::where('created_at', '<=', now()->subMonths(6));
}
}

💡 Tip: MassPrunable skips model events and callbacks — it’s faster, but you can’t hook into pruning() or deleted events.


🧠 Useful Artisan Commands

Dry-run first to check what will be deleted:

php artisan model:prune --pretend

Only prune specific models:

php artisan model:prune --model="App\\Models\\TemporaryUpload"

Exclude models from pruning:

php artisan model:prune --except="App\\Models\\User"

🧰 Common Use Cases

  • 🗂 Temporary uploads or previews – delete files after a few days
  • 📜 Activity / audit logs – keep only the last 6 months
  • 🕰 Soft-deleted models – permanently delete after 90 days
  • 💬 Notifications or tokens – clean expired entries
  • 📦 Large data archives – control database size over time

⚙️ Best Practices

  • 🔍 Test first using --pretend to confirm your query.
  • 🧑‍💻 Use Prunable if you need model events or file deletion hooks.
  • Use MassPrunable for very large datasets (no per-model callbacks).
  • 🧾 Log or monitor how many records get deleted each run.
  • 🧩 Combine with SoftDeletes for time-based permanent removal.
  • 🧠 Document your retention policy — know what data you’re deleting.
  • 🕐 Schedule during off-peak hours for heavy deletes.

✅ Summary

Laravel’s Model Pruning gives you a clean, framework-native way to handle old data — no custom cron scripts, no manual deletes.

You just:

  1. 🧩 Define your pruning rule
  2. 🕓 Schedule the command
  3. 🧹 Let Laravel keep your database clean automatically

It’s simple, powerful, and perfect for production-grade apps in Laravel 12.


💬 Have you used the Prunable trait yet? Share your favorite use-case or pruning strategy in the comments below!


Dinesh Uprety

Senior Software Engineer • Writer @ Laranepal • PHP, Laravel, Livewire, TailwindCSS & VueJS • CEO @ Laranepal & Founder @ laracodesnap

Filed in:

Discussion

Login or register to comment or ask questions

No comments or questions yet...

SPONSORED
MetaMagnet

Metamagnet

 Manage SEO and track how your site performs and appears in search engine results.