The Peak-Season Code Freeze Is a Symptom, Not a Strategy
The 6-week code freeze exists because nobody trusts the deploy pipeline, and the calendar is the only control left. Build that trust by October and the freeze shrinks to a 2-week window scoped to genuinely irreversible changes, at almost no cost to the roadmap.
The email goes out around mid-October. No production changes from mid-November to the first week of January, exceptions need a director's sign-off, and every team quietly opens a January branch that will rot for 7 weeks.
I have read a version of that email at every retailer I have worked with. The intent is sound, since peak traffic is when a self-inflicted outage costs the most.
The mechanism is the problem, because a freeze does not reduce change. It reduces practiced change.
What a freeze actually tells you
A blanket deploy freeze prices every deploy as equally dangerous. That is only a rational price when you cannot tell your safe deploys from your risky ones, and that inability is the real finding.
Teams with automated deploys, canary analysis, and rehearsed rollbacks know the blast radius of a change before it ships. Teams without those things know only that some deploys have hurt them before, so all deploys get banned in November.
DORA's capability page on deployment automation describes the target state plainly: deployments automated to the point of needing no manual intervention, done the same way in every environment. A deploy like that is a repeatable operation, and repeatable operations do not need a calendar to be safe.
A freeze does not stop change during peak. Config still changes, vendor tags still change, traffic grows by an order of magnitude, and data volumes hit yearly highs. The freeze stops only the one kind of change you fully control and can rehearse.
The freeze paradox: your riskiest deploy of the year happens inside the freeze
Something always breaks in the freeze window. A payment edge case, a tax rounding bug, a crash on the December iOS point release.
Now the fix ships through an exception process: reviewed under time pressure, deployed into the year's highest traffic, by a team that has not deployed in 3 weeks and whose muscle memory has faded. Every property of that deploy is worse than a routine Tuesday release in October.
This is the strongest argument against the long freeze. It does not remove your riskiest deploy of the year. It manufactures it.
The changes the freeze cannot see
Walk through the incidents you actually had last peak. In my experience the deploy that the freeze would have blocked is rarely the trigger.
The trigger is a marketing team publishing a new tag through the tag manager on the Wednesday before the sale. Or a promotion configured with a stacking rule nobody tested, a third-party script vendor shipping their own update on their own schedule, or a search index rebuild that behaves differently at 4x the catalog churn.
Every one of those is a production change, and none of them passes through the deploy pipeline the freeze governs. A freeze policy that ignores them is guarding the front door of a house with no walls.
The fix is to widen what counts as a deploy, not to widen the freeze.
- Put application config in version control with the same review gate as code, so a promo rule change has an author, a diff, and a revert path.
- Treat the tag manager as a deploy surface with named approvers during peak, because it injects arbitrary script into your highest-traffic pages.
- Subscribe to the change feeds of your critical third parties, since their deploy calendar does not care about yours.
- Rehearse against peak-shaped data volumes, because a query plan that flips on a table 3x its October size is a production change nobody committed.
What to harden by October
4 workstreams, all startable in early September and finishable before the window opens. None require replatforming, and each one shrinks the freeze you will still want.
1. Deploy automation and the rollback drill
The question is not "can we roll back". The question is how many minutes a rollback takes, measured, this quarter, by the person who will be on call.
If nobody can answer with a number, you have a rollback theory, not a rollback capability. Run the drill on production.
- Deploy a harmless change through the normal pipeline, not a shortcut path.
- Have the on-call engineer, not the release owner, execute the rollback.
- Time it from decision to healthy metrics, and write the number down where the incident channel can find it.
- Repeat until the number is boring, then repeat monthly so it stays boring.
If the drill surfaces a schema migration that cannot be reversed, you have found your real November risk. It had nothing to do with deploy frequency.
2. Canary before you trust, and automate the judgment
The Google SRE workbook chapter on canarying releases frames the practice as a controlled experiment: expose a small fraction of traffic to the new version, compare it against control, and promote or abort on evidence. The chapter's caution is the useful part, because a canary without defined evaluation metrics is just a slower deploy with better branding.
Tooling here is commodity now. Argo Rollouts gives Kubernetes teams canary and blue-green strategies with analysis runs against real metric providers, and it aborts and rolls back automatically when the analysis fails.
The specific controller matters less than the property. Promotion decisions move from a human's gut on a Friday afternoon to a metric query that runs identically in week 46 and week 12.
3. Feature flags: deploy is not release
A flag-gated feature can be deployed in November with zero user exposure and released in January with zero deploys. That single property dissolves most of what a freeze is for, because the risky half of shipping, activation, becomes independently controlled and reversible in seconds.
The discipline has a spec now. OpenFeature, a CNCF project, defines a vendor-neutral API for flag evaluation, which turns flagging into an architectural layer rather than a point tool each team bolts on differently.
Before peak, the flag work is an inventory pass, not a build-out.
- List every flag that can shed non-essential load: recommendations, search suggestions, loyalty widgets, review imports, chat.
- Flip each one in production, this month, and record who owns it and what turning it off actually does.
- Delete expired flags. A stale flag nobody understands is a loaded weapon in the middle of an incident.
- Confirm the flag system itself fails safe when its backing store is unreachable.
A feature flag you have never flipped in production is a hypothesis. The week you flip it for real is the week you find the cache that ignores it.
4. Pin the dependencies, slow the treadmill
A build that resolves dependencies at install time can change underneath you with no commit anywhere. Lockfiles close that hole, and npm's package-lock.json documentation is explicit about the guarantee: subsequent installs produce the identical dependency tree regardless of intermediate updates to those dependencies.
Commit the lockfile, install from it in CI, and make the November rule "no dependency updates except security patches". GitHub's Dependabot supports exactly that split, with version updates on a schedule you can slow for Q4 while security updates keep flowing.
The split matters because freezing a known-vulnerable dependency through Black Friday is not caution. It is exposure with a process wrapped around it.
The freeze you should still run
None of this argues for zero freeze. It argues for a precise one, scoped by change category rather than by a blanket date range.
| Change type | Peak-window policy | Why |
|---|---|---|
| Schema migrations | Freeze | Hard to reverse, lock-heavy on the year's largest tables |
| Infrastructure topology: DNS, load balancers, regions | Freeze | Failure modes are global and slow to diagnose |
| Framework and runtime upgrades | Freeze | Broad blast radius, no user-facing urgency |
| Dependency version bumps | Freeze, except security patches | Reproducibility beats freshness for 4 weeks |
| Flag-gated application code | Ship normally | Deployed dark; activation is a flag, reversible in seconds |
| Bug fixes on the purchase funnel | Ship normally, canaried | The alternative is a rushed exception deploy later |
| Content, pricing, merchandising config | Ship normally, with an audit trail | It will change during peak anyway; pretending otherwise just hides it |
A 2-week window of that shape protects the genuinely irreversible changes without benching the whole team. It also keeps the deploy muscle warm for the hotfix you will inevitably need.
The freeze scoped by change category: 4 classes freeze for 2 weeks, everything below the line keeps shipping under guardrails.
The September-to-October calendar
Working backward from a window that opens in mid-November, this is the sequencing I would run.
- Early September: rollback drill on production, timed. Fix whatever it surfaces, because that fix is the highest-value peak-prep work available.
- Late September: flag inventory, production flips of every load-shedding flag, deletion of expired flags.
- Early October: canary analysis wired to real metrics, then 2 routine releases promoted through it to prove the path.
- Late October: lockfile and update-cadence changes, final funnel fixes, and publication of the scoped freeze policy with named exception approvers.
The output of that last step is 1 page: which categories freeze, who approves exceptions, and the measured rollback time everyone can rely on. That page is the difference between a freeze policy and a freeze superstition.
FAQ
Our commerce platform freezes its own changes over BFCM. Doesn't that validate the blanket freeze?
A platform freezing infrastructure changes underneath other people's peak load is scoping by category, which is the model argued here. Copy the scoping, not the blanket.
Leadership wants the freeze for accountability, not for engineering reasons. Then what?
Offer the category table and the measured rollback number instead of a date range. "We can revert any application change in a known number of minutes, and here is the drill log" is a stronger control than a calendar, and it reads that way to auditors too.
We have none of the 4 capabilities and it is already November. Now what?
Freeze broadly this year, without guilt. Book the production rollback drill for the first week of January while the pain is fresh, because this is a September argument and the decision for this year was made in September.
Don't feature flags add their own risk?
Unmanaged, yes: stale flags and untested combinations are real failure sources. That argues for flag hygiene with owners and expiry dates, not for coupling every release to a deploy during the most expensive weeks of the year.
What about mobile apps, where rollback is not ours to control?
App-store review latency makes the binary the one artifact that genuinely deserves an early freeze. Ship the last binary in early November, and keep everything you might need to change behind server-driven config and flags.