Production and deployment

Deploy, migrate, and roll back

Ship a versioned Worker and its data changes in a compatible order with a tested recovery path.

Rolling back a Worker takes one command. Rolling back the data it wrote does not. So deploying safely means keeping the database and the message formats compatible with both the old and the new version, for as long as a rollback is possible.

Versions and deployments

Every wrangler deploy creates a version, a snapshot of your code, assets, bindings, and compatibility settings, and makes it the active deployment. Give it a message so you can tell versions apart later:

npx wrangler deploy --message "Add optional link description"
npx wrangler deployments list

The list shows each version’s ID, when it went live, and who deployed it. Save the ID of what you just shipped.

Expand, deploy, observe, contract

Say we want to add a description column to links. Here is the order that keeps both versions happy:

  1. Apply an additive migration: ALTER TABLE links ADD COLUMN description TEXT. Nullable. The old version ignores it and keeps working.
  2. Deploy code that reads and writes description but tolerates NULL.
  3. Watch logs and error rates for your whole rollback window. A day is a good default.
  4. Only then, in a later release, make the column required or remove old fields.

Code first, migration second, and the new version crashes on a column that doesn’t exist yet.

Version your queue messages

During a rollout, an old producer and a new consumer may run at the same time. Or the reverse, after a rollback. That’s why the export message carries version: 1. A consumer that gets a version it doesn’t understand logs it and sends it to the dead-letter queue instead of guessing.

What rollback does and doesn’t do

npx wrangler rollback

This makes an earlier version the active deployment. Every route switches at once.

It changes code only. D1 rows, KV values, R2 objects, delivered queue messages, and calls to external APIs stay as they are. If the new version wrote data the old version can’t read, the rollback restores the old bug and adds a new one.

Rollback can also refuse. If the old version expected a binding or a Durable Object class that no longer exists in your config, there is nothing valid to roll back to. Test the rollback while those dependencies still exist.

Smoke test both directions

After a deployment, run the smoke test from the testing lesson: health route, one request per binding. After a rollback, run it again. Then fix the code in Git, or the next wrangler deploy ships the same broken version right back.

Now write the release sequence for the description column: the migration file, the code change, the smoke test commands, the version ID you’d roll back to, and what you’d check afterwards. Then run it against staging for real.

Lesson completed