Django Migrations in Production: A VPS Release Checklist
Keep application code and database changes compatible while production requests and queued jobs continue.
A migration that finishes instantly on a developer database may behave differently against years of production records. Table size, concurrent writes, database engine, and the exact operation all affect deployment risk. Before applying a Django migration on your VPS, decide which application versions must keep working during the change and how you will prove the final data is correct. A successful command exit is only one part of that proof. Assign one release step to apply migrations so overlapping startup scripts do not turn a controlled schema change into competing maintenance attempts.
Review the operation, not just the filename
Read the migration and inspect the SQL where appropriate. Adding a field, changing an index, and rewriting every row are different operational tasks. The official Django migrations guide explains backend differences and historical model behavior. Check the documentation for your installed Django and database versions. Estimate how much data the change touches, whether it may wait for locks, and whether it requires additional disk space while old structures remain present.
Use a compatibility window
Suppose you are replacing a customer's display name field with separate name fields. Dropping the original column in the first release can break workers still running old code. A staged approach adds the new fields, deploys code that handles the transition, backfills existing rows, and removes the old field in a later release. Spell out which version reads and writes each representation. Do not leave dual writes indefinitely without a reconciliation rule for conflicting values.
Keep backfills observable
A large data transformation deserves progress records, bounded batches, and a restart strategy. Choose stable record ordering, track what has completed, and decide how concurrent updates interact with the transformation. For a million archived events, rewriting everything in one transaction may create an unnecessarily long operation. Test a representative batch, measure duration and database impact, then derive an estimated window. Treat that estimate as planning evidence rather than a guarantee that production will behave identically.
Define rollback before deployment
Rolling application code back does not automatically reverse the database. Some migrations are irreversible, and restoring a backup can discard writes received since that backup. Decide whether the practical recovery is reverting code, applying a corrective migration, or entering maintenance and restoring data. Record the decision with the release. On a LayerOne VPS, application backups are customer managed; review the backup guide and perform a restoration rehearsal before relying on a recovery window.
Validate business records after the change
Use staging data with realistic size and relationships, with sensitive values removed. Verify row counts, expected null values, and a sample of transformed records. Exercise both a new write and an update to an older record. During the production release, monitor database lock waits, application errors, and background job failures. Keep the previous compatible artifact available until acceptance checks finish. Review the wider Django process layout so web workers, task workers, and scheduled commands all participate in the same release plan.