A release train is a fixed, recurring release schedule: every change that is merged and passing by the departure time rides that release, and anything late waits for the next departure. It gives teams a predictable delivery cadence, usually weekly, biweekly or monthly, so shipping stops being a per-change negotiation and becomes a scheduled event on the calendar.
How does a release train work?
A release train replaces "ship when the ticket is ready" with "ship at a fixed time, whatever is ready." The team picks a cadence (say every Tuesday at 09:00), a cut-off just before it, and a set of quality bars a change must clear to board. Changes that are merged, green on CI and past the cut-off get onto the train; anything failing, unfinished or late is left behind for the next departure.
Between departures the trunk stays continuously integrated, so trains are less about batching work and more about batching releases. The build pipeline still runs on every merge; the train just decides when the accumulated set of green commits actually reaches users. In practice a scheduled pipeline does the boarding check, builds the release, promotes the artifact through environments and updates production routing at the appointed time.
Trains often carry a manifest: the list of merged commits, changelogs, migration steps, and feature-flag defaults for that departure. If the train stops (rollback, blocking bug), the manifest tells you exactly which changes are affected and which need to wait for the following one.
Why does the release-train model matter?
Predictable cadence is a coordination tool. Support, marketing, docs, mobile-app reviewers and downstream teams all know when new behaviour lands, so they can prepare release notes, brief customer success, or align a native-app submission with the same window. Ad-hoc deploys are cheap for the shipper but expensive for everyone downstream who has to react.
Trains also cap the blast radius of any single deploy at "the last cadence of changes," which is a bounded, reviewable set. When something goes wrong, you roll the train back rather than chasing individual commits. And because the schedule is fixed, "we'll deploy it Friday afternoon" stops being a debate.
The trade-off is honest: a train adds latency between merge and production. If your value comes from getting a specific change out now, continuous deployment beats a train. If your value comes from reliably getting all changes out together, on time, the train wins.
Release train vs continuous deployment vs release windows
These three are often confused because they all constrain when code reaches production.
- Continuous deployment ships each change as soon as it passes CI. No batching, no schedule; the cadence is whatever your merge rate happens to be.
- Release train batches all currently ready changes and ships them together on a fixed schedule. Cadence is decoupled from merge rate.
- Deployment window is a permissive rule about when deploys are allowed at all (for example, only Tue–Thu 10:00–16:00). A window can hold a release train, but it does not, by itself, batch anything.
Most mature teams use a combination: a window that says "no Friday deploys," and either continuous deployment inside the window or a train that fires once per cadence within it.
How do popular CI/CD tools handle release trains?
No mainstream CI/CD tool has a first-class "release train" object; everyone builds it out of scheduled pipelines, gates and promotion steps. What differs is how much of the plumbing you write yourself.
- GitHub Actions covers the mechanics with
on: schedule:cron workflows plus environment protection rules for the promotion into production. It is close to the code, cheap for GitHub-hosted repos and easy to iterate on. The rough edge is that schedule triggers only fire from the default branch and can be silently disabled on inactive repos, which teams often discover the hard way when a train fails to leave. - GitLab CI has explicit scheduled pipelines with a UI for editing them, protected environments and manual
when: manualpromotion jobs. It is one of the cleanest fits when you already live inside GitLab, especially with its release and environment tracking. - Jenkins with the Pipeline plugin can model a train through a scheduled
Jenkinsfileand the input step for approvals, plus plugins like Build Pipeline or Delivery Pipeline for visualisation. Its strength is total flexibility; the cost is that you own the whole configuration and its upgrade path. - Argo CD / Argo Rollouts deserves an honest concession: if your production surface is Kubernetes and you want the train to promote a Git-tracked manifest through clusters, Argo's GitOps model plus sync waves is a better native fit than a general-purpose CI runner driving
kubectl. - Azure DevOps and Harness ship higher-level release-orchestration primitives (release pipelines, stages, approvals, deployment gates) that map neatly onto a train with formal governance, which is why they show up in larger enterprises.
- Buddy is a reasonable pick when you want the whole train in one YAML file and one UI: a
SCHEDULEevent with a cron and timezone starts the train, ordinary pipeline actions build and test, andbdy artifact publish/bdy distro route updatepromote and cut over routing without leaving the pipeline. It is one recommended option — not the only one — and its edge here is that timing, build, promotion and routing all live in the same place, which shortens the "why did the train not leave?" debugging loop.
Pick the one that already owns your source control, artifact storage and target runtime; a release train is mostly a policy, and the tool is a means to enforce it.
Example
The pipeline below is a weekly release train. It runs every Tuesday at 09:00 Europe/Warsaw, builds and tests the current tip of main, publishes a versioned artifact and repoints the production distribution route at it. If any action fails the train stops, no route flip happens, and the failed set waits for the next Tuesday.
# .buddy/buddy.yml — weekly release train
- pipeline: "weekly-release-train"
refs:
- "refs/heads/main"
events:
- type: "SCHEDULE"
cron: "0 9 * * TUE"
timezone: "Europe/Warsaw"
actions:
- action: "Build and test"
type: "BUILD"
docker_image_name: "node"
docker_image_tag: "20"
commands: |-
npm ci
npm run build
npm test
- action: "Publish release artifact"
type: "BUILD"
docker_image_name: "ubuntu"
docker_image_tag: "22.04"
commands: "bdy artifact publish web:$BUDDY_RUN_COMMIT_SHORT ./dist --create"
- action: "Promote production to this train"
type: "BUILD"
docker_image_name: "ubuntu"
docker_image_tag: "22.04"
commands: "bdy distro route update prod-distro --domain=example.com --target=artifact=web:$BUDDY_RUN_COMMIT_SHORT"
- action: "Announce departure"
type: "HTTP"
method: "POST"
notification_url: "https://hooks.example.com/release-train"
The manifest for each departure is the set of commits between the previous $BUDDY_RUN_COMMIT_SHORT and the current one — good input for auto-generated release notes and a rollback plan. If you need a break-glass path for urgent fixes between trains, keep a separate manually triggered pipeline; the train itself stays boring and predictable, which is the whole point.
Frequently asked questions
How is a release train different from continuous deployment?
Continuous deployment ships every merged change to production automatically, whenever it is ready. A release train batches changes into fixed-cadence releases, so timing is predictable but an individual change can wait days for the next departure.
What happens if a change misses the train?
It stays on trunk and rides the next departure. A missed train never blocks other teams: the release leaves on schedule with whatever is ready and passing, and the late change simply gets the next slot.
How long should the cadence be?
Match it to your risk appetite and testing cost. Weekly is common for web apps with strong automated tests; two-week or monthly trains fit mobile, firmware or heavily regulated systems where every release carries more compliance and QA overhead.
Do release trains work with feature flags?
Yes, and they pair well. The train gives predictable release timing while flags keep code hidden until the business is ready to switch it on, so shipping and launching are decoupled.
Suggest a new word or an edit to an existing one. Every submission is reviewed before it goes live.