Overview
Thegeni down command rolls back previously applied migrations using the .down.sql files. This allows you to revert database changes when needed.
Usage
With Amount Flag
Flags
Number of migrations to rollback. Migrations are rolled back in reverse chronological order (newest first).Aliases:
-aExamples:--amount 1- Rollback the most recent migration (default)--amount 5- Rollback the last 5 migrations--amount 0- Rollback nothing
Required Environment Variables
The database connection string. Format varies by database type.Examples:
- PostgreSQL:
postgres://user:password@localhost:5432/dbname?sslmode=disable - MySQL:
mysql://root:password@localhost:3306/app - MariaDB:
mariadb://root:password@localhost:3307/app - SQLite:
sqlite://./database.sqlite - LibSQL:
https://localhost:6000
Optional Environment Variables
Authentication token for LibSQL/Turso databases.
Path to the directory containing migration files.
Name of the table used to track applied migrations.
Filename for the dumped database schema.
Number of seconds to wait for the database to be ready.
Set to
true to disable automatic schema dumping after rollback.How It Works
- Connect to the database
- Retrieve the list of applied migrations from the tracking table
- Sort migrations in reverse chronological order (newest first)
- Select the specified number of migrations to rollback
- Find the corresponding
.down.sqlfiles - Execute each down migration
- Remove the migration record from the tracking table
- Dump the updated database schema (unless disabled)
Examples
Rollback One Migration (Default)
Rollback the most recently applied migration:Rollback Multiple Migrations
Rollback the last 3 migrations:Using Short Flag
SQLite Example
LibSQL/Turso Example
Rollback All Migrations
To rollback all applied migrations, specify a large number:Rollback Order
Migrations are always rolled back in reverse chronological order (newest first):Transaction Behavior
Likegeni up, rollbacks run inside transactions by default. Each .down.sql file can disable transactions:
If a rollback fails mid-transaction, the database state is preserved and the migration record remains in the tracking table. You can fix the
.down.sql file and retry.Error Handling
No Down Migration File
.down.sql file for a migration is missing.
Solution: Ensure every applied migration has a corresponding .down.sql file in the migrations folder.
Rollback Failed
- Fix the
.down.sqlfile - Run
geni downagain - The failed migration is still marked as applied, so it will retry
No Migrations to Rollback
If no migrations are applied,geni down completes successfully without doing anything.
Writing Down Migrations
Down migrations should reverse all changes from the up migration:Up Migration
Down Migration
Use
IF EXISTS in down migrations to make them idempotent and prevent errors if the migration was partially applied.Testing Rollbacks
Always test that your down migrations work correctly:Schema Dumping After Rollback
After rolling back migrations, Geni updates the schema dump file to reflect the current database state:Production Considerations
Safe Production Rollback
Docker Usage
Best Practices
- Always write down migrations: Every up migration should have a corresponding down migration
- Test rollbacks: Verify that
geni downworks before deploying - Use IF EXISTS: Make down migrations idempotent with
DROP TABLE IF EXISTS - Consider data loss: Down migrations may delete data - plan accordingly
- Rollback incrementally: Use
-a 1to rollback one migration at a time - Backup first: Always backup production databases before rollback
- Document destructive changes: Note in comments if data will be lost
Common Patterns
Reverting a Failed Deployment
Testing Migration Reversibility
Cleaning Up Development Database
Next Steps
Apply Migrations
Re-apply migrations with
geni upCheck Status
View migration status with
geni statusCreate Migration
Create new migrations with
geni newDump Schema
Export current schema with
geni dump