← Delivery Operating Model

Release Management

How you get working software from your engineers to your users - reliably, safely, and often.

Release management is not about big-bang deployments and release trains. It is about building the capability to release frequently, safely, and without drama. This covers the practices, tooling decisions, and team behaviours that make releases boring.

The Goal: Boring Releases

The mark of a mature release management practice is that nobody notices when a release happens. Not because nobody cares about the software, but because the release is so routine, so reliable, and so low-risk that it does not warrant attention.

In most engineering organisations, releases are the opposite of boring. They are scheduled events. They require coordination across multiple teams. They involve manual steps that must be performed in sequence. They happen infrequently because each release is expensive and risky. And they frequently go wrong.

The path from dramatic releases to boring releases is not primarily a tooling problem. It is a practice and culture problem. The tooling is the easy part.

The Spectrum: Manual to Continuous

Release management exists on a spectrum. Understanding where your organisation sits on that spectrum - and what moving along it requires - is the starting point for improvement.

Manual Releases

At one end, releases are fully manual. An engineer SSHes into a server, pulls code, restarts services. There is no automation. Every release is a unique operation performed by a person who knows the specific steps.

Manual releases are slow, error-prone, and knowledge-concentrated. When the person who knows the release process leaves, the process goes with them. They represent the highest possible risk and the lowest possible frequency.

Scripted and Tooled Releases

The first step toward automation is scripting the manual steps. A deployment script codifies what was previously done by hand. CI/CD tooling - Jenkins, GitHub Actions, GitLab CI, CircleCI - runs that script on a trigger, typically a code merge.

This eliminates human error in the execution of known steps and makes releases reproducible. It does not eliminate the risk that the release itself introduces problems.

Continuous Delivery

In a continuous delivery practice, every code change that passes automated testing is in a releasable state. The decision to deploy to production is still made by a human, but the preparation is automated. Release is a button press rather than a project.

Continuous delivery requires strong automated test coverage, reliable build pipelines, and clear environments. It removes most of the mechanical effort from releases and allows teams to release frequently - daily or more - without significant overhead.

Continuous Deployment

Continuous deployment removes the human approval step entirely. Every code change that passes the pipeline is automatically deployed to production. This is the end state of high-maturity release management.

Continuous deployment requires very high confidence in automated testing, excellent monitoring, and the capability to roll back rapidly. It also requires a culture comfortable with the idea that production changes continuously rather than in discrete batches.

Not every organisation or product is appropriate for continuous deployment. Regulated industries, hardware-adjacent software, and consumer products with strict quality expectations often require human checkpoints that preclude full automation.

Deployment Frequency as a Health Signal

DORA research - the most substantial longitudinal study of software delivery performance - identifies deployment frequency as one of four key metrics that distinguish high-performing engineering organisations from low-performing ones.

High-performing organisations deploy multiple times per day. Low-performing organisations deploy monthly or less frequently. The correlation with overall engineering effectiveness is strong.

Why does deployment frequency matter? Because it is a proxy for a set of underlying capabilities. Teams that deploy frequently have:

  • Strong automated test coverage that gives them confidence in each change
  • Clean, modular code that can be changed in small increments
  • Good monitoring and alerting that lets them detect problems quickly
  • Psychological safety to push changes without drama
  • Tight feedback loops that let them learn from production quickly

Infrequent deployment is usually a symptom of deficiencies in these underlying capabilities, not a cause of poor performance. But increasing deployment frequency forces these capabilities to develop. The constraint creates the pressure for improvement.

Feature Flags and Decoupling Deploy from Release

One of the most powerful techniques in modern release management is separating deployment - putting code into production - from release - making a feature available to users.

Feature flags are conditional checks in code that control whether a feature is active. A feature can be deployed to production but hidden behind a flag. It becomes visible to users only when the flag is enabled, which can be done at any time, for any subset of users, without a deployment.

This decoupling has significant benefits:

Gradual rollout. Enable a feature for 1% of users, observe the impact, then increase incrementally. If something is wrong, you see it at 1% scale rather than 100%.

Instant rollback. If a released feature causes problems, disable the flag. No deployment required. Problem resolution in seconds rather than minutes.

Separation of concerns. Product decisions about when to release a feature are separated from engineering decisions about when code is ready for production. Engineers can merge and deploy without waiting for marketing alignment.

Trunk-based development. Feature flags allow long-running feature work to be merged to the main branch continuously, avoiding the integration nightmare of long-lived feature branches.

Feature flags introduce complexity - a flag that is never cleaned up becomes technical debt. Establish a practice of retiring flags as features are fully rolled out. A flag that has been live and at 100% for a month should be removed from the codebase.

Rollback Strategies

Every release should have a defined rollback plan before it is executed. This forces thinking about what could go wrong and what the recovery path is.

Code Rollback

The simplest rollback strategy: redeploy the previous version. This works for most situations but assumes the previous version and the current database schema are compatible. Migrations that are not backward-compatible make code rollback impossible or dangerous.

Database migration strategy: Write migrations to be backward-compatible with the previous code version. This means expanding schema before deploying new code, and contracting schema only after the new code is confirmed stable. This pattern - expand, migrate, contract - allows safe rollback at any point.

Feature Flag Rollback

When features are behind flags, rollback is disabling the flag rather than redeploying code. This is faster and lower risk than code rollback and should be the default strategy for feature-level problems.

Blue-Green Deployment

Maintain two identical production environments - blue and green. Deploy new code to the inactive environment, validate it, then switch traffic over. If problems emerge, switch back. This makes rollback a configuration change rather than a deployment, and eliminates deployment downtime.

Blue-green requires maintaining two environments, which has infrastructure cost. For teams where release risk is high and downtime is expensive, that cost is usually justified.

Release Governance and Approvals

Many engineering organisations have formal approval gates before production releases - change advisory boards (CABs), manual sign-offs, mandatory review periods. These exist for legitimate reasons: regulatory compliance, risk management, auditability.

The problem is that approval gates that are not tightly designed often become bottlenecks that slow releases without providing meaningful risk reduction. A weekly CAB that reviews changes in aggregate adds a week of delay to every release and provides review at a level of abstraction that makes genuine risk assessment difficult.

The question for each approval gate is: what risk is this gate designed to mitigate, and is the gate as currently designed effectively mitigating that risk?

When approval processes are automated - when the evidence for a release (test results, security scans, performance baselines) is generated automatically and the approval is checking that evidence rather than the change itself - they can be fast and low-friction while still providing genuine governance.

Work with your governance and compliance stakeholders to understand what the approval process actually needs to verify. In most cases, automated evidence satisfies the underlying requirement more reliably than manual review.

Transitioning to Higher Frequency Releases

Moving from infrequent to frequent releases is a journey, not a switch. The key constraint at each stage is different.

From monthly to weekly: The primary constraint is usually manual release process. Automate the deployment steps. Establish automated smoke tests that confirm a deployment is healthy. Reduce the duration and ceremony of the release event.

From weekly to daily: The primary constraint is usually automated test coverage and confidence. Invest in test automation. Establish monitoring that detects problems within minutes of deployment. Build the team's comfort with frequent change.

From daily to on-demand: The primary constraint is usually culture and code architecture. Teams need to be comfortable working in small, releasable increments. Code needs to be modular enough that individual changes are genuinely independent. Feature flags become essential.

Each step requires investment. Not all organisations need to reach continuous deployment. But every organisation benefits from moving faster than they currently do. The discipline required to release frequently is the discipline required to deliver reliably - they are the same capability, expressed differently.