5 exercises — practise the English vocabulary for database migrations: up/down migration functions, zero-downtime strategies, backfilling, breaking vs. non-breaking changes, and communicating migration risk in pull requests.
0 / 18 completed
1 / 18
A code reviewer sees a migration file containing both an up() and a down() function. What is the purpose of the down() function, and why do some teams argue it is not always worth maintaining?
Migration up/down vocabulary:
Option B is correct. The down() function is intended to undo the up() migration — enabling rollback — but its value is frequently debated in engineering teams.
Why down() is controversial:
Destructive migrations — if up() drops a column, down() can recreate the column structure, but the data is already gone. The rollback function creates a false sense of safety.
Data migrations — if up() transforms data (e.g., splits a name column into first_name/last_name), reversing that transformation requires preserving the original, which adds complexity.
Skipped in practice — many teams argue that forward-only migrations paired with a well-tested rollback deployment procedure are safer than relying on down().
Function
Direction
Triggered by
up()
Forward — applies the schema change
migrate up / deploy
down()
Reverse — undoes the schema change
migrate rollback
2 / 18
A team needs to rename the column user_name to username in a high-traffic PostgreSQL table without taking downtime. Which sequence of steps correctly implements a zero-downtime column rename?
Zero-downtime migration vocabulary:
Option D describes the standard expand-and-contract (or parallel-write) pattern for zero-downtime column renames.
Why ALTER TABLE RENAME COLUMN (Option A) causes downtime: In PostgreSQL, renaming a column acquires an ACCESS EXCLUSIVE lock on the table, blocking all reads and writes for the duration — unacceptable on large, high-traffic tables.
The expand-and-contract sequence:
Expand: Add the new username column (nullable, no lock required on most databases)
Backfill: Copy data from user_name → username in batches to avoid lock contention
Dual-write: Deploy application code that writes to both columns on every insert/update
Migrate reads: Once backfill is complete, point all reads at username
Contract: In a later migration, drop user_name after confirming no code references it
Term
Meaning in migration context
Backfill
Populating a new column with data derived from existing rows
Dual-write
Application writes to both old and new columns during transition
ACCESS EXCLUSIVE lock
PostgreSQL lock that blocks all concurrent access to the table
Expand-and-contract
Two-phase pattern: add new structure, migrate, then remove old structure
3 / 18
A migration adds an is_verified BOOLEAN NOT NULL DEFAULT FALSE column, then immediately runs an UPDATE to set is_verified = TRUE for all rows created before a specific date. Which definition of "backfill" is correct?
Backfill vocabulary:
Option A is the correct definition. Backfilling populates a new column (or repairs missing data) across existing rows that were created before the column existed.
Backfill risk vocabulary for PR descriptions:
Batch backfill — running the UPDATE in chunks (e.g., 1,000 rows at a time) to avoid a long-running transaction that locks the table
Backfill duration estimate — communicate to reviewers: "This backfill runs against ~2M rows; estimated time: 45 minutes on production"
Idempotent backfill — the UPDATE can be re-run safely without double-applying changes
Online backfill — runs concurrently with live traffic, using small batches and short transactions
How to describe a backfill in a PR:
"This migration adds the is_verified column and backfills it for existing rows using a batched UPDATE (500 rows per transaction). Estimated backfill time on production: ~20 minutes. The migration is safe to run with live traffic — it uses row-level locks only and no table-level lock."
4 / 18
Your team uses rolling deployments where multiple application versions run simultaneously during a deploy. Which of the following schema changes is non-breaking — safe to apply to the database before all application instances have been updated?
Breaking vs. non-breaking schema change vocabulary:
Option C is the only non-breaking change. Adding a nullable column without a default is safe during a rolling deployment because: existing application code that does not know about the column will simply ignore it; new inserts by old app versions will set the column to NULL, which is valid.
Schema change
Breaking?
Why
Remove a column
Yes
Old app versions reading that column get an error
Add NOT NULL col without default
Yes
Old app inserts that don't supply the column fail
Add nullable column
No
Old app inserts silently produce NULL; no error
Rename a column
Yes
Queries using the old name break immediately
Add an index
No (CONCURRENTLY)
Transparent to application; no column reference change
Key vocabulary for migration risk communication:
Breaking change — a schema change that causes errors in the currently running application version
Rolling deployment — deploying new app version gradually, with multiple versions running simultaneously
Forward compatibility — the new schema must work with the old application code during the window between migration and full rollout
5 / 18
Which PR description most effectively communicates the risk of a database migration to a reviewer who is not a database specialist?
Migration risk communication in PRs:
Option B demonstrates professional database migration communication. It gives the reviewer every piece of information they need to make a risk decision without requiring database expertise.
What makes Option B effective:
Element
Value to the reviewer
Row count (8M rows)
Quantifies the scope of the operation
Lock duration estimate (12–20 min)
Makes the downtime risk concrete and time-bounded
Safer alternative proposed
Shows the author has thought about mitigation
Staging test result with dataset size
Evidence that the estimate is data-driven, not guessed
Migration PR description vocabulary checklist:
State the table name and approximate row count
Identify whether the migration takes a table lock and estimate the duration
Classify the change as breaking or non-breaking
Describe the rollback plan if the migration fails partway
Report staging test results with dataset size proxy
6 / 18
Alex: 'Hey team, I'm reviewing this migration script. It has both an `up()` and a `down()` function. What's the purpose of the `down()` function, and why do some teams argue it's not always worth maintaining?
Here are the options:
insufficient — the account balance is too lowredundant — the migration only contains a single up() functionrollback — to undo any changes made by the up() function in case of failurelegacy — it's an outdated pattern and doesn't offer significant benefits
The `down()` function is crucial for providing a way to *rollback* the database changes introduced by the `up()` function. If the migration fails partway through, running the `down()` function will revert the database back to its original state before the migration started. Some teams argue against maintaining it because modern migration tools (like Alembic) often have built-in rollback capabilities and the `down()` function can become a maintenance burden; however, explicit rollbacks are still vital for ensuring data consistency in complex migrations.
7 / 18
During a code review, the team discusses a database migration script that includes both an `up()` and a `down()` function. The lead developer explains that the `down()` function is designed to revert any changes made by the `up()` function if the migration fails. However, some team members are questioning the necessity of maintaining this `down()` function. Which of the following best describes the primary concern driving this debate?
Note: Database migration tools often provide rollback capabilities, but their effectiveness and maintenance overhead can vary significantly.
The `down()` function is primarily intended as a rollback mechanism. While technically useful for reverting changes, maintaining a complex `down()` function introduces additional code complexity, testing requirements, and potential points of failure. Modern migration tools often have built-in rollback features that are more robust and easier to manage than manually crafted `down()` functions, leading teams to question its ongoing necessity.
8 / 18
Alex: 'Hey team, I'm reviewing this migration script. It has both an `up()` and a `down()` function. What's the purpose of the `down()` function, and why do some teams argue it's not always worth maintaining?
Here are the options:
insufficient — the account balance is too lowredundant — the migration only contains a single up() functionrollback — to undo any changes made by the up() function in case of failurelegacy — it's an outdated pattern and doesn't offer significant benefits
The `down()` function is crucial for providing a way to *rollback* the database changes introduced by the `up()` function. If the migration fails partway through, running the `down()` function will revert the database back to its original state before the migration started. Some teams argue against maintaining it because modern migration tools (like Alembic) often have built-in rollback capabilities and the `down()` function can become a maintenance burden; however, explicit rollbacks are still vital for ensuring data consistency in complex migrations.
9 / 18
During a code review, the team discusses a database migration script that includes both an `up()` and a `down()` function. The lead developer explains that the `down()` function is designed to revert any changes made by the `up()` function if the migration fails. However, some team members are questioning the necessity of maintaining this `down()` function. Which of the following best describes the primary concern driving this debate?
Note: Database migration tools often provide rollback capabilities, but their effectiveness and maintenance overhead can vary significantly.
The `down()` function is primarily intended as a rollback mechanism. While technically useful for reverting changes, maintaining a complex `down()` function introduces additional code complexity, testing requirements, and potential points of failure. Modern migration tools often have built-in rollback features that are more robust and easier to manage than manually crafted `down()` functions, leading teams to question its ongoing necessity.
10 / 18
Alex: 'Hey team, I'm reviewing this migration script. It has both an `up()` and a `down()` function. What's the purpose of the `down()` function, and why do some teams argue it's not always worth maintaining?
Here are the options:
insufficient — the account balance is too lowredundant — the migration only contains a single up() functionrollback — to undo any changes made by the up() function in case of failurelegacy — it's an outdated pattern and doesn't offer significant benefits
The `down()` function is crucial for providing a way to *rollback* the database changes introduced by the `up()` function. If the migration fails partway through, running the `down()` function will revert the database back to its original state before the migration started. Some teams argue against maintaining it because modern migration tools (like Alembic) often have built-in rollback capabilities and the `down()` function can become a maintenance burden; however, explicit rollbacks are still vital for ensuring data consistency in complex migrations.
11 / 18
During a code review, the team discusses a database migration script that includes both an `up()` and a `down()` function. The lead developer explains that the `down()` function is designed to revert any changes made by the `up()` function if the migration fails. However, some team members are questioning the necessity of maintaining this `down()` function. Which of the following best describes the primary concern driving this debate?
Note: Database migration tools often provide rollback capabilities, but their effectiveness and maintenance overhead can vary significantly.
The `down()` function is primarily intended as a rollback mechanism. While technically useful for reverting changes, maintaining a complex `down()` function introduces additional code complexity, testing requirements, and potential points of failure. Modern migration tools often have built-in rollback features that are more robust and easier to manage than manually crafted `down()` functions, leading teams to question its ongoing necessity.
12 / 18
Alex: 'Hey team, I'm reviewing this migration script. It has both an `up()` and a `down()` function. What's the purpose of the `down()` function, and why do some teams argue it's not always worth maintaining?
Here are the options:
insufficient — the account balance is too lowredundant — the migration only contains a single up() functionrollback — to undo any changes made by the up() function in case of failurelegacy — it's an outdated pattern and doesn't offer significant benefits
The `down()` function is crucial for providing a way to *rollback* the database changes introduced by the `up()` function. If the migration fails partway through, running the `down()` function will revert the database back to its original state before the migration started. Some teams argue against maintaining it because modern migration tools (like Alembic) often have built-in rollback capabilities and the `down()` function can become a maintenance burden; however, explicit rollbacks are still vital for ensuring data consistency in complex migrations.
13 / 18
During a code review, the team discusses a database migration script that includes both an `up()` and a `down()` function. The lead developer explains that the `down()` function is designed to revert any changes made by the `up()` function if the migration fails. However, some team members are questioning the necessity of maintaining this `down()` function. Which of the following best describes the primary concern driving this debate?
Note: Database migration tools often provide rollback capabilities, but their effectiveness and maintenance overhead can vary significantly.
The `down()` function is primarily intended as a rollback mechanism. While technically useful for reverting changes, maintaining a complex `down()` function introduces additional code complexity, testing requirements, and potential points of failure. Modern migration tools often have built-in rollback features that are more robust and easier to manage than manually crafted `down()` functions, leading teams to question its ongoing necessity.
14 / 18
Sarah, a database engineer, sends the following Slack message to her team: 'Just ran the migration script. It seems to have added a new field, `user_id`, to the `users` table. Should I check the schema changes?' What is Sarah *really* asking when she mentions checking the schema changes?
Sarah's question isn't about the *execution* of the migration (option A), nor is it about performance (option C) or compatibility (option D). She's directly asking if a specific schema change—the addition of `user_id`—has occurred. This highlights the importance of verifying that migrations are doing what they're supposed to do at a granular level.
15 / 18
During a standup meeting, David explains: 'We're using Flyway for database migrations. We've just deployed a change that adds an index to the `orders` table on the `customer_id` column. How should we ensure this index is correctly applied across all our application instances?'
Flyway is designed to automatically propagate schema changes across connected databases. Manually executing scripts (option A) defeats this purpose and introduces inconsistencies. While monitoring logs can be helpful (option D), it doesn't address the core issue of ensuring the index is applied correctly. Creating a new migration (option C) would be an unnecessary step.
16 / 18
You are reviewing a PR that includes a database migration to add a `last_login` timestamp column to the `users` table. The commit message states: 'Added last_login timestamp for improved user tracking.' What is the *most* important consideration you should raise as a reviewer regarding this change?
While testing (option A), rollback strategies (option C) and using the correct library version (option D) are important, the *most* critical issue is how the `last_login` column will be maintained. The PR doesn't address this crucial aspect of data integrity, which could lead to stale or inaccurate user tracking information.
17 / 18
Maria is reviewing a database migration script that involves updating the `products` table. The script includes an `UP()` block that adds a new column named `discount_percentage`. After running the `UP()` block, Maria notices that some products are still without this discount percentage. What's the *most likely* cause of this issue?
If the migration script didn't execute correctly in all instances (option B), some products wouldn't have received the update. Network issues (option A) and constraint violations (option C) are less likely causes for incomplete updates during a schema change. The application not reading the column (option D) would result in *all* rows having it, but that's not the scenario described.
18 / 18
You are preparing a PR description for a database migration that changes the data type of the `email` column from VARCHAR(255) to TEXT. The migration script includes an `UP()` block to perform this change. What's the *most effective* way to communicate the potential impact of this migration to a reviewer who isn't a database specialist?
The key concern for non-database specialists is the *impact* on users. Option A provides a simple explanation of why the change was made – increased length support – which is easier to understand than technical details about performance or future changes. Downtime (option B) and standard practices (option D) are irrelevant to someone unfamiliar with database operations.
What does the "Database Migration Language" exercise practise?
Practice English for database migration discussions: up/down migrations, zero-downtime column renames, backfill vocabulary, breaking vs. non-breaking schema changes, and migration risk communication in PRs. 5 exercises.
How many questions are in this exercise?
This exercise has 18 questions, each multiple-choice with a full explanation shown after you answer.
What English level is this exercise for?
This exercise is tagged Intermediate. If the vocabulary feels difficult, browse the Database & SQL category page for an easier module to start with.
Is this exercise free to use?
Yes. Every exercise on CoderSlingo, including this one, is free with no account, sign-up, or paywall.
Do I get feedback if I answer incorrectly?
Yes — whichever option you choose, right or wrong, you'll immediately see an explanation clarifying the correct term and why the other options don't fit.
Can I retry this exercise?
Yes — once you finish all the questions, a "Try again" button on the results screen resets the exercise so you can practise as many times as you like.
Do I need an account to track my progress?
No account is required. Your progress bar and score for this session are tracked in the browser as you go, but nothing is saved once you leave the page.
Is "Database Migration Language" part of a larger series?
Yes — it's one exercise in the Database & SQL category on CoderSlingo. See the category page for the full list of related exercises on similar terminology.
Can I link directly to this exercise?
Yes — this exercise has its own permanent URL, so you can bookmark it or share the link directly with a colleague or study partner.
Where can I find more exercises like this one?
See the Database & SQL category page for related exercises, or browse the main Exercises hub for other IT English topics.