Feature flags and staged rollouts: when do you announce?

Feature flags broke the word “shipped.” It used to name a moment — the release went out, everyone got it, you wrote the entry. With flags and staged rollouts, shipping is a dial: the code has been in production for weeks, 5% of accounts have the feature, a beta cohort has a different version of it, and the default flips next Tuesday. A changelog is a record of what changed for the reader — so which of those moments gets the entry? This guide is about announcing features not everyone can see yet: when the entry goes live, what it says mid-rollout, why experiments are a special case, and what to write when the dial goes backwards.

The rule: announce what the reader can verify

Every changelog entry makes a checkable claim: this is different now. Trust comes from the check passing. Publish “New: bulk export” while 10% of accounts have it and you’ve shipped a statement that is false for nine readers out of ten — they open the app, there’s no bulk export, and they conclude either that your changelog is unreliable or that the feature is broken. Both conclusions cost you; the second also costs your support team, who now field “where is it?” tickets about a feature working exactly as intended.

So the default rule is one sentence: the entry goes live when its claim is true for the people reading it. For a public changelog, that means general availability. For a beta cohort’s stream, cohort-complete. Not at merge, not at first-percent, not when the keynote says it. Everything else in this guide is footnotes to that rule — including the honest ways to bend it when a three-week rollout or a marketing date forces your hand.

What each rollout stage owes the changelog

A flagged feature passes through recognizable stages. Each has a comms answer:

  • Dark launch — code in production, flag off. Silence. Nothing changed for any reader, and the changelog is not a build log. This is the right moment to write the entry, though: the person who shipped it has the facts fresh (the same write-at-merge logic as changelog ownership) — you just don’t publish yet.
  • Internal dogfood. An entry, but in the internal changelog: support and sales need to know a flagged feature exists before the first customer mentions it.
  • Private beta cohort. Announce to the cohort — a beta stream with its own feed, per the beta release notes playbook — not on the public page, where it’s a claim most readers can’t verify.
  • Opt-in early access. The one pre-GA stage that earns a public entry, because the claim is verifiable by everyone: “New in Labs: bulk export — turn it on under Settings → Labs.” Every reader can run that check, and it passes. Label it clearly and say what “early access” means for stability (publish the contract).
  • Percentage rollout. The hard case — next section.
  • General availability. The entry, dated at GA. Not backdated to the merge: readers experience the change on flip day, so flip day is the announcement date.
  • Flag cleanup. Silence again — deleting a flag that was 100%-on changes nothing. One exception: if cleanup changes behavior for anyone who had the flag off (an opt-out that stops being honored), that’s a real change and it gets a real entry.

The mid-rollout entry, done honestly

Sometimes you can’t wait for 100%. The rollout takes three weeks; the launch post, the conference demo, or the staged store rollout already told the world. Announcing mid-rollout is fine — hedging is not. An honest mid-rollout entry states three things:

  • The span. “Rolling out to all accounts over the next two weeks” — a date range, not a shrug. If you don’t know the end date, you’re not ready to announce.
  • The tell. How a reader knows they have it: “you’ll see an Export button on the project page.” This one line converts “is it broken for me?” tickets into a self-serve check.
  • The now-path, if one exists. Opt-in toggle, waitlist, or “contact us to enable early” — give the excited reader something to do besides refresh.

Put together:

New: bulk export — rolling out now

Export every post in a project as CSV or JSON. Rolling out to all
accounts between <date> and <date>; you have it when an Export
button appears on the project page. Want it sooner? Turn on early
access under Settings → Labs.

Then edit the entry when the rollout completes — same URL, updated in place, the way hotfix entries get their second pass. “Rolling out over the next two weeks” still sitting on the page in November is a small lie with a timestamp.

Support sees the seam

Staged rollouts quietly break a load-bearing assumption: that a version number identifies behavior. During a rollout, two users on the same version live in different products, and “what version are you on?” stops being a useful support question. The changelog is where that gets repaired — the entry’s tell gives support a one-line diagnostic (“do you see the Export button?”), and the entry’s permalink gives them one canonical URL to answer with. If your rollout tooling can say which cohort an account is in, put that lookup in the internal entry; the public one just needs the visible check.

When the dial goes backwards

Flags exist so you can turn things off. The comms failure isn’t the rollback — it’s the changelog still claiming everyone has a feature that’s currently disabled. If you roll back a flag after announcing:

  • Update the entry, in place, the same day. A dated note at the top: “Update <date>: we’ve temporarily disabled bulk export while we fix an issue with large projects. Your data is unaffected; back within a week.”
  • Never silently delete the entry. People linked it, support quoted it, feeds delivered it. A vanished announcement reads as a cover-up; an updated one reads as a team paying attention (the never-fix-silently rule, mirrored).
  • Close the loop. When it re-ships, a short new entry links back: “Bulk export is back on for everyone — here’s what we fixed.”

Experiments never get entries

A/B tests look like staged rollouts — same flags, same percentages — but they make the opposite promise. A rollout is a decision being delivered; an experiment is a decision being made, and half of them end in “no” by design. Announce an experiment and you’ve pre-committed publicly to an outcome you haven’t chosen: now the losing variant’s rollback needs a removal announcement for a feature that never officially existed. So: announce the decision, not the experiment. The changelog entry ships when the winning variant becomes the product.

Two boundaries keep this honest. First, an experiment that runs long enough to become the de-facto product for its cohort has stopped being an experiment — decide, then announce. Second, some things should never be silently experimented on at all: prices, data handling, permissions. Users who discover they were in a pricing or policy test cohort don’t call it an experiment; they call it something worse.

Flags as migration levers

Flags aren’t only for launches — they’re the best breaking-change tool you have, because they decouple the code shipping from each user’s behavior changing. The pattern: ship both behaviors behind a flag, announce the coming default flip with dates, let people opt in early (they test on their schedule, not yours), then flip the default, then remove the old path per your deprecation policy. Each user gets to choose when their product changes inside your window — which converts one big surprise into many small consents.

The changelog dates in that sequence follow the reader, not the repo: the announcement entry is dated when the opt-in appears, the change entry is dated on default-flip day — even if the code shipped a quarter earlier. A default flip is a real change for everyone who never touched the toggle, which is most people; give it a full entry with the rollback line (“to keep the old behavior, turn off X in Settings until <sunset date>”).

Six anti-patterns

Announcing at merge. The entry ships with the deploy, three weeks before the flag opens. Every reader who checks finds nothing. This is what “announce when usable” exists to prevent.

The keynote-changelog gap. Marketing announces on stage; the changelog says nothing for a month; support triangulates from tweets. Whatever moment you choose to announce, all channels point at one canonical entry, same day.

The eternal “rolling out.” A hedge with no dates that never gets updated. If every launch entry says “rolling out gradually,” readers learn that your announcements mean nothing yet — the boy who cried partial.

The vanished announcement. Flag rolled back, entry quietly deleted. Feeds already delivered it; screenshots exist. Update in place instead.

The flag firehose. An entry for every flag change — 5%, 20%, 50%, oops back to 20%… That’s an ops log, and it belongs next to your deploys, not in front of users. One entry per user-meaningful moment.

Announcing the experiment. “We’re testing a new dashboard with some users!” Now the control group feels excluded, the test group feels watched, and the rollback needs a eulogy. Decide first.

How this maps onto Wakelog

Drafts and scheduled publishing are the flag workflow, mechanized. Write the entry at merge time when the facts are fresh — wakelog post --draft from the deploy script, or a curl from CI — and it sits invisible next to the dark-launched code. When the rollout has a planned GA date, schedule it: publish_at takes an ISO timestamp and the entry goes live on flip day with the right date, no human awake. When GA is “whenever the metrics look good,” the same pipeline that turns the dial to 100% flips the entry live with one PATCH call (draft=false). Rollback notes are ordinary edits — permalinks are stable, so the URL support quoted keeps telling the truth. One honest caveat: Wakelog doesn’t integrate with your flag provider — the flip-the-entry-when-the-flag-flips call is a one-line curl you wire into your own rollout script.

Start your changelog — free   Next: channels and timing for launches →

Related guides

Last updated 2026-07-30 · All guides