gh-ost: triggerless online schema migration for MySQL
GitHub's Online Schema-migration Tool for MySQL
At a glance
- What is it?
- gh-ost copies a table into a ghost table and applies ongoing changes from the binary log instead of triggers. It is a good fit for busy MySQL masters, and a poor fit for anything that is not MySQL.
- Who is it for?
- Adopt gh-ost if you run MySQL or a MySQL-compatible service and your migrations are blocked by table size or replication lag; the README's own advice is to run --test-on-replica first, then a noop, then the real migration with --execute. Do not adopt it if your database is Postgres: there is no Postgres support in the repository, and the related searches asking for it have no answer here.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The migration problem gh-ost was built to remove
A plain ALTER TABLE on a large MySQL table locks or rebuilds that table, and the rebuild can run for hours. On a busy master that means blocked writes or a replica that falls far behind. The older generation of online schema change tools works around this by creating a ghost table, copying rows into it, and keeping it in sync with triggers on the original table. gh-ost keeps the ghost table pattern and drops the triggers. The README states the project was designed around the limitations and risks of triggers, and points to doc/why-triggerless.md for the reasoning.
The audience is narrow and specific: teams running MySQL who need to change a table's schema while the table is serving traffic. If your tables are small, a normal ALTER is cheaper than any tool. If your database is Postgres, gh-ost is not the answer, and the repository contains nothing for it.
How the binary log replaces triggers
gh-ost creates a ghost table in the likeness of the original, migrates the empty ghost table with the schema change, then copies rows from the original to the ghost in batches. Ongoing INSERT, DELETE and UPDATE statements on the original are captured from the binary log stream and applied asynchronously to the ghost table, according to doc/triggerless-design.md. At the end, the original table and the ghost table are swapped.
Taking the change capture out of the database and into the tool is the whole design. The README says gh-ost takes on tasks that other tools leave to the database, and the consequence it claims is control: the migration can be suspended, and its write load is decoupled from the master's workload. That is a real architectural difference, not a tuning difference. It also means gh-ost must read the binary log, which constrains which replication formats and privileges are workable. The README notes that a migration that uses a replica is the required mode when the master uses Statement Based Replication.
Installing gh-ost and running a first test migration
The README says gh-ost is available in binary format for Linux and Mac OS/X, and links to the latest release page for downloads. It is a Go project, built with Go 1.15 and above; building from source uses script/build. The go.mod in the repository declares go 1.25.12, which is worth noting if you plan to compile it yourself.
The README's first recommendation is not to touch production. Test on a replica, where gh-ost performs the same flow it would on the master but does not replace the original table, leaving two tables you can compare. The README gives --test-on-replica for this, and the cheatsheet in doc/cheatsheet.md lists the full set of flags; the README does not print a complete example invocation, so read the cheatsheet before you type a command.
The README also advises issuing a noop before each real master migration, then issuing the real thing via --execute. For progress reporting it suggests --exact-rowcount, and for control over the swap it suggests --postpone-cut-over-flag-file, which holds the cut-over until you release it. The README does not document rollback.
Where gh-ost is the wrong tool
The most concrete limitation is the one the name implies: MySQL. There is no Postgres support in the repository, and no amount of configuration will produce it. If you are on Postgres, this project is not for you, whatever search results suggest.
The second limitation follows from the design. Because change capture comes from the binary log rather than from triggers, gh-ost depends on reading that log, and the README explicitly calls out Statement Based Replication as a case where running against a replica is required rather than preferred. The README also links doc/requirements-and-limitations.md, which is where the project keeps the full list; that document is the one to read before you assume a particular table is migratable.
Third, there is the cut-over itself. The README calls the table swap probably the most critical step, and offers --postpone-cut-over-flag-file precisely because it is risky. A tool that gives you a pause button is not the same as a tool that makes the swap safe; it moves the responsibility for timing to you.
gh-ost compared with pt-online-schema-change
The README names pt-online-schema-change directly, alongside Facebook's online schema change, as the lineage gh-ost came from. The difference in approach is the trigger. Percona's tool follows the conventional pattern: triggers on the original table write ongoing changes into the ghost table, and the database does the capture work. gh-ost removes the triggers and reads the binary log instead, applying changes asynchronously.
That single change is what buys the operational behaviour gh-ost advertises: a true pause that ceases row copies and event processing, interactive reconfiguration while the migration runs, and a write load decoupled from the master's own workload. The trade is that gh-ost now has requirements of its own around binary log access and replication format, and it carries the code that a trigger-based tool leaves inside MySQL. Which of those two sets of constraints you would rather own depends on your topology. If you are already running Percona Toolkit and your replication setup is awkward, the trigger-based approach may be less friction.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-10. Releases are frequent: v1.1.11 on 2026-08-17, v1.1.10 on 2026-06-04, and v1.1.9 on 2026-05-01. The README describes gh-ost as GA and stable, and the project accepts pull requests, though it notes that GitHub's priorities may differ from yours.
gh-ost is MIT licensed. That is permissive, and it is the licence most teams expect from a Go CLI tool. The README adds that gh-ost uses third party libraries under their own licences, listed in the vendor directory. If your organisation reviews dependency licences, that directory is the place to look, since the MIT grant covers gh-ost itself and not necessarily everything it links against. Nothing here is legal advice; check with whoever handles licensing on your team.
The upgrade path is a binary swap. There is no server component and no schema of its own to migrate. The cost that does not disappear is operational: every migration still needs an operator who understands the cut-over, and the README's testing advice exists because the project expects you to build trust in it rather than assume it.
Editorial conclusion
Adopt gh-ost if you run MySQL or a MySQL-compatible service and your migrations are blocked by table size or replication lag; the README's own advice is to run --test-on-replica first, then a noop, then the real migration with --execute. Do not adopt it if your database is Postgres: there is no Postgres support in the repository, and the related searches asking for it have no answer here. Before your first production cut-over, verify three things: that your master and replica use the right replication format, that the account you pass to gh-ost can read the binary log, and that you have run a migration with --postpone-cut-over-flag-file so the swap happens when you are watching it.
Frequently asked questions
How do I install gh-ost?
The README says gh-ost is available in binary format for Linux and Mac OS/X, with downloads on the latest release page. It is a Go project built with Go 1.15 and above, and script/build is the build entry point if you compile it yourself.
What are the alternatives to gh-ost?
The README names Facebook's online schema change and pt-online-schema-change as the tools gh-ost was designed in the lineage of. The difference is that those use triggers on the original table to propagate changes, while gh-ost reads the binary log stream instead.
Does gh-ost work with foreign keys?
The README does not address foreign keys directly; it points readers to doc/requirements-and-limitations.md, which is where the project keeps its full list of constraints. That document is the one to check before migrating a table with foreign keys.
Can I run a gh-ost migration without actually changing the table?
Yes. The README describes a noop migration that merely tests whether the migration is valid and good to go, and recommends issuing one before every real master migration. The real migration is then issued with --execute.
Does gh-ost support Postgres?
No. gh-ost is described as an online schema migration solution for MySQL, and the repository contains nothing for Postgres.
How do I control when gh-ost swaps the tables?
The README suggests --postpone-cut-over-flag-file, which lets you postpone the cut-over, the table swap, until a time you choose. It also recommends getting familiar with the interactive commands, since gh-ost can be reconfigured while a migration runs.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/github-gh-ost)
Community notes