Code freezes are a confession
A code freeze is a public statement that you don't trust your own safety mechanisms. It gets described as prudence before a busy period, and what it actually does is stockpile every change until the system is under the most load, then release them all at once.
Every year, somewhere around the middle of November, an email goes out. No merges to main from the fifteenth until the new year, except for approved hotfixes. Please plan accordingly.
Nobody replies to argue. It reads like responsibility, and whoever wrote it has probably been paged over a holiday before, so it is hard to begrudge them.
I'd still take it out.
The claim, stated plainly
A code freeze is a public statement that you do not trust your own safety mechanisms.
People describe it as prudence before a high-traffic period, and what it actually does is batch up every change until the moment the system is under the most load, then release them together.
Long-lived release branches, same confession. Different format.
If you can't ship on the busiest day of the year, the freeze is not the fix. It's the symptom, written down and circulated to the whole company with a date range attached.
What the freeze actually does
Follow the changes, not the calendar.
Engineers keep working during a freeze, because the roadmap didn't freeze and neither did their manager's expectations, so the work piles up on branches (one per person, or one per feature) with each drifting a little further from main every day it sits unmerged.
Then the freeze lifts, all at once. Three or four weeks of accumulated change goes out in the space of a few days, into a system nobody has deployed to in a month, with everybody out of practice at deploying to it.
The batch. That is what hurts you.
Forty changes land together and production breaks at 2am. You know that much. Which one did it, you don't know. Every one of those changes might have been fine on its own, and the one that wasn't is now hiding among thirty-nine that were, while the person who wrote it has half forgotten what it touched.
So no, the freeze doesn't remove risk. It moves it a few weeks down the calendar and concentrates it. You traded a steady trickle of small, attributable changes for one large, unattributable one and scheduled it for right after the busiest period of the year, when the team is tired and traffic hasn't fully gone back to normal.
I've written about the mechanics of why big batches fail out of proportion to their size elsewhere. A freeze is the purest example of it. A policy whose only output is a bigger batch.
The branch is the same confession
Freezes are the visible version. Long-lived branches are the quiet one. And everywhere.
My rule is trunk-based, with branches measured in hours or days and never weeks. A long-lived feature branch is a process for accumulating risk and calling it safety.
Branch lifetime and merge pain rise together. Not linearly, either. Six weeks on a branch means negotiating with six weeks of everyone else's work, and every rebase is a small bet that you understood what changed underneath you, and the bets compound.
There's a second cost that nobody puts in the risk register. A branch converts a reversible decision into an irreversible one, because stakeholders attach to it until cancelling becomes a social event. Six weeks in, somebody has demoed it. Someone else has told a customer. Killing it now means a conversation with three people who have already told their own bosses it's coming. Throwing the code away would take a minute. The commitment, not so much.
Always the same objection: the feature isn't done.
Which is exactly what flags are for.
Deploying is not releasing
Everything here rests on separating two decisions that most orgs still treat as one.
Merges go to production automatically, with no human deploy step, on the condition that production means dark behind a flag. That condition is the whole answer.
Nobody removes the human step. It moves, from "is this safe to deploy" to "is this ready to expose," and for most changes even the second decision is automated through percentage rollout, canary, and automatic rollback on a metric threshold.
Put that way, the freeze stops making sense. A change that ships dark on the busiest day of the year does nothing on the busiest day of the year. Sits in production behind a flag that's off, carrying no traffic. What you were freezing to avoid was the risk of exposure, and exposure was never tied to the merge in the first place.
If you want caution over a busy period, be cautious about the flags. Don't turn on anything big the week before a launch. A reasonable call, and it costs you nothing, because the code keeps flowing and the batch never builds.
Making this possible is its own piece of work. The deploy pipeline as a safety net covers flags, rollback and progressive delivery in the order worth adopting them, and straight to production covers what has to be true before you can delete the environments sitting in between.
The honest exception
There is one, and I'd rather name it than pretend the argument has no edges.
The one-way door. Anything touching money, auth, or data in a way that can't be reversed. A migration that drops a column, a change to how payments settle, deleting the old path in a cutover.
Slower rollout for those. A second pair of eyes, too. On the release side, though, not as a merge checkpoint. The merge still flows. What slows down is the moment of exposure, because that's where being wrong costs more than any rollback can fix.
Notice what that exception doesn't justify. Not the dependency bump, not the copy change, not the new internal dashboard or the thousand other changes that can be undone in seconds. A freeze treats every change like a one-way door because the org can't tell which ones are, and that's the real problem: a classification problem, not a calendar problem.
Nobody has to approve the agent's merge makes the same cut for merge approval. Blast radius, not authorship. Reversibility, not the date.
What to fix instead
Holding merges because you don't trust the pipeline is a safety net problem wearing a process costume.
So fix the safety net. Specifically, find out which of these isn't true yet:
- Every change ships behind a flag, so merging and exposing are separate decisions.
- Rollback is measured in seconds, and somebody has actually rehearsed it this quarter.
- Rollout is staged, with a canary that can stop itself on a metric.
- The test suite tells the truth, so green means something. That one is the prerequisite for everything else.
Whichever one is missing is the reason you want a freeze. It is also the thing the freeze will never build for you, since a month of not deploying is a month of nobody practising the thing you're afraid of.
If the pipeline can't ship every merge without ceremony, fix the pipeline rather than growing longer branches or longer freezes to compensate.
The test
Look at your calendar for the next busy period. Picture shipping a fix at the peak of it, and be honest about whether you'd trust the path that fix takes to production.
If you would, you don't need the freeze. Simple as that.
If you wouldn't, you have a much bigger problem than the freeze was ever going to solve, because a real incident at peak doesn't wait for January and you'll be shipping through that path anyway, under pressure, with the least practice you've had all year.
That's what the email in November is really saying. It just says it about the pipeline instead of about the people who own it.