People searching “Laravel prune models” copy a scope onto User and then the schedule deletes accounts. Prune a table you can afford to lose, such as old invitations or expired exports. Put the command in routes/console.php. Something on the server has to call schedule:run every minute. The deploy guide is the release around that cron, not a replacement for it.
TL;DR
- MassPrunable deletes rows that match prunable().
- Schedule model:prune.
- Do not point that scope at users.
- Do not prune from a Vue button that calls this on
User.
The fix#
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\MassPrunable;
class Invitation extends Model
{
use MassPrunable;
public function prunable(): Builder
{
return static::where('created_at', '<=', now()->subDays(30));
}
}Schedule::command('model:prune')->daily();MassPrunable deletes in SQL and does not fire model events. Use Prunable when you need deleting. Run php artisan model:prune --pretend before you trust the scope.
What to avoid#
Gotcha
Do not prune from a Vue button that calls this on User. Do not write where('created_at', '>=', ...) and think you kept the old rows. That keeps the new ones and deletes the rest. Read the comparison twice.
FAQ#
How do I prune old rows on a schedule?
MassPrunable deletes rows that match prunable(). Schedule model:prune. Do not point that scope at users.
What goes wrong with Laravel prune models?
Many developers copy a scope onto User and then the schedule deletes accounts. Do not prune from a Vue button that calls this on User.



