Lesson 28 of 30
Ship on a fixed schedule and batch the risk, or ship every merge and spread it thin. Neither is the 'grown-up' choice — they trade cadence for safety differently, and the right one depends on your team.
14 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
There are two common answers to "when does a merged change reach production," and they sit at opposite ends of a trade-off between predictability and speed:
main, automatically, with no schedule at all. There's no "next train" — a change either passes the pipeline or it doesn't, and if it does, it's live in minutes.Neither is more mature than the other. A release train buys predictability and a stable review window at the cost of speed and batching risk. Continuous deployment buys speed and small, easy-to-isolate changes at the cost of needing serious automated test coverage and fast rollback machinery to be safe at all.
A release train, cut on a cron schedule instead of a push:
name: Cut release train
on:
schedule:
- cron: "0 10 * * 2" # every Tuesday, 10:00 UTC
jobs:
cut-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: git checkout -b release/$(date +%Y-%m-%d) main
- run: git push origin release/$(date +%Y-%m-%d)
# Everything merged to main before 10am Tuesday is on this train.
# Everything merged after waits for next week's.
Continuous deployment, triggered by the merge itself:
name: Deploy on merge
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm build
- run: vercel deploy --prod --token=$VERCEL_TOKEN
# Merged at 2:14pm, live at 2:17pm. No calendar involved.
Same underlying pipeline machinery — checkout, build, ship — pointed at two completely different triggers.
The mental-model lesson drew the line between Continuous Delivery — always release-ready, a human decides when — and Continuous Deployment — every passing change ships automatically. A release train is what Continuous Delivery looks like in practice once you add a calendar to the human's decision. This lesson is that same fork in the road, just with a concrete choice attached to it.