firstOrNew() is a Laravel Eloquent method that finds the first record matching a set of attributes, or — if nothing matches — returns a new unsaved model instance with those attributes pre-filled. Available in Laravel 10, 11, and 12, the key detail is that it does not save. You get the model back and decide what to do with it before calling ->save() yourself.
:::note[TL;DR]
Model::firstOrNew($attributes, $values)finds a match or returns a new, unsaved model instance- Does NOT save to the database — you must call
->save()manually - Check
$model->existsto know if the record already existed or was freshly built - Use over
firstOrCreate()when you need to modify the instance before saving - Second argument fills extra fields on the new instance but isn’t used for searching :::
What is the syntax for firstOrNew()?
The method signature matches firstOrCreate() exactly. The difference is entirely in behavior after the lookup.
Model::firstOrNew(array $attributes, array $values = [])
The $attributes array is the search criteria. If no matching record exists, Laravel builds a new model instance with $attributes and $values merged in — but doesn’t run an INSERT query. You hold an unsaved model. Call ->save() when you’re ready to persist it.
How does firstOrNew() work in practice?
Scenario: You’re building a CSV import tool. Each row represents a product. You call
firstOrNew()for each row, check if it’s a brand new product ($model->existsis false), and if so, call an external pricing API to enrich it with market data before saving. WithfirstOrCreate(), there’s no step between “find or create” and “saved” — you can’t intercept it.firstOrNew()gives you that gap.
Without firstOrNew(), the manual pattern looks like this:
$email = $request->input('email');
$user = User::where('email', $email)->first();
if ($user === null) {
$user = new User(['email' => $email]);
}
$user->username = $request->input('username');
$user->save();
With firstOrNew(), it’s more concise — and the pattern is clearer:
$user = User::firstOrNew(
['email' => $request->input('email')],
['username' => $request->input('username')]
);
// $user->exists is false if this is a new record
$user->save();
The email is searched. username is set only when a new instance is being built. If an existing user is found, username from the second argument is ignored entirely.
How do I know if the model was found or just built?
Check $model->exists. It’s true if the record already existed in the database and false if firstOrNew() built a fresh instance.
This is what makes firstOrNew() genuinely useful for conditional logic:
$product = Product::firstOrNew(['sku' => $row['sku']], [
'name' => $row['name'],
'price' => $row['price'],
]);
if (!$product->exists) {
// This is a new product — fetch extra data before saving
$product->description = $this->fetchDescriptionFromApi($product->sku);
$product->category_id = $this->resolveCategoryId($row['category']);
}
$product->save();
You can’t do this with firstOrCreate() — by the time it returns, the record is already in the database.
What is the difference between firstOrNew() and firstOrCreate()?
| Method | Saves to DB? | Use when… |
|---|---|---|
firstOrNew() | No — manual ->save() | You need to modify the instance before persisting |
firstOrCreate() | Yes, immediately | You want a guaranteed-saved record with no extra steps |
Both methods accept the same two arguments. Both return a model instance. The only functional difference is whether a new record gets inserted automatically.
If you don’t need to touch the model between “find or build” and “save”, use firstOrCreate() — it’s one less line and clearer intent.
Can I use firstOrNew() and then conditionally skip saving?
Yes. Because you control when ->save() is called, you can add conditions:
$subscription = Subscription::firstOrNew(['user_id' => $user->id]);
if ($subscription->exists) {
// Already subscribed — don't overwrite anything
return $subscription;
}
$subscription->plan = 'free';
$subscription->trial_ends_at = now()->addDays(14);
$subscription->save();
This is cleaner than a where()->first() followed by a conditional new Model() block.
:::warning
Don’t call ->save() inside a loop without thinking about transaction boundaries. If you’re importing 500 rows and something fails at row 300, your database ends up half-populated. Wrap bulk firstOrNew + save operations in DB::transaction() when data consistency matters.
:::
Summary
firstOrNew($attributes, $values)finds a matching record or builds a new unsaved instance- It never saves automatically — always call
->save()when you’re ready $model->existsis your signal:truemeans found,falsemeans newly built- Use
firstOrCreate()when you don’t need to modify the model before saving - Wrap bulk operations in a database transaction to avoid partial inserts
FAQ
Does firstOrNew() fire model events?
No events fire during firstOrNew() itself. Events fire normally when you call ->save() — creating/created for new records, updating/updated for existing ones.
Can I call firstOrNew() with just one argument?
Yes. The second argument is optional. User::firstOrNew(['email' => $email]) is valid — you just won’t have any default values populated on the new instance beyond the search attributes.
What if I call save() on an existing record returned by firstOrNew()?
It runs an UPDATE query. The exists property is true, so Eloquent knows to update rather than insert.
Is firstOrNew() available in Laravel 10, 11, and 12? Yes. It’s been part of Eloquent for many major versions, unchanged in 10, 11, and 12.
How is firstOrNew() different from new Model($attributes)?
new Model() always creates a fresh unsaved instance regardless. firstOrNew() checks the database first and only builds a new instance when nothing matches.
What to Read Next
- Laravel firstOrCreate(): Find or Create a Record — the auto-saving variant for when you don’t need to modify before persisting
- Update a Laravel Record Without Touching Timestamps — control over what changes when you save
- Get an Array of IDs from an Eloquent Collection — a quick Collection utility worth knowing