In Laravel, is there a way to find out whether `firstOrCreate` created or if it found the row?

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

The Ambiguity of firstOrCreate: Differentiating Creation from Retrieval in Laravel Eloquent

In the world of database interactions, especially within an Object-Relational Mapper (ORM) like Laravel’s Eloquent, developers often seek methods that handle common scenarios efficiently. One such method is firstOrCreate(), designed to simplify the process of either creating a new record if it doesn't exist or retrieving the existing one if it does.

However, this convenience introduces a subtle ambiguity: In Laravel, is there a way to find out whether firstOrCreate created the row or if it simply found an existing one?

This question touches upon the core difference between an operation that modifies the database and an operation that merely queries it. As a senior developer, understanding this nuance is crucial for writing robust, predictable application logic.

The Nature of firstOrCreate

The short answer is that no, firstOrCreate() itself does not return a simple boolean flag indicating whether a creation or an update occurred. It is designed to return the resulting Eloquent model instance—either the newly created record or the existing one that matched the criteria.

When you execute:

php
$user = User::firstOrCreate(['email' => 'test@example.com'], ['name' => 'New User']);

The variable $user will contain an instance of the User model, regardless of whether a database INSERT or a SELECT occurred on that specific operation cycle. The method prioritizes returning the desired object over providing a detailed transactional status.

If your goal is to conditionally execute logic based on the type of database action performed (create vs. find), you must employ alternative strategies that leverage the state before and after the operation, or use slightly different Eloquent methods.

Strategies for Differentiating Actions

Since firstOrCreate prioritizes convenience over explicit status reporting, we need to implement external logic to capture the outcome. Here are the most effective developer-centric approaches:

1. The Pre-Check Method (Explicit and Reliable)

The safest and most explicit way to determine if a creation actually happened is to check for existence before attempting the creation. This approach forces you to manage the conditional logic yourself, making the flow crystal clear to future developers.

php
$attributes = ['email' => 'test@example.com', 'name' => 'New User'];

// 1. Check if the record exists first
$user = User::where('email', $attributes['email'])->first();

if ($user) {
    // Record found: Perform an update or simply use the existing record
    $user->name = $attributes['name']; // Example update
    $user->save();
    echo "Record found and updated.";
} else {
    // Record not found: Perform a creation
    $user = new User($attributes);
    $user->save();
    echo "New record created.";
}

This method, while slightly more verbose than a single function call, provides absolute certainty about the database state and is highly readable. This level of control over data flow is exactly what separates simple scripting from enterprise-grade Laravel applications, echoing the principles of clean design found in high-quality packages like those on laravelcompany.com.

2. Using updateOrCreate for Status Insight

If your primary goal is to ensure that you are either creating a record or updating it based on a specific condition, consider using updateOrCreate() instead. While it still doesn't return a simple "created/found" boolean, the underlying operation is inherently an update-or-insert command, which can sometimes be leveraged in more complex transaction flows to infer intent.

php
$result = User::updateOrCreate(
    ['email' => 'test@example.com'], // Conditions to match
    ['name' => 'New User', 'status' => 'active'] // Values to set/update
);

// While $result is the model, you know this operation was an atomic attempt 
// to satisfy both conditions simultaneously.
echo "Operation completed for user.";

Conclusion

firstOrCreate() is a fantastic tool for boilerplate reduction, saving valuable development time by combining two database operations into one fluent call. However, when application logic demands knowing the exact nature of the operation (creation vs. retrieval), relying solely on the return value is insufficient.

For robust systems, always default to explicit checks, such as checking existence first using where()->first(), especially when transactional integrity or clear logging of data changes is paramount. Master these subtle differences in Eloquent, and you move from simply writing code to architecting reliable software.