Laravel fillAndInsert(): Fast Bulk Inserts with Eloquent Power
If you’ve ever handled bulk data insertion in Laravel, you probably faced a frustrating choice:
- Use
insert()for speed, but sacrifice Eloquent's rich features. - Or go with
create()/save()for casting, timestamps, and UUIDs—but at the cost of performance.
With Laravel 11+, that dilemma is finally over. Say hello to the new fillAndInsert() method. This feature allows you to insert multiple records efficiently without giving up the Eloquent magic you've come to rely on.
The Trade-Off: Speed vs. Features
In traditional Laravel development, choosing between performance and functionality during bulk insert was tough. The insert() method is blazing fast but skips model events, accessors, and casting. On the flip side, looping through and creating model instances gives you full control—but it's painfully slow with large datasets.
Get Developer Awam’s stories in your inbox
Join Medium for free to get updates from this writer.
The new fillAndInsert() method merges both worlds. You get:
- Attribute casting (including enums and JSON)
- Auto timestamps
- UUID generation via model events
All in one efficient operation.
Simple Example with Enum Casting
Let’s say you have a User model that casts the role attribute to an enum. You can now insert multiple users like this:
User::fillAndInsert([
[
'name' => 'Ayu',
'email' => 'ayu@example.com',
'role' => UserRole::Admin,
],
[
'name' => 'Dimas',
'email' => 'dimas@example.com',
'role' => 2, // Will be cast to enum
],
]);Laravel will automatically handle the enum casting and timestamps for you, just like if you were using create().
More Powerful When Models Get Complex
Here’s where fillAndInsert() really shines—models with UUIDs, decimals, JSON fields, and enums.
class Invoice extends Model
{
protected $fillable = ['number', 'amount', 'status', 'client_id', 'meta'];
protected function casts(): array
{
return [
'amount' => 'decimal:2',
'status' => InvoiceStatus::class,
'meta' => 'array',
'id' => 'string',
];
}
protected static function booted(): void
{
static::creating(function ($invoice) {
if (!$invoice->id) {
$invoice->id = (string) Str::uuid();
}
});
}
}Now, you can bulk insert invoices like this:
Invoice::fillAndInsert([
[
'number' => 'INV-001',
'amount' => '1200.50',
'status' => InvoiceStatus::Paid,
'meta' => ['method' => 'card', 'trx' => 'TRX001'],
],
[
'number' => 'INV-002',
'amount' => 880.90,
'status' => 'pending', // Will be cast to enum
'meta' => json_encode(['method' => 'bank', 'trx' => 'TRX002']),
],
[
'number' => 'INV-003',
'amount' => 645,
'status' => 1, // Integer will be cast to enum
'meta' => ['method' => 'paypal', 'trx' => 'TRX003'],
],
]);Laravel handles everything under the hood: the enum conversions, decimal precision, JSON decoding, and even auto-generating UUIDs — at scale.
Final Thoughts
fillAndInsert() is a major win for Laravel developers who deal with large data inserts. It gives you the best of both worlds: the speed of raw insertions and the consistency and safety of Eloquent models.
If you’re working on performance-heavy apps or just want cleaner, more maintainable code without sacrificing speed — it’s time to upgrade and start using fillAndInsert().










