{"id":13491034,"url":"https://github.com/xataio/pgroll","last_synced_at":"2026-01-05T11:17:42.012Z","repository":{"id":196217284,"uuid":"657224325","full_name":"xataio/pgroll","owner":"xataio","description":"PostgreSQL zero-downtime migrations made easy","archived":false,"fork":false,"pushed_at":"2025-05-13T10:25:31.000Z","size":3025,"stargazers_count":4930,"open_issues_count":72,"forks_count":92,"subscribers_count":21,"default_branch":"main","last_synced_at":"2025-05-13T10:45:48.933Z","etag":null,"topics":["golang","hacktoberfest","migrations","postgres","postgresql","schema","zero-downtime"],"latest_commit_sha":null,"homepage":"https://pgroll.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xataio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-06-22T15:29:36.000Z","updated_at":"2025-05-13T10:25:33.000Z","dependencies_parsed_at":"2023-10-03T12:28:12.315Z","dependency_job_id":"1175ba72-5876-4ba7-88d0-2003eab27382","html_url":"https://github.com/xataio/pgroll","commit_stats":{"total_commits":394,"total_committers":20,"mean_commits":19.7,"dds":0.3426395939086294,"last_synced_commit":"6ff198baec8fa8a8dea2621ef4d7541cf5885630"},"previous_names":["xataio/pgroll","xataio/pg-roll"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xataio%2Fpgroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xataio%2Fpgroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xataio%2Fpgroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xataio%2Fpgroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xataio","download_url":"https://codeload.github.com/xataio/pgroll/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254010823,"owners_count":21998993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","hacktoberfest","migrations","postgres","postgresql","schema","zero-downtime"],"created_at":"2024-07-31T19:00:53.006Z","updated_at":"2026-01-05T11:17:41.999Z","avatar_url":"https://github.com/xataio.png","language":"Go","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"brand-kit/banner/pgroll-banner-github@2x.png\" alt=\"pgroll logo\" /\u003e\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/xataio/pgroll/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-Apache_2.0-green\" alt=\"License - Apache 2.0\"\u003e\u003c/a\u003e \u0026nbsp;\n  \u003ca href=\"https://github.com/xataio/pgroll/actions?query=branch%3Amain\"\u003e\u003cimg src=\"https://github.com/xataio/pgroll/actions/workflows/build.yml/badge.svg\" alt=\"CI Build\"\u003e\u003c/a\u003e \u0026nbsp;\n  \u003ca href=\"https://github.com/xataio/pgroll/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/release/xataio/pgroll.svg?label=Release\" alt=\"Release\"\u003e\u003c/a\u003e \u0026nbsp;\n  \u003cimg alt=\"GitHub Downloads (all assets, all releases)\" src=\"https://img.shields.io/github/downloads/xataio/pgroll/total\"\u003e \u0026nbsp;\n  \u003ca href=\"https://pgroll.com/docs\"\u003e\u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/pgroll-documentation-page?style=flat\u0026link=https%3A%2F%2Fpgroll.com%2Fdocs%2Flatest%2Fgetting-started\"\u003e\u003c/a\u003e \u0026nbsp;\n  \u003ca href=\"https://xata.io/discord\"\u003e\u003cimg src=\"https://img.shields.io/discord/996791218879086662?label=Discord\" alt=\"Discord\"\u003e\u003c/a\u003e \u0026nbsp;\n  \u003ca href=\"https://twitter.com/xata\"\u003e\u003cimg src=\"https://img.shields.io/badge/@xata-6c47ff?label=Follow\u0026logo=x\" alt=\"X (formerly Twitter) Follow\" /\u003e \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://xata.io\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Made%20with%20♥%20%20-%20%20by%20Xata-6c47ff?style=flat\u0026logo=postgresql\u0026logoColor=white\" alt=\"Made with ♥ by Xata\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# pgroll - Zero-downtime, reversible, schema migrations for Postgres\n\n`pgroll` is an open source command-line tool that offers safe and reversible schema migrations for PostgreSQL by serving multiple schema versions simultaneously. It takes care of the complex migration operations to ensure that client applications continue working while the database schema is being updated. This includes ensuring changes are applied without locking the database, and that both old and new schema versions work simultaneously (even when breaking changes are being made!). This removes risks related to schema migrations, and greatly simplifies client application rollout, also allowing for instant rollbacks.\n\nSee the [introductory blog post](https://pgroll.com/blog/introducing-pgroll-zero-downtime-reversible-schema-migrations-for-postgres) for more about the problems solved by `pgroll`.\n\n## Features\n\n- Zero-downtime migrations (no database locking, no breaking changes).\n- Keep old and new schema versions working simultaneously.\n- Automatic columns backfilling when needed.\n- Instant rollback in case of issues during migration.\n- Works against existing schemas, no need to start from scratch.\n- Works with Postgres 14.0 or later.\n- Works with any Postgres service (including RDS and Aurora).\n- Written in Go, cross-platform single binary with no external dependencies.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [How pgroll works](#how-pgroll-works)\n- [Documentation](#documentation)\n- [Benchmarks](#benchmarks)\n- [Contributing](#contributing)\n- [License](#license)\n- [Support](#support)\n\n## Installation\n\n### Binaries\n\nBinaries are available for Linux, macOS \u0026 Windows, check our [Releases](https://github.com/xataio/pgroll/releases).\n\n### From source\n\nTo install `pgroll` from the source, run the following command:\n\n```sh\ngo install github.com/xataio/pgroll@latest\n```\n\nNote: requires [Go 1.24](https://golang.org/doc/install) or later.\n### From package manager - Homebrew\n\nTo install `pgroll` with homebrew, run the following command:\n\n```sh\n# macOS or Linux\nbrew tap xataio/pgroll\nbrew install pgroll\n```\n\n## Usage\n\nFollow these steps to perform your first schema migration using `pgroll`:\n\n### Prepare the database\n\n`pgroll` needs to store some internal state in the database. A table is created to track the current schema version and store version history. To prepare the database, run the following command:\n\n```sh\npgroll init --postgres-url postgres://user:password@host:port/dbname\n```\n\n### Start a migration\n\nCreate a migration file. You can check the [examples](examples) folder for some examples. For instance, use this migration file to create a new `customers` table:\n\n\u003cdetails\u003e\n  \u003csummary\u003einitial_migration.json\u003c/summary\u003e\n\n```json\n{\n  \"name\": \"initial_migration\",\n  \"operations\": [\n    {\n      \"create_table\": {\n        \"name\": \"customers\",\n        \"columns\": [\n          {\n            \"name\": \"id\",\n            \"type\": \"integer\",\n            \"pk\": true\n          },\n          {\n            \"name\": \"name\",\n            \"type\": \"varchar(255)\",\n            \"unique\": true\n          },\n          {\n            \"name\": \"bio\",\n            \"type\": \"text\",\n            \"nullable\": true\n          }\n        ]\n      }\n    }\n  ]\n}\n```\n\u003c/details\u003e\n\nThen run the following command to start the migration:\n\n```sh\npgroll --postgres-url postgres://user:password@host:port/dbname start initial_migration.json\n```\n\nThis will create a new schema version in the database, and apply the migration operations (create a table). After this command finishes, both the old version of the schema (with no customers table) and the new one (with the customers table) will be accessible simultaneously.\n\n### Configure client applications\n\nAfter starting a migration, client applications can start using the new schema version. In order to do so, they need to be configured to access it. This can be done by setting the `search_path` to the new schema version name (provided by `pgroll start` output), for instance:\n\n```sql\nSET search_path TO 'public_initial_migration';\n```\n\n### Complete the migration\n\nOnce there are no more client applications using the old schema version, the migration can be completed. This will remove the old schema. To complete the migration, run the following command:\n\n```sh\npgroll --postgres-url postgres://user:password@host:port/dbname complete\n```\n\n### Rolling back a migration\n\nAt any point during a migration, it can be rolled back to the previous version. This will remove the new schema and leave the old one as it was before the migration started. To rollback a migration, run the following command:\n\n```sh\npgroll --postgres-url postgres://user:password@host:port/dbname rollback\n```\n\n## How pgroll works\n\n`pgroll` works by creating virtual schemas by using views on top of the physical tables. This allows for performing all the necessary changes needed for a migration without affecting the existing clients.\n\n![Multiple schema versions with pgroll](docs/img/schema-changes-flow@2x.png)\n\n\n`pgroll` follows a [expand/contract workflow](https://openpracticelibrary.com/practice/expand-and-contract-pattern/). On migration start, it will perform all the additive changes (create tables, add columns, etc) in the physical schema, without breaking it.\n\nWhen a breaking change is required on a column, it will create a new column in the physical schema, and backfill it from the old column. Also, configure triggers to make sure all writes to the old/new column get propagated to its counterpart during the whole active migration period. The new column will be then exposed in the new version of the schema.\n\nOnce the start phase is complete, the new schema version is ready, mapping all the views to the proper tables \u0026 columns. Client applications can then access the new schema version, while the old one is still available. This is the moment to start rolling out the new version of the client application.\n\n![Multiple schema versions with pgroll](docs/img/migration-schemas@2x.png?c=0)\n\nWhen no more client applications are using the old schema version, the migration can be completed. This will remove the old schema, and the new one will be the only one available. No longer needed tables \u0026 columns will be removed (no client is using this at this point), and the new ones will be renamed to their final names. Client applications still work during this phase, as the views are still mapping to the proper tables \u0026 columns.\n\n## Documentation\n\nFor more advanced usage, tutorials, and detailed options refer to the guides and references in the [Documentation](https://pgroll.com/docs/).\n\n## Benchmarks\n\nSome performance benchmarks are run on each commit to `main` in order to track performance over time. Each benchmark is run against Postgres 14.8, 15.3, 16.4, 17.0, 18.0 and \"latest\". Each line on the chart represents the number of rows the benchmark was run against, currently 10k, 100k and 300k rows.\n\n* `Backfill:` Rows/s to backfill a text column with the value `placeholder`. We use our default batching strategy of 10k rows per batch with no backoff.\n* `WriteAmplification/NoTrigger:` Baseline rows/s when writing data to a table without a `pgroll` trigger.\n* `WriteAmplification/WithTrigger:` Rows/s when writing data to a table when a `pgroll` trigger has been set up.\n* `ReadSchema:` Checks the number of executions per second of the `read_schema` function which is a core function executed frequently during migrations.\n\nThey can be seen [here](https://xataio.github.io/pgroll/benchmarks.html).\n\n## Contributing\n\nWe welcome contributions from the community! If you'd like to contribute to `pgroll`, please follow these guidelines:\n\n* Create an [issue](https://github.com/xataio/pgroll/issues) for any questions, bug reports, or feature requests.\n* Check the documentation and [existing issues](https://github.com/xataio/pgroll/issues) before opening a new issue.\n\n### Contributing Code\n\n1. Fork the repository.\n2. Create a new branch for your feature or bug fix.\n3. Make your changes and write tests if applicable.\n4. Ensure your code passes linting and tests.\n5. Submit a pull request.\n\nFor this project, we pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.\n\n## References\n\nThis is a list of projects and articles that helped as inspiration, or otherwise are similar to `pgroll`:\n\n* [Reshape](https://github.com/fabianlindfors/reshape) by Fabian Lindfors\n* [PgHaMigrations](https://github.com/braintree/pg_ha_migrations)\n* [PostgreSQL at Scale: Database Schema Changes Without Downtime](https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680)\n* [Zero downtime schema migrations in highly available databases](http://essay.utwente.nl/92098/1/vanKampen_MA_EEMCS.pdf)\n* [Expand and contract pattern](https://openpracticelibrary.com/practice/expand-and-contract-pattern/)\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\nIf you have any questions, encounter issues, or need assistance, open an issue in this repository our join our [Discord](https://xata.io/discord), and our community will be happy to help.\n\n\n\u003cbr\u003e\n\u003cp align=\"right\"\u003eMade with :heart: by \u003ca href=\"https://xata.io\"\u003eXata 🦋\u003c/a\u003e\u003c/p\u003e\n","funding_links":[],"categories":["Go","postgresql","Utilities"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxataio%2Fpgroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxataio%2Fpgroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxataio%2Fpgroll/lists"}