# How to Ensure the Laravel Migrate Command Detects and Applies New Migrations

> Ensure laravel migrate command detects new migrations by understanding its scanning process in the database migrations directory and how it checks the migrations table.

- Repository: [Laravel/framework](https://github.com/laravel/framework)
- Tags: how-to-guide
- Published: 2026-02-16

---

**The Laravel migrate command discovers new migration files by scanning timestamp-prefixed PHP files in the `database/migrations` directory (or custom paths specified via `--path`), comparing them against the `migrations` table, and executing only those not yet recorded.**

When working with the `laravel/framework` repository, understanding how the migration discovery chain operates ensures that every new schema change you create is properly recognized and executed. The system relies on a specific set of conventions for file naming, directory structure, and autoloading coordination to determine which migrations are pending.

## How Laravel Migration Discovery Works

The `php artisan migrate` command delegates file discovery to a series of interconnected classes within the `Illuminate\Database` namespace. Understanding this pipeline helps diagnose why a migration might be skipped.

### Step 1: Defining Migration Paths via BaseCommand

The entry point for path resolution is `BaseCommand::getMigrationPaths()`, located in [`src/Illuminate/Database/Console/Migrations/BaseCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Console/Migrations/BaseCommand.php). This method returns the default `database/migrations` directory merged with any additional paths supplied via the `--path` option.

```php
// From BaseCommand.php (lines 15-31)
protected function getMigrationPaths()
{
    // Default path plus any --path arguments
    return array_merge(
        [$this->getMigrationPath()],
        $this->option('path') ?: []
    );
}

```

### Step 2: File Naming Conventions and Sorting

Once paths are resolved, the `Migrator::getMigrationFiles()` method scans these directories for PHP files. Laravel strictly requires that migration filenames begin with a timestamp in the format `YYYY_MM_DD_HHMMSS`. This prefix ensures deterministic ordering when the `Migrator` sorts the file list alphabetically before execution.

For example, [`2024_02_16_000001_create_posts_table.php`](https://github.com/laravel/framework/blob/main/2024_02_16_000001_create_posts_table.php) is valid, while [`create_posts_table.php`](https://github.com/laravel/framework/blob/main/create_posts_table.php) will be ignored by the scanner.

### Step 3: Comparing Against the Migration Repository

The `MigrateCommand` (in [`src/Illuminate/Database/Console/Migrations/MigrateCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Console/Migrations/MigrateCommand.php)) initializes the `Migrator` and calls `run()` with the discovered paths. Inside `Migrator::run()`, the system compares the sorted filenames against records in the `migrations` table. Only files whose names do not appear in this table are considered "pending" and are subsequently executed.

```php
// Conceptual flow in MigrateCommand.php (lines 14-20)
$this->migrator->run($this->getMigrationPaths(), [
    'pretend' => $this->option('pretend'),
    'step' => $this->option('step'),
]);

```

### Step 4: Autoloading and Class Resolution

After a migration is created using `make:migration`, the `MigrateMakeCommand` (in [`src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php)) ensures the new class is discoverable. While the framework handles autoloading automatically in most cases, the class map may need refreshing if the migration class cannot be found. This is typically handled by running `composer dump-autoload` if you encounter autoloading errors.

## Practical Implementation: Ensuring Migrations Are Detected

Follow these concrete steps to guarantee the `laravel migrate` command recognizes your new schema files.

### Creating a Migration in the Default Location

Use the Artisan command to generate properly timestamped files:

```bash
php artisan make:migration create_posts_table --create=posts

```

This creates a file like [`2024_02_16_000001_create_posts_table.php`](https://github.com/laravel/framework/blob/main/2024_02_16_000001_create_posts_table.php) in `database/migrations/`, which will be automatically detected on the next `migrate` run.

### Using Custom Migration Directories

For modular applications or packages, specify a custom path during creation:

```bash
php artisan make:migration add_status_to_orders --table=orders --path=custom/migrations

```

Then run the migrate command with the corresponding path option:

```bash
php artisan migrate --path=custom/migrations

```

### Verifying Detected Migrations

Before running migrations, verify which files the system recognizes using the status command:

```bash
php artisan migrate:status

```

This outputs a table showing all migrations found in the scanned paths and whether they have been executed (indicated by a "Y" or "N" in the "Ran?" column).

### Refreshing the Autoloader (When Needed)

If you manually copy migration files into the directory without using `make:migration`, or if you encounter "Class not found" errors, refresh the autoloader:

```bash
composer dump-autoload
php artisan migrate

```

## Troubleshooting: Why the Laravel Migrate Command Might Skip Files

If your migration is not being applied, check these common causes:

- **Missing timestamp prefix**: Files must start with `YYYY_MM_DD_HHMMSS`. [`create_users_table.php`](https://github.com/laravel/framework/blob/main/create_users_table.php) will be ignored; [`2024_02_16_000001_create_users_table.php`](https://github.com/laravel/framework/blob/main/2024_02_16_000001_create_users_table.php) will be processed.
- **Incorrect directory**: The file must reside in `database/migrations` or a path explicitly added via `--path`. Typos in directory names are a frequent cause of "migration not found" issues.
- **Already executed**: If the filename exists in the `migrations` table, Laravel considers it complete. Use `php artisan migrate:rollback` or manually remove the entry from the database only if you are certain the migration was not fully applied.
- **Autoloading issues**: If the class cannot be instantiated, ensure `composer dump-autoload` has been run, especially after manually copying files.

## Key Source Files in the Migration System

Understanding these core files in the `laravel/framework` repository clarifies how the discovery mechanism operates:

| File | Role in Migration Discovery |
|------|----------------------------|
| [`src/Illuminate/Database/Console/Migrations/BaseCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Console/Migrations/BaseCommand.php) | Defines `getMigrationPaths()`, which resolves the default `database/migrations` directory and merges custom `--path` arguments. |
| [`src/Illuminate/Database/Console/Migrations/MigrateCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Console/Migrations/MigrateCommand.php) | Entry point for `php artisan migrate`; initializes the `Migrator` and passes resolved paths to `run()`. |
| [`src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php) | Handles `make:migration`; ensures files are created with proper timestamp prefixes and triggers autoloading updates. |
| [`src/Illuminate/Database/Migrations/Migrator.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Database/Migrations/Migrator.php) | Core engine that scans paths via `getMigrationFiles()`, compares filenames against the `migrations` table, and executes pending migrations. |

## Summary

- The **laravel migrate command** discovers files by scanning timestamp-prefixed PHP files in `database/migrations` (or custom paths specified with `--path`).
- **File naming is critical**: Only files matching the `YYYY_MM_DD_HHMMSS_*` pattern are recognized and sorted for execution.
- The system compares discovered filenames against the `migrations` database table to determine which migrations are pending.
- **Autoloading coordination** via `composer dump-autoload` ensures migration classes are discoverable, particularly when files are manually added.

## Frequently Asked Questions

### Why isn't my new migration being picked up by `php artisan migrate`?

The most common reason is a **missing or incorrect timestamp prefix** in the filename. Laravel requires the format [`YYYY_MM_DD_HHMMSS_description.php`](https://github.com/laravel/framework/blob/main/YYYY_MM_DD_HHMMSS_description.php) (e.g., [`2024_02_16_000001_create_users_table.php`](https://github.com/laravel/framework/blob/main/2024_02_16_000001_create_users_table.php)). Files without this prefix are ignored by the `Migrator::getMigrationFiles()` scanner. Additionally, verify the file resides in `database/migrations` or a directory explicitly included via the `--path` option.

### Can I store migrations in multiple directories?

Yes. While Laravel defaults to `database/migrations`, you can organize migrations in subdirectories or external package directories. When running migrations, use the `--path` option to specify additional locations: `php artisan migrate --path=database/migrations/tenant --path=vendor/package/migrations`. The `BaseCommand::getMigrationPaths()` method merges these custom paths with the default directory before scanning begins.

### How does Laravel determine the order of migration execution?

Laravel sorts migration files **alphabetically by filename**, which is why the timestamp prefix is essential. When `Migrator::getMigrationFiles()` retrieves the list of files from the resolved paths, it performs a standard alphabetical sort. This ensures that [`2024_01_01_000000_create_users.php`](https://github.com/laravel/framework/blob/main/2024_01_01_000000_create_users.php) executes before [`2024_01_02_000000_create_posts.php`](https://github.com/laravel/framework/blob/main/2024_01_02_000000_create_posts.php), maintaining a chronological schema history regardless of when the files were physically created on disk.

### Do I need to run `composer dump-autoload` after creating a migration?

Usually **no**. When you use `php artisan make:migration`, the `MigrateMakeCommand` automatically handles the necessary setup to ensure the new class is discoverable. However, if you manually copy a migration file into the directory without using the Artisan command, or if you encounter a "Class not found" error when running migrations, you should execute `composer dump-autoload` to refresh the autoloader class map before retrying `php artisan migrate`.