Every time you save an Eloquent model, Laravel updates the updated_at column automatically. That’s the right behavior for most updates. But sometimes you’re making a change that isn’t a real content modification — incrementing a view counter, recording a heartbeat, fixing a background data field — and you don’t want updated_at touched. Laravel gives you four ways to prevent it.
:::note[TL;DR]
$model->timestamps = false; $model->save();— disables timestamps for that one save$model->saveQuietly()— skips timestamps AND model events (Laravel 8+)Model::withoutTimestamps(fn() => ...)— clean closure-based approach (Laravel 9+)- Query builder
Model::where()->update([])— never touches timestamps by design - All four work in Laravel 10, 11, and 12 :::
Why would I not want to update the timestamp?
Scenario: You’re incrementing a page view counter on every request. Each page load fires
$post->increment('views'), which touchesupdated_at. Now your admin dashboard sorts posts by “recently modified” and every popular post floats to the top — not because an editor changed something, but because it was viewed. None of those view counts represent real content changes. You don’t wantupdated_attouched.
Other common cases: syncing background metadata, recording soft diagnostic flags, running data migrations on legacy fields, or updating a last_seen_at column that has its own timestamp semantics already.
Method 1: Disable timestamps on the model instance
Set $model->timestamps = false before calling save(). This disables automatic timestamp management for that specific save operation only. It doesn’t affect other operations or other instances.
$user = User::find($id);
$user->timestamps = false; // disable just for this save
$user->profile_views += 1;
$user->save();
After save() completes, the instance still has timestamps set to false — so be careful if you reuse the same $user object for another save later in the same request. Re-enable it with $user->timestamps = true if needed.
Method 2: saveQuietly() — skip timestamps and events
saveQuietly() was added in Laravel 8. It saves the model without firing any Eloquent model events AND without updating timestamps. Use it when you want to be completely silent — no observers notified, no event listeners triggered, no timestamp changes.
$post->views += 1;
$post->saveQuietly();
This is the most aggressive option. No saving, saved, updating, or updated events fire. If you have listeners that send notifications or clear caches on model save, they won’t run here.
:::warning
Because saveQuietly() suppresses all model events, any side effects tied to those events — cache invalidation, audit logs, notification dispatches — will be silently skipped. Use it intentionally, not as a shortcut to avoid debugging an observer.
:::
Method 3: withoutTimestamps() — clean closure syntax
Model::withoutTimestamps() was added in Laravel 9. It accepts a closure, runs it with timestamps disabled, then restores the previous timestamp behavior. It’s cleaner than setting and unsetting $model->timestamps manually.
User::withoutTimestamps(function () use ($user) {
$user->update(['last_heartbeat_at' => now()]);
});
You can update multiple models inside the closure:
Post::withoutTimestamps(function () use ($posts) {
foreach ($posts as $post) {
$post->update(['cached_comment_count' => $post->comments()->count()]);
}
});
This is the recommended approach in Laravel 9, 10, 11, and 12 when you want readable, maintainable code.
Method 4: Use the query builder directly
The Eloquent query builder’s update() method never touches timestamps. It fires a direct SQL UPDATE query, bypassing the model layer entirely.
// Increment views directly — no timestamps touched, no model loaded
Post::where('id', $id)->update(['views' => DB::raw('views + 1')]);
This is also the most performant option for single-column updates — it doesn’t load the model into memory at all. The trade-off: no model events fire, and mass assignment protection doesn’t apply.
:::warning
Query builder update() does not fire Eloquent events and does not run through $fillable/$guarded checks. It also doesn’t cast attributes through your model’s $casts array. Use it for simple numeric updates or raw SQL expressions where you don’t need model-layer behavior.
:::
Comparing all four methods
| Method | Min Laravel | Saves timestamps? | Fires events? | Notes |
|---|---|---|---|---|
$model->timestamps = false | Any | No | Yes | Manual toggle; affects this instance |
saveQuietly() | Laravel 8+ | No | No | Suppresses all model events |
withoutTimestamps() | Laravel 9+ | No | Yes | Cleanest syntax; scoped to closure |
Query builder update() | Any | No | No | No model loaded; most performant |
Summary
- Four methods get the job done depending on how much of the model layer you want to bypass
$model->timestamps = falseis the simplest for one-off saves on an already-loaded modelsaveQuietly()silences everything — use it when you want zero side effectswithoutTimestamps()is the cleanest and most readable for Laravel 9+- The query builder
update()is best for performance-critical bulk updates where you don’t need the model instance
FAQ
Does withoutTimestamps() affect created_at too?
Yes. Both created_at and updated_at are skipped inside the closure. If you’re creating new records inside a withoutTimestamps() block, created_at won’t be set automatically either.
Does saveQuietly() also skip validation?
saveQuietly() skips model events. If your validation is done in a form request or controller (the normal place), it’s unaffected. If you have an observer that validates on the saving event, yes — that would be skipped.
What happens if my model has custom timestamp columns?
All four methods respect custom timestamp column names. If you’ve set const CREATED_AT = 'date_created', disabling timestamps still prevents that column from being updated. See how to change Laravel timestamp column names.
Can I permanently disable timestamps for a model?
Yes. Set public $timestamps = false; as a class property on the model. Eloquent will never manage timestamps for that model. Useful for pivot tables and lookup tables.
Is withoutTimestamps() available in Laravel 10, 11, and 12? Yes. It was introduced in Laravel 9 and is present in all subsequent versions.
What to Read Next
- Change Laravel Model Timestamp Column Names — rename
created_atandupdated_atto match your existing schema - Laravel firstOrCreate(): Find or Create a Record — save a record in one call without manual if/else
- Laravel firstOrNew(): Find or Prepare a Record — build and save a record with full control over the process