P.4.2 Release Cadence & LTS

recommended

When you work in a Bazel repository, you choose both a build command and the Bazel release stream the repo lives on. Bazel ships rolling releases and long-term-support major releases, and most teams deliberately pin one exact version with Bazelisk rather than following whatever binary happens to be newest on a developer laptop.1,2

Preview the next Bazel major, then pin the version your team uses
Rolling releases expose upcoming behavior. Each major version becomes an LTS line. Bazelisk keeps the repository on one exact binary.
HEAD
Bazel development continues
New work can include incompatible changes
ROLLING PREVIEW
Cuts from HEAD show the next major early
Roughly every two weeks. Useful for canary CI.
NEXT MAJOR LTS
A new supported line starts roughly yearly
active maintenance deprecated
MIGRATION RUNWAY BEFORE THE MAJOR
--incompatible_*
Tests a planned breaking behavior early. Its tracking issue should explain the change and migration.
--experimental_*
Can change at any time. Treat it as experimentation, not the shared production baseline.
DAY-TO-DAY TEAM DEFAULT
Commit one exact version. Let Bazelisk run it everywhere.
.bazelversionexample
9.2.0
Developers and CI use the same binary. Keep floating labels such as rolling and last_rc in canary jobs, not shared mainline builds.
Preview future behavior, migrate deliberately, then pin one exact team version.

Two Release Tracks

Bazel's rolling releases come from HEAD on roughly a two-week rhythm. They preview the next major line and can include incompatible changes. Separately, Bazel cuts a new major release roughly every 12 months, and each major is an LTS line with its own support lifecycle.1

That lifecycle matters more than memorizing current version numbers. An LTS line moves through stages such as Active, Maintenance, and eventually Deprecated. The exact support matrix changes over time, so the live release page matters more than a stale mental list of which majors are still supported today.1

Why Major Upgrades Are Not Sudden

Major versions can break compatibility, but Bazel tries to make those breaks visible before the major ships. The usual mechanism is an --incompatible_* flag plus a GitHub issue describing the change and a migration recipe. The recommended pattern is to back-port the flag to the current LTS without turning it on by default, which gives teams a window to test the future behavior early instead of discovering it only after the upgrade.3

--experimental_* flags are a different category: they can change at any time. That is why experimental or incompatible flags should not be used for production builds.3

Why Bazelisk Belongs In The Story

The Bazel binary itself is part of the build environment. If one machine runs the pinned LTS and another runs a release candidate or newer major, the same repository can behave differently. Bazelisk reads .bazelversion, fetches the requested Bazel binary, and runs that exact version. The mechanics are covered in 0.1.1 Bazelisk & .bazelversion.2

Bazelisk also understands preview channels such as rolling and last_rc, plus floating series pins like 8.x that track the latest release in an LTS line. Those are useful for canaries and compatibility checks, but they are a poor default for day-to-day team builds because they reintroduce version drift.2

LTS Buys Coordination Time

LTS gives the rest of the ecosystem a coordination point: rulesets, custom macros, CI jobs, wrappers, and toolchains all need time to stay compatible across majors. Rulesets are expected to keep their own migrations manageable so users are not forced to upgrade a ruleset's major version and Bazel's major version at the same time.4

A major LTS often becomes the boundary where broader ecosystem migrations stop being optional and become the new default. Bazel 8 was one example of that pattern.5

A Bazel upgrade is usually planned work. Keep the repository pinned to one exact version, test the next major early, and then use a deliberate migration playbook when you are ready to move. The operational side of that playbook starts in M4 Bazel Version Upgrades.3,4

key takeaway

Release cadence is part of how Bazel is meant to be used. Rolling releases show where HEAD is going, LTS releases give teams a stable, supported release line, --incompatible_* flags provide time to test migrations, and Bazelisk uses the version recorded in the repository instead of leaving the choice to each developer's machine.

Check your understanding · 3 questions

1.Match each part of Bazel's release model to its description:

Drag each answer onto the matching prompt, or click an answer and then click a prompt

Answers
Rolling releases
LTS major release
--incompatible_* flags
--experimental_* flags

2.Why do most teams pin one exact Bazel version with Bazelisk rather than using the newest binary on each machine?

Select one answer

3.True or false: managing Bazel versions safely.

Choose True or False for each sentence

--experimental_* flags are a safe baseline for production builds.
--incompatible_* flags are a temporary migration aid, not something to leave on permanently in production builds.
Floating pins like rolling, last_rc, or 8.x are best used for canaries and upgrade rehearsals, not as the default team pin.
A breaking change typically appears first behind an --incompatible_* flag with a migration recipe before the next major ships.
0 of 3 answered

Footnotes

  1. Release Model — rolling vs LTS tracks, support stages, and expected release cadence 1 2 3 4

  2. Bazelisk — A user-friendly launcher for Bazel.bazelversion, exact pinning, and preview-oriented version labels such as rolling and last_rc 1 2 3 4

  3. Backward Compatibility--incompatible_* flags, migration recipes, and guidance for production use 1 2 3

  4. Rule Compatibility — why rulesets try to keep Bazel upgrades manageable instead of forcing simultaneous major jumps 1 2

  5. Bazel 8.0 LTS Release Blog Post — Bazel 8 as a concrete example of an LTS release carrying ecosystem-level migration milestones