# Upgrade from 0.x to 1.0

> Every breaking change and upgrade step from 0.4.x to 1.0.0, one release at a time.

Source: https://good-webhooks.dev/docs/upgrading/from-0x

1.0.0-rc.1 is out on the `rc` tag and needs no code change or SQL from 0.7.0. 1.0.0 is planned for early December 2026 and is planned to need none either.

Read the sections in order from the version you run. Each one lists the breaking changes and the steps for that release. Follow the [rollout order](https://good-webhooks.dev/docs/operations/migrations.md#rollout-order) whenever a step needs SQL.

## 0.4.x to 0.5.0 [#04x-to-050]

0.5.0 is a breaking minor that moves the schema to version 6. [Changelog](https://github.com/pplytas/good-webhooks/blob/main/CHANGELOG.md#050-2026-10-26).

Breaking changes:

- `check()` refuses schema 5.
- A pause resets the delivery's retry window ([ADR 0015](https://github.com/pplytas/good-webhooks/blob/main/docs/adr/0015-pause-resets-delivery-window.md)). Paused deliveries keep their full `retry.maxAgeMs` after resume, and a worker must run during the pause.
- `ManagementRepository.create(scope, endpoint, { limit })` takes an options object instead of a third `limit` argument.
- `StoredEndpoint` gains `encryptedHeaders`.
- Built-in management needs no code change.

Steps:

1. Run `getPostgresUpgrade({ from: 5 })` or `migrations/upgrades/006-all.sql`. The step locks the deliveries table while it backfills, so prune first. Older schemas and separate namespaces are covered in [migrations](https://good-webhooks.dev/docs/operations/migrations.md#upgrades).
2. With Better Auth, run your Better Auth migration for the new optional `encryptedHeaders` field.
3. Restart producers, then workers, on 0.5.0.
4. A custom `ManagementRepository` implements `create(scope, endpoint, { limit })` and enforces the limit.
5. A custom `ManagementRepository` stores `StoredEndpoint.encryptedHeaders` as is.

## 0.5.0 to 0.6.0 [#050-to-060]

0.6.0 needs no SQL and has no breaking changes. [Changelog](https://github.com/pplytas/good-webhooks/blob/main/CHANGELOG.md#060-2026-10-27).

Changed behavior:

- Management reads decrypt stored headers. A rotated standalone storage key needs `decryptionKeys` for `get()` and `list()` too.
- The worker sends headers that a custom `EndpointSource` returns, and defers a delivery when a header uses a reserved name.

Steps:

1. Restart producers, then workers, on 0.6.0. Better Auth needs no migration.
2. If you [rotated the standalone storage key](https://good-webhooks.dev/docs/operations/key-rotation.md#rotate-the-standalone-storage-key), keep the old key in `decryptionKeys` wherever management calls `get()` or `list()`.
3. A custom `EndpointSource` that returns headers must avoid the [reserved names](https://good-webhooks.dev/docs/guides/endpoints.md#send-extra-headers), because the worker defers a delivery that carries one.

## 0.6.0 to 0.7.0 [#060-to-070]

0.7.0 adds no features and changes no default. It moves the schema to version 7 for one index that keeps `prune()` fast on large history ([#153](https://github.com/pplytas/good-webhooks/issues/153)). [Changelog](https://github.com/pplytas/good-webhooks/blob/main/CHANGELOG.md#070-2026-11-02).

Breaking changes:

- `check()` refuses schema 6.

Steps:

1. Run `getPostgresUpgrade({ from: 6 })` or `migrations/upgrades/007-all.sql`. Building the index blocks writes to the deliveries table while it reads the table once. On a large table, [build it concurrently first](https://good-webhooks.dev/docs/operations/migrations.md#upgrades).
2. Restart producers, then workers, on 0.7.0. Better Auth needs no migration.

## 0.7.0 to 1.0.0 [#070-to-100]

1.0.0-rc.1 has no breaking changes, no code change, and no SQL. It keeps schema 7. [Changelog](https://github.com/pplytas/good-webhooks/blob/main/CHANGELOG.md#100-rc1-2026-11-02).

Steps:

1. Install `good-webhooks@rc` and restart producers, then workers. Better Auth needs no migration.

Moving from 1.0.0-rc.1 to 1.0.0 is planned to need no migration.
