Welcome to Laranepal - Nepal's Laravel Community!

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

Published on November 1, 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 yet

Be the first to share your thoughts or ask a question.

Join the conversation

Sign in to share your thoughts with the community.