Reader Stacks

How to Get the Last Insert ID in Laravel

Eloquent's create() already returns the new model with its ID populated — reaching for a separate lastInsertId() call is really only needed with the raw query builder, not Eloquent.

Getting the ID of a just-inserted row is something Eloquent already handles automatically — reaching for a separate "last insert ID" call is really only necessary when working with the raw query builder or raw SQL directly.

The Eloquent way (usually all that's needed)

$product = Product::create([
    'name' => 'Wireless Mouse',
    'price' => 29.99,
]);

echo $product->id; // the new row's auto-incremented ID, already populated

create() returns the fully populated model instance, including its new primary key — there's no separate step needed to retrieve the ID afterward, since Eloquent already fetches it as part of the insert operation.

Using the query builder instead of Eloquent

$id = DB::table('products')->insertGetId([
    'name' => 'Wireless Mouse',
    'price' => 29.99,
]);

echo $id;

insertGetId() is the query builder's equivalent — necessary here because the plain query builder's regular insert() method returns only a boolean success indicator, not the new row's ID, unlike Eloquent's create().

Getting the last insert ID after a raw insert statement

DB::insert('insert into products (name, price) values (?, ?)', ['Wireless Mouse', 29.99]);

$id = DB::getPdo()->lastInsertId();

This lowest-level approach, calling lastInsertId() directly on the underlying PDO connection, is rarely needed in a typical Laravel application — it exists mainly for the edge case of a fully raw SQL insert where neither Eloquent nor the query builder's own insert methods are being used.

A gotcha: lastInsertId() isn't reliable after a multi-row insert

DB::table('products')->insert([
    ['name' => 'Mouse', 'price' => 20],
    ['name' => 'Keyboard', 'price' => 50],
]);
// There's no reliable way to get "the" last insert ID here — multiple rows were inserted

Both insertGetId() and lastInsertId() are meaningful only for a single-row insert — inserting multiple rows in one call doesn't have a well-defined "last" ID to retrieve for each individual row, so a loop calling create() or insertGetId() once per row is the correct approach when the ID of every inserted row is actually needed.

Using the new ID immediately for a related insert

$order = Order::create(['customer_id' => $customerId, 'total' => 150]);

OrderItem::create([
    'order_id' => $order->id,
    'product_id' => $productId,
    'quantity' => 2,
]);

This is the most common real-world reason to need the newly inserted ID at all — using it immediately to create a related record, which Eloquent's automatic ID population (via create()) handles cleanly without any extra retrieval step.