Engineering

If a fresh install does not work, nothing else you measure matters

20 July 2026 · 5 min read

The command that rebuilds the database from nothing is the one command every new machine runs first, and it is the one nobody runs again after the first month.

Every project can be rebuilt from an empty database on the day it starts. Most cannot a year later, and nobody notices, because everybody working on it has a database that was migrated forwards one step at a time.

It breaks quietly. A migration reads a column that a later migration renames. A seeder depends on a record that another seeder happens to create first. A model boots and queries a table that does not exist yet. None of that fails for anyone whose database already has the finished shape.

Where it costs you

The first new developer. The first CI job that builds from scratch. The first time you clone the project as the starting point for another one - which is when a broken fresh install stops being one project's problem and becomes every future project's problem.

Make it a test

Run the full rebuild in CI on every push:

php artisan migrate:fresh --seed

It is slower than running the migrations that changed. That is the point: the thing being tested is the whole sequence from zero, and a partial run tests the one path that already works.

The boot-time trap in particular

Watch for code that reads the database while the framework is booting - a service provider resolving a setting, a config value that comes from a table. migrate itself boots the framework, so on an empty database the table is created by a process that has already crashed trying to read it. Accept a closure and resolve it at render time instead.