ADD COLUMN … FIRST / AFTER: instant, or a full table rebuild?
Adding a column is the migration people assume is free. It usually is — ALGORITHM=INSTANT is the default since 8.0.12 — but before MySQL 8.0.29 an instant add only worked at the end of the table. FIRST or AFTER other_col forced an in-place rebuild of every row.
What the manual says
| Operation | Instant | In place | Rebuilds | Concurrent DML |
|---|---|---|---|---|
| Adding a column | Yes* | Yes | No* | Yes* |
* From the manual, Column operations: "Before MySQL 8.0.29, INSTANT could only add columns at the end. As of MySQL 8.0.29, it can add at any position." INSTANT is not available for ROW_FORMAT=COMPRESSED tables, tables with a FULLTEXT index, data-dictionary tables or temporary tables; a table may carry at most 64 instant row versions before a rebuild is required.
What to do
- If column order does not matter (it almost never does for an application), omit FIRST/AFTER and the add is instant on any 8.0.12+ server.
- If you must position the column, run on 8.0.29+ and assert it:
ALTER TABLE users ADD COLUMN nickname VARCHAR(50) NULL AFTER name, ALGORITHM=INSTANT;— on an older server or an ineligible table the statement fails immediately instead of rebuilding. - Check the server:
SELECT VERSION();and the table's row format / indexes.
How Presift flags it
▲ MG004 WARNING migration.sql:1
ALTER TABLE users: ADD COLUMN with AFTER NAME is INSTANT only on MySQL 8.0.29+
Why: Before MySQL 8.0.29 an added column could only be INSTANT when placed last; FIRST/AFTER forced an in-place rebuild. On 8.0.29+ any position can be INSTANT unless the table has a FULLTEXT index, uses ROW_FORMAT=COMPRESSED, or the instant-column limit is reached.
Do: Add the column at the end (omit FIRST/AFTER) if column order does not matter, or declare ALGORITHM=INSTANT so the statement fails fast on servers/tables where INSTANT is unavailable.
Confidence: medium (statement-only analysis; current schema not visible)
Evaluate it on your own migrations — 30 days, whole product, no key to copy
Add the Action to a pull-request workflow and give the job id-token: write. On its first
run the client asks GitHub for the job's own identity token and exchanges it, in memory, for a
short-lived evaluation entitlement. There is no form, no account, no card and nothing to paste.
name: migration-safety
on: [pull_request]
permissions:
contents: read
id-token: write # lets Presift start your 30-day evaluation
jobs:
presift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nishu-sde/presift@v1
with:
paths: db/migrations
fail-on: error
One 30-day evaluation per GitHub owner — an organisation or a personal account.
Linux x86_64 runners with Python 3.9+ (GitHub-hosted ubuntu-* runners qualify). Fork pull
requests cannot evaluate, because GitHub issues them no identity token. Outside GitHub Actions the
evaluation is not available; a paid organisation key is.