To seed a Laravel 13 database, create a seeder with php artisan make:seeder, fill it using model factories, call it from DatabaseSeeder, and run php artisan db:seed. Factories generate realistic fake rows, and seeders decide which rows to create and in what order.
This tutorial covers factories, seeders, relationships, running seeders safely, and the mistakes that cause duplicate or missing data.
What is the difference between a seeder and a factory?
A factory describes how to build one fake model, for example a user with a random name and email. A seeder is a class with a run() method that decides how many models to create. Seeders usually call factories, but they can also insert fixed rows such as an admin account or a list of countries.
What do I need before I start?
- Laravel 13 (current stable at the time of writing) with a supported PHP version.
- A migrated database, using SQLite, MySQL or PostgreSQL.
- The
Usermodel, which already ships with a factory.
Mass assignment protection is automatically disabled while seeding, so you do not need $fillable entries for seeded columns.
How do I create a factory?
php artisan make:factory PostFactory --model=Post<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'title' => fake()->sentence(6),
'body' => fake()->paragraphs(3, true),
'published_at' => fake()->optional(0.7)->dateTimeBetween('-1 year'),
];
}
public function published(): static
{
return $this->state(fn () => ['published_at' => now()]);
}
public function draft(): static
{
return $this->state(fn () => ['published_at' => null]);
}
}Using User::factory() for user_id means that creating a post also creates its owner, unless you pass an existing user. The state methods published() and draft() let tests and seeders ask for a specific kind of row.
The model also needs the HasFactory trait. New models created with make:model include it by default.
How do I write a seeder?
php artisan make:seeder PostSeeder<?php
namespace Database\Seeders;
use App\Models\Post;
use App\Models\User;
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
public function run(): void
{
$authors = User::factory()->count(5)->create();
foreach ($authors as $author) {
Post::factory()
->count(4)
->for($author)
->create();
}
Post::factory()->count(3)->draft()->create();
}
}The for($author) method attaches each batch of posts to an existing user. Laravel also supports relationship helpers such as User::factory()->hasPosts(3) when the matching relationship method exists on the model.
How do I register and run seeders?
Call your seeders from DatabaseSeeder. The order of the array is the order of execution, so seed parents before children.
public function run(): void
{
$this->call([
UserSeeder::class,
PostSeeder::class,
]);
}php artisan db:seed
php artisan db:seed --class=PostSeeder
php artisan migrate:fresh --seedmigrate:fresh --seed drops every table, runs all migrations, then seeds. Use it only on a local or test database.
How do I seed fixed data such as an admin user?
use Illuminate\Support\Facades\Hash;
User::updateOrCreate(
['email' => 'admin@example.com'],
['name' => 'Admin', 'password' => Hash::make('change-me-locally')]
);Using updateOrCreate keeps the seeder safe to run more than once, because it looks the row up by email first. Never ship a real default password to production. Read credentials from environment variables or create the first admin another way.
How do I stop model events firing during seeding?
Add the WithoutModelEvents trait to DatabaseSeeder. No observer or model event runs during the seed, even in seeders loaded with call(). That avoids sending emails or dispatching jobs for fake rows.
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
class DatabaseSeeder extends Seeder
{
use WithoutModelEvents;
// ...
}What happens in production?
When the app runs in the production environment, db:seed asks for confirmation. The --force flag skips that prompt. Use it only for seeders that are safe to repeat, such as lookup tables written with updateOrCreate.
What are the common mistakes?
- Seeding children before parents. Foreign key errors appear. Fix the order in
call(). - Duplicate unique values. Fixed emails inserted with
create()fail on the second run. UseupdateOrCreate. - Huge counts. Creating 100,000 models one by one is slow. Create in chunks or use
insert()with factorymake()->toArray()output. - Missing factory. The error "Call to undefined method factory()" means the model lacks
HasFactory.
How can I check the result?
php artisan tinker
>>> App\Models\Post::count();
>>> App\Models\Post::whereNull('published_at')->count();You can also run php artisan db:show --counts to see row counts for every table.
FAQ
Can I use factories in tests?
Yes. The same factories work in feature tests, usually together with the RefreshDatabase trait.
How do I make fake data repeatable?
Call fake()->seed(1234) at the start of a seeder. The same seed then produces the same values.
Should I commit seeders to Git?
Yes. Seeders are code. Commit them, but keep real secrets out of them.



