Case study

From Weekly Releases to Several a Day: SLOs and Trunk-Based Development

A team of five was releasing a payments frontend weekly off long-lived branches, with no SLOs to say whether a release had actually regressed anything. Moving to trunk-based development with feature flags and Sentry-backed SLOs turned that into several releases a day.

Naseebullah Ahmadi  Senior Software Engineer, London
5 mos
3 min read
Release frequency
Weekly → several/day
Mean time to resolution
−70%
Engineers on trunk
5

I led this as one of five engineers on the frontend team for ibanq, IFX Payments' banking, FX and cash-management platform. We were releasing weekly, each release built off branches that had been alive for days, sometimes weeks.

There was no formal service-level objective for the frontend: "is this release healthy" was answered by watching for support tickets after the fact, not by a dashboard before the fact.

The constraint

Long-lived branches and weekly releases weren't a preference, they were a symptom: nobody trusted a same-day release because nobody had a fast, reliable signal that a change hadn't regressed something. Without that signal, the team's real risk-management tool was time, batching changes into a big weekly release and hoping code review caught what testing didn't.

That made every release riskier, not safer, since a bigger diff is harder to review carefully and harder to roll back cleanly if something in it is wrong. The fix wasn't "release more often", that's the outcome, not the mechanism: the actual work was building a signal the team could trust enough to release on.

What I did

  1. Long-lived branches, weekly release, big diffs to Trunk-based, SLO-gated, several releases a day: Feature flags + SLO release gate
Long-lived branches gave way to trunk-based releases gated on SLOs
  1. 1

    Define SLOs before changing the process

    Set concrete SLOs against Sentry's LCP and INP data first, so the team had an objective answer to "did this regress anything" that didn't depend on someone noticing a support ticket.

  2. 2

    Move to trunk-based development with feature flags

    Incomplete work could merge to main continuously without shipping half-built features to users, and a release became "what's flagged on" rather than "what's on this branch".

  3. 3

    Gate releases on the SLOs automatically

    Turned "is this safe to release" from a judgment call into a pass/fail check the deploy had to clear.

  4. 4

    Considered just shrinking the branches

    Rejected: the actual bottleneck was the lack of a trustworthy regression signal, not branch lifetime, so shrinking branches without that signal would only have made small releases feel as risky as big ones.

The release gate turned "is this safe" into a checkpoint every merge passed through automatically, rather than a question someone had to remember to ask:

  1. Dev to CI: merge to trunk (flagged off)
  2. CI to SLO gate: run release checks
  3. SLO gate to CI: within budget
  4. CI to Prod: deploy
  5. Prod to Dev: flag on for cohort
A release moving through the SLO-gated pipeline

Outcome

Release frequency went from weekly to several a day, and mean time to resolution fell by around 70%, because a smaller diff behind a feature flag is both easier to diagnose and easier to roll back than a week's worth of changes bundled together.

The change also removed the merge-conflict overhead of long-lived branches for all five engineers. That's not in the headline numbers, but it was a big part of why the new process stuck rather than sliding back to old habits after a few months.

Solving something similar?

I take on select engineering work like this.

Work with me

What I'd do differently

I'd introduce the feature-flag tooling and the SLO dashboards in the opposite order. We shipped the flags first and the SLOs a few weeks later. That left a stretch where the team was already releasing more often but without the dashboard that would have told us confidently whether that was safe.