Senior Engineering Interview Handbook / Chapter 100
The Software Delivery Lifecycle
A production-engineering foundation chapter that follows one consequential change through requirements, design, implementation, review, testing, release, observation, and production learning.
Page tools
When every stage succeeds and the change still fails
A team replaces the shipping estimator in checkout. The ticket says the new model will produce more accurate delivery windows. The design is approved, the pull request is reviewed, the tests pass, and the deployment completes without errors. Two days later, support finds that customers in one region were promised dates the carrier could not meet.
Every named stage of delivery happened. The stages did not exchange the right evidence. “More accurate” was never tied to a region, a carrier, or a measure of promise misses. The design review studied the estimator but not the fallback when carrier data became stale. The tests used representative orders in aggregate and hid a thin regional slice. The release dashboard watched latency and server errors, both of which looked healthy. Support discovered the product failure because production observation had been defined as service health rather than fulfillment of the customer promise.
The software delivery lifecycle is the work of keeping that promise visible as a change moves from intent to production learning. Requirements, design, implementation, review, testing, release, and observation are not independent ceremonies. Each should reduce a particular uncertainty and leave evidence that the next decision can use.
This loop is compatible with rapid delivery. A copy correction may complete it through an ordinary review, existing checks, a routine deployment, and a glance at the usual dashboard. The shipping estimator deserves more weight because it changes a customer promise at broad scale and its accuracy cannot be established from unit tests alone. Process should grow with consequence, not with the team’s appetite for paperwork.
Begin with a promise that can survive contact with production
Before discussing architecture, restate the request so that success and harm are visible. For the estimator, a useful delivery brief might begin:
Outcome
Domestic customers receive delivery windows that are more accurate by region
and carrier without exceeding the checkout latency budget.
Not in this release
International estimates and the customer-facing presentation remain unchanged.
The legacy estimator remains available through launch verification.
Evidence needed
Historical replay, live shadow comparison, carrier-contract checks, latency
under realistic load, and promise-miss results segmented by region and carrier.
Exposure and ownership
Shadow first, then a regional canary, then gradual expansion. A named engineer
owns launch decisions, support review, cleanup, and the proposal to retire the
legacy path.
This is short because its job is to invite disagreement while disagreement is cheap. Product can challenge what “accurate” means. Support can ask whether a window can be explained after an order ships late. The carrier-integration owner can expose freshness and quota limits. The team can decide whether the latency budget is a hard bound or a trade worth making. A ticket title cannot carry those conversations.
Risk classification follows from the promise. Ask how widely an error can spread, how serious the consequence is, whether the system introduces an unfamiliar dependency or operating burden, and how much must be learned from real traffic. Above all, ask what reversibility actually means. A server-side flag can send new requests back to the legacy estimator, but it cannot retract a delivery date already shown to a customer. Disablement limits future harm; it does not erase an external effect.
Those facts establish the first gate: before building, the team should agree on the risk it is accepting and the decisions that will become expensive once code exists.
Carry the risk into design and implementation
The design now has a sharper question than “Where should the estimator run?” It must preserve the evidence the launch will need.
The new path runs behind a server-side flag. It records a version of the model and its important inputs and outputs so that a disputed estimate can be replayed. Calls to carrier data have explicit freshness rules, timeouts, and a fallback to cached or legacy estimates. Shadow mode computes a result without showing it to the customer, allowing the team to compare the new and old paths on live request shapes. The rollout can be scoped by region and carrier rather than by a random global percentage, because those are the dimensions along which the model may fail differently.
These are not release decorations added after the estimator works. They are part of the design because explainability, comparison, containment, and repair are part of operating the change.
Implementation should make those decisions inspectable. The pull request ought to show both flag states, the behavior for missing or stale carrier data, the version recorded with a result, and the metrics that distinguish a fallback from an ordinary estimate. A reviewer can then ask operational questions against code: Can a timeout multiply checkout latency through retries? Can shadow evaluation produce a side effect? Will support have enough context to investigate a bad promise without exposing sensitive customer data? Who removes the old branch, and under what condition?
Code review is too late to invent the delivery strategy, but it is the right place to verify that the implementation preserves it. Review loses much of its value when the design says “gradual rollout” and the code offers only a global Boolean flag.
Test claims, not stages
“Add unit, integration, and load tests” describes activity. A useful validation plan names the claim each test can support and admits what remains unknown.
For the estimator, unit tests can establish boundary behavior in the model and fallback rules. Contract tests can catch a changed carrier payload. Historical replay can compare predictions with known delivery outcomes, provided the sample is segmented rather than reduced to one flattering average. Load tests can show whether the checkout path holds its latency budget at p95 and p99 and how it behaves when the carrier dependency slows down. Negative and fault tests can exercise missing inventory regions, stale cache entries, timeouts, and malformed data.
None of these proves how the model will behave on tomorrow’s traffic. Shadow comparison supplies a further kind of evidence: disagreements between the old and new estimator under live inputs. It still cannot prove customer impact, because customers have not acted on the new result. The plan is stronger when it says where confidence ends.
The test suite therefore hands the release decision more than a green status. It supplies expected ranges, known blind spots, and the segments most likely to deserve a narrow canary.
Decide how to learn without learning at everyone’s expense
Before exposure, the team needs a second gate. It should name who sees the change first, what signals permit expansion, what signals pause it, and what happens after a pause.
For this change, the team first observes shadow disagreements by carrier and region. It then enables one region whose carrier mix is understood and whose support team knows the launch window. The dashboard combines technical health with the promise the feature exists to keep:
- estimator latency, timeouts, errors, and fallback rate;
- difference between legacy and new windows, segmented by carrier and region;
- delivery-promise misses when fulfillment results arrive;
- checkout completion and support contacts that may reveal customer harm;
- traffic and sample size, so an apparently quiet canary is not mistaken for evidence.
Pause criteria belong in the plan before the graph becomes ambiguous. A sharp rise in timeouts may justify immediate disablement. A cluster of overly optimistic windows for one carrier may justify freezing that segment while others continue. A bad model version may be rolled back; promises already shown may require support guidance or customer communication. “Rollback” is only one member of a larger family that includes disable, roll forward, drain, repair, and mitigate.
Suppose the canary reveals the original regional problem: the carrier feed is fresh during business hours but lags overnight, so the model makes optimistic morning promises. The lifecycle has worked even though the first release did not ramp. Observation found a false assumption while exposure was bounded. The team can disable that carrier, change the freshness policy, replay the affected windows, and add the discovered condition to its fixtures. The production result has become design and test evidence for the next turn of the loop.
Close the loop while the evidence is still legible
A successful ramp does not finish the work. Temporary machinery has a way of becoming permanent architecture: shadow jobs continue spending capacity, flags accumulate untested combinations, dual paths drift, launch dashboards lose owners, and the legacy estimator remains available long after anyone can operate it safely.
The post-launch decision should compare the promised outcome with production evidence and choose what changes because of it. For the estimator, that means reviewing accuracy and promise misses across normal and peak traffic, recording the carrier-freshness lesson, deciding whether the old path can be removed, and assigning cleanup. If the launch exposed a class of risk that other teams share, the learning belongs in common fixtures, review guidance, or platform controls rather than in one engineer’s memory.
Ownership is at the center of the loop because handoffs otherwise create gaps. The requirement author may not operate the code, the implementer may not own the carrier, and support may see customer harm first. Senior delivery judgment is often the work of keeping those people and their evidence connected until the uncertainty has genuinely fallen.
Scale the loop to the danger
The same questions apply to other work, but different risks take the lead.
In a database migration, transformation moves the rollback boundary. Before a backfill, old code may be restored; after rows change, recovery may require verification and repair. An expand-contract sequence, batched progress, pause controls, and compatibility checks matter more than a feature flag alone.
In an authorization change, failure can look like success: a forbidden request returns 200. The evidence must include denied actors, revoked sessions, cross-tenant cases, stale policy caches, audit records, and the default when a dependency fails. Watching only error rates would miss the dangerous result.
In a performance change, an improved average can conceal worse tail latency, cost, saturation, or correctness. Workload shape and invariants decide what to measure. A fast cache that serves stale authorization decisions is not a successful optimization.
For a small, reversible change with familiar operating behavior, existing review, tests, deployment controls, and dashboards may be sufficient. The lifecycle has not disappeared; the evidence needed for the next decision is simply cheaper to obtain.
Use the lifecycle in an interview without reciting it
An answer does not become senior by naming every stage. It becomes credible when one risk changes the design, validation, release, and ownership plan. For the shipping prompt, a compact answer could be:
Wrong estimates break a customer promise, so I would define accuracy by region
and carrier rather than as one aggregate. I would keep the legacy path, record
versioned inputs and outputs, replay historical orders, and shadow the new
model on live traffic. I would canary by region and carrier, then gate expansion
on latency, fallback rate, and delivery-promise misses. The launch owner would
also own support review and removal of the old path after peak-traffic evidence.
The same reasoning strengthens a system design when you explain how a new index will be built, compared, canaried, and rebuilt before the old read path is removed. It strengthens a project deep dive when you can say which evidence changed the rollout or acceptance criteria. It strengthens a leadership story when the central decision was to split a data migration from a behavior change because their recovery paths were different.
To practice, choose one change you know well and write its customer or operational promise in one sentence. Then answer four questions:
- Which consequence makes this change deserve more than the routine path?
- Which assumption should be challenged before implementation becomes sunk cost?
- Which claim can tests establish, and what must still be learned from bounded production exposure?
- After exposure, what can be disabled or reverted, and what can only be repaired or mitigated?
Now change one condition: make the data transformation irreversible, the client slow to update, the authorization cache stale, or the first cohort unrepresentative. Revise the delivery path. If only the test list changes, the exercise has not yet reached design or ownership.
Delivery is the evidence chain that turns an intention into a controlled production change. The next chapter narrows in on the release machinery. Keep the wider loop in view: a trustworthy pipeline cannot rescue an outcome that was never defined, a risk that was never carried into design, or a launch that nobody stays to learn from.
Related links
Continue reading
Full table of contents