Direct answer
Run a backward‑compatible (additive) migration against your production database before promoting the Netlify deploy. After the deploy is live, you may run a second cleanup migration to remove obsolete schema objects. If your migration requires breaking changes, you must use a blue‑green/feature‑flag approach instead of the simple pre‑deploy step.
Likely explanation
Netlify’s atomic deploys guarantee that the frontend is only swapped in after a successful build, so downtime can only come from the database layer. A migration that only adds columns, tables, or indexes can be applied while the old code is still running because the old code ignores the new objects. Once the new Netlify version is serving traffic, it can safely use the new schema. After you verify everything works, a follow‑up migration can drop or rename the old objects.
Confirmed facts
- Netlify deploys are immutable and atomic; the frontend change itself never causes downtime.
- Database downtime occurs only when a migration introduces breaking changes that the current code cannot tolerate.
- A zero‑downtime strategy therefore requires migrations to be backward‑compatible with the previously deployed code, or a separate rollout of the new schema before the code that needs it is activated.
Steps for a backward‑compatible migration
- Write an additive migration – use only
ADD COLUMN, CREATE TABLE, CREATE INDEX, or ALTER TABLE … SET DEFAULT statements; avoid DROP, RENAME, or making existing columns NOT NULL without a default.
- Run the migration on production – for example:
psql -U $DB_USER -d $DB_NAME -f 001_add_user_prefs.sql
- Verify the schema – run a quick check:
SELECT column_name, is_nullable FROM information_schema.columns
WHERE table_name = 'user_prefs' AND column_name = 'new_col';
Ensure the column exists and is nullable if the old code does not reference it.
- Deploy the new Netlify site – trigger your CI/CD pipeline or run:
netlify deploy --prod --dir=dist
The deploy will be atomic; the frontend continues to work with the old schema.
- Optional cleanup migration – after you have confirmed the new code works (e.g., via smoke tests or feature flags), run a second migration to drop obsolete columns or tables:
When the migration includes breaking changes
If you must drop or rename a column that the current Netlify code still reads, the simple pre‑deploy step will cause errors. In that case:
- Deploy a separate environment (e.g., a Netlify branch deploy) that runs the new code after* the migration has been applied.
- Use split traffic or a feature flag to route a small percentage of users to the new version while the majority stay on the old version.
- Validate that the new version works with the migrated schema.
- Gradually increase traffic until 100 % is on the new version, then run a cleanup migration to remove the old schema objects.
Verification checklist
- Inspect the migration SQL for any
DROP, RENAME, or ALTER COLUMN … SET NOT NULL without a default.
- After migration, query the schema to confirm old columns remain present and nullable if needed.
- Deploy a test Netlify branch, run the migration on a copy of production data, and exercise critical paths (login, data write/read) to ensure no errors appear before promoting to production.
Missing diagnostic detail that would change the recommendation: Does your migration involve any dropping or renaming of columns/tables that the current Netlify code still accesses? If yes, follow the breaking‑change flow above; otherwise the additive‑migration steps are sufficient.