Versioning Spring Boot Databases with Flyway
Use Flyway's Spring Boot starter to apply versioned SQL migrations on startup and keep schema in sync across environments.
23 Feb 2026, 01:02 UTC

The problem: schema drift between environments
Your Spring Boot application starts cleanly on your laptop. In staging, it fails because a teammate added a column manually to the database. In production, a deployment succeeds but queries break because a table is missing. The root cause is usually the same: the database schema is not versioned alongside the application code, so environments quietly diverge.
The useful takeaway is that Flyway's Spring Boot starter can apply versioned SQL migrations automatically when the application starts, recording each change in a history table so every environment moves through the same schema states.
How Flyway integrates with Spring Boot startup
Flyway is a database migration tool. In Spring Boot, the spring-boot-starter-jdbc or spring-boot-starter-data-jpa dependency combined with the Flyway starter enables auto-configuration. On startup, Spring Boot reads the configured DataSource, scans the migration locations, and applies any pending scripts in order before the application accepts requests.
Each migration is a SQL file named with a version prefix, such as V1__create_users.sql. Flyway tracks applied scripts in a table named flyway_schema_history. If a script has already run, Flyway skips it. If a script's checksum changes after it has been applied, Flyway refuses to start, which prevents silent schema corruption.
Worked example: two migrations and application properties
Add the Flyway dependency to your build. For Maven:
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
Create the migration directory src/main/resources/db/migration and add versioned SQL files.
-- V1__create_users.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE
);
-- V2__add_email_column.sql
ALTER TABLE users ADD COLUMN email VARCHAR(255);
Configure the data source and migration locations in src/main/resources/application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=app_user
spring.datasource.password=change-me
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=true
Run the application from the project root:
./mvnw spring-boot:run
Required permissions: the database user needs CREATE, ALTER, DROP, and INSERT on the target schema so Flyway can create the history table and apply migrations. Risk: if spring.datasource.url points to a shared staging or production database, running the application locally can apply migrations there. Verify the URL before starting.
Trade-offs and limitations
- Startup blocking. Migrations run during application startup. Large data migrations can delay readiness significantly. Test migration duration against a production-sized database copy, and consider running heavy schema changes outside the web process if startup time becomes a problem.
- No manual drift. Do not mix Flyway migrations with manual schema changes in production. Inconsistencies cause migration failures and make the history table unreliable.
- Community edition limits. Flyway Community Edition does not include undo migrations. Reverting a change requires writing reverse SQL manually and treating it as a new versioned migration.
- Checksum failures. Modifying an already-applied migration file causes Flyway to fail on the next startup. Treat migration files as immutable after deployment.
Verify before you deploy
- Start the application and inspect the console for Flyway log lines indicating that migrations were applied.
- Query the history table to confirm expected entries:
SELECT * FROM flyway_schema_history ORDER BY installed_rank;
Each row should correspond to a migration file you expect to be applied. If a row is missing or marked as failed, investigate before allowing traffic.
As a diagnostic check, modify a migration file locally and restart the application. Flyway should refuse to start because the checksum no longer matches the recorded version. Revert the file before proceeding. This confirms Flyway is actively guarding the schema rather than silently skipping scripts.
Closing
Flyway turns database schema into versioned code that travels with your Spring Boot application. Start with one or two migrations, verify the history table after startup, and treat migration files as immutable once deployed. Check your specific Spring Boot and Flyway versions for any behavior differences before rolling this into production.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.