The branch nobody wants to touch

Somebody started the upgrade. It might have been Rails 6 to 7, or 7 to 8, or a Ruby version that’s about to lose security support. They got partway: a few gems bumped, a pile of deprecation warnings fixed. Then a customer needed something, and the upgrade branch sat.

Now it’s months behind the main branch. Merging it is its own project. A key gem hasn’t been updated for the new version. Every week the gap grows, and every week someone says “we should really finish that.”

Your team made the right call. Customer work pays the bills. But an outdated framework has a real cost: security patches stop, new gems won’t install, hiring gets harder, and the eventual jump gets bigger. Your developers know the app well. What they haven’t had is uninterrupted time and a method that doesn’t need one big risky weekend.

What I do: small steps, always shippable

I don’t do big-bang upgrades. The app stays deployable at every step, and each step goes to production on its own.

Current versionin productionTests aroundcritical flowsDual-bootboth versions, one branchSmall mergesgems, deprecationsNext versionin productionUpgrade logrepeatable process next version
Figure 1. One version at a time. The app runs on both versions while the work lands in small merges, and every step ships.

A process you can repeat

The upgrade shouldn’t be a once-a-decade event. Rails ships a new version roughly every year, and staying close to current is much cheaper than catching up. So the written output matters as much as the upgrade itself:

You own all of it. The next upgrade can be done by your own team, a freelancer, or me, from the same log.

Why me

For seven years I was a senior engineer on a multi-tenant B2B SaaS that grew from about $4M to $13M in annual revenue, which meant keeping a large, long-lived Rails app current without stopping the business. I also built and run a live product on Rails 8 on my own, and I have a merged contribution to faraday, one of the Ruby HTTP libraries many apps depend on. I’ve written about zero-downtime migrations at scale and related work on my writing page.

Take a business like this one

The business in this section is a composite of the kind of company I talk to, not a named client. The numbers are the shape of the problem, not a case study.

Picture a B2B scheduling platform on Rails 6.1 and an older Ruby, with around four hundred models and a test suite that covers about half the app. An upgrade branch to Rails 7 was started fourteen months ago and is now hundreds of commits behind. Two gems the app depends on have no release for newer Rails, and one of them handles the calendar sync that customers rely on most.

What I’d do for a business shaped like this:

  1. Week one: assess. List every blocking gem, read the changelogs for each Rails step, and estimate the work per step. Decide whether to salvage anything from the stale branch.
  2. Tests around calendar sync, billing and login, the flows where a quiet failure hurts customers.
  3. Set up dual-booting on main, so both versions run in CI.
  4. Replace or patch the two stuck gems. For the calendar gem, either a maintained fork or a small in-house replacement covered by tests.
  5. Step through 7.0, 7.1, 7.2 and 8.0, each deployed to production on its own, with Ruby upgraded alongside.
  6. Hand over the upgrade log and the process, so the team runs the next upgrade themselves.

The team keeps shipping features the whole time, because the upgrade happens on main in small pieces instead of on a branch that blocks everyone.

What it costs

It starts with a small fixed-price assessment: a written upgrade plan with every blocker, every step and an honest estimate for each. Some teams take the plan and do the work themselves. Otherwise the upgrade is scoped and quoted step by step from the plan, so you can stop after any version. No retainer, and no lock-in.

What I need from you

Access to the code, CI and a staging environment. A developer on your side to review merges and learn the dual-boot setup. Your release schedule, so upgrade steps land at quiet times. And a list of the flows customers notice first when something breaks.