Using a Progress Bar while Seeding a database in Laravel

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Progress: Using Progress Bars While Seeding Data in Laravel

As senior developers, we often deal with tasks that take significant time, such as large-scale database seeding. When running these processes via Artisan commands, providing feedback to the user about the progress is crucial for a good experience. You are right to look into integrating console helpers like the progress bar functionality available through Symfony components.

While the documentation points to using progressbar helpers, integrating them seamlessly into a Laravel Seeder requires understanding the context of how Artisan handles output streams. Let’s dive into why your attempts might be failing and how to implement a robust progress indicator for your data seeding tasks.

The Challenge: Console Output in Seeder Context

The difficulty often lies not in the progress bar logic itself, but in correctly accessing and manipulating the console output stream within the scope of an Eloquent Seeder. A Seeder runs inside an Artisan command execution, meaning we need to interact with the underlying Symfony Console component's output handler rather than standard PHP output functions.

The methods you referenced (createProgressBar, advance, finish) are part of the low-level console helpers provided by Symfony. To use them effectively in a Laravel Seeder, you must access the $this->output object correctly.

The Solution: Implementing Progress Bars in Seeders

To successfully implement a progress bar during seeding, we need to leverage methods available on the Illuminate\Console\Command context, which is implicitly available within a Seeder class when executed via Artisan.

Here is a corrected and idiomatic way to structure your seeder to display a progress bar for iterating over data insertion:

Example Implementation

We will use the standard pattern of initializing the progress bar and then advancing it inside our loop.

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class SubDivisionRangeSeeder extends Seeder
{
    /**
     * Run the database seeding.
     *
     * @return void
     */
    public function run()
    {
        $totalItems = 1000; // Example: Total records to insert
        $progress = $this->output->createProgressBar($totalItems);

        for ($i = 0; $i < $totalItems; $i++) {
            // Simulate a time-consuming database operation
            sleep(0.01); 
            
            // Advance the progress bar by one step
            $progress->advance();
        }

        // Important: Finish the bar when done
        $progress->finish();

        $this->output->writeln("\nDatabase seeding complete!");
    }
}

Explanation of Best Practices

  1. Accessing Output: The key is using $this->output. In a Seeder, this property provides access to the underlying console stream, allowing you to invoke Symfony's helper methods. This ties directly into how Laravel structures its command-line interaction, which is foundational to building robust command-line tools, much like those we see in modern framework development at laravelcompany.com.
  2. Initialization: First, initialize the progress bar using $this->output->createProgressBar($total). This tells the console what the total scope of the operation is.
  3. Iteration Control: Inside your loop, after every unit of work (e.g., inserting a batch or processing an item), call $progress->advance(). This signals to the console that progress has been made.
  4. Finalization: Crucially, always call $progress->finish() once the loop is complete. This ensures the progress bar closes properly and the user sees a clear completion message.

Advanced Considerations

While the above method works perfectly for simple iteration, large-scale seeding often involves bulk operations using Eloquent's insert methods or database query builders. If your operation involves inserting many records at once rather than one-by-one, you can adjust how you track progress:

Instead of tracking individual record insertions, calculate the percentage based on the total number of batches or operations completed. For instance, if you are seeding 10 large batches, you could use a separate counter for those batches to drive the progress bar, giving a more meaningful indicator of overall seeding completion rather than per-row progress.

Conclusion

Implementing progress bars in Laravel seeders is entirely achievable by correctly interfacing with the underlying console output mechanism provided by Symfony components. By understanding that $this->output is your gateway to these helpers, you can transform slow, tedious database seeding into an engaging and informative process for your users. Keep focusing on how frameworks like Laravel manage their command-line interaction; mastering this layer of abstraction is what separates functional code from excellent developer experience.