Solo Dev Release Discipline in 2026: Feature Flags, Fast Rollback, and Post-Release Calm

June 01, 2026

The scariest moment in solo development isn’t writing the code. It’s the deploy. You hit a button, and suddenly the thing an AI assistant and you wrote together is live in front of real people, with no teammate to catch what you missed.

For a long time my release process was “merge, deploy, and hope.” It worked until it didn’t — and when it didn’t, I’d lose an evening firefighting a production issue I could have prevented in five minutes. The fix wasn’t more testing or a heavier process. It was discipline: a small, repeatable system that makes shipping boring on purpose.

Boring is the goal. This is the system I use now, the one that lets me deploy and then actually go make a coffee instead of refreshing my error dashboard.

1. Control the scope before you control anything else

Most painful releases are painful because they were too big. The single highest-leverage thing I do happens before any code exists.

Ship one thing. I write down, in one sentence, exactly what this release does. If the sentence needs an “and,” it’s two releases. This is even more important when I’m working with AI — an assistant will happily generate a 600-line diff that touches eight files, and a 600-line diff is something you read, not something you verify.

Write the non-goals. Right under the one-sentence scope, I list what this release explicitly does not do. “Does not change the billing logic.” “Does not touch the auth middleware.” Non-goals are how I catch an AI quietly refactoring something I never asked it to.

Note the risk. One line: what’s the worst thing that breaks if this goes wrong? “Worst case: new users can’t complete signup.” That sentence tells me how careful to be — a copy change and a payment-path change deserve very different levels of paranoia.

Small batches aren’t just safer; they’re faster to debug. When something breaks after a 40-line release, you already know where to look.

2. Progressive delivery, solo-dev edition

Big companies have entire platform teams for progressive delivery. You don’t need that. You need two ideas: deploy is not the same as release, and everything risky has an off switch.

Put new features behind a flag. A feature flag is just a boolean you can change without deploying. The code ships to production in the “off” state, you turn it on for yourself, then for a slice of users, then for everyone. Martin Fowler’s Feature Toggles article is the canonical write-up, but the solo version is humble: an environment variable, a row in a config table, or a hosted flag service if you want targeting. The point is that turning a feature on is a config change, not a deploy.

Build the kill switch first. Before I write the feature, I write the flag that disables it. That ordering matters. If the off switch is an afterthought, it won’t exist when you’re panicking at 11pm. With it in place, “rollback” can be a single toggle instead of a frantic redeploy.

Shrink the blast radius. Staged rollout for a solo dev doesn’t need fancy infrastructure:

  • Turn it on for your own account first. Use the feature like a real user.
  • Expand to a small, tolerant cohort — internal users, beta testers, or a percentage slice.
  • Watch your dashboards for a bit (see section 4).
  • Only then flip it on for everyone.

Every stage is a chance to catch a problem while it affects ten people instead of ten thousand.

3. Rollback readiness: the checklist before you deploy

Here’s the rule that changed everything for me: I don’t deploy anything I can’t undo in under a minute. If I can’t answer “how do I reverse this?” before shipping, I’m not ready to ship.

Run this before every deploy:

  • Is the change reversible? Code rolls back by redeploying the previous build or flipping a flag. Make sure one of those is genuinely available — not “in theory.”
  • Is the database backward-compatible? This is the one that bites solo devs hardest. A migration that drops or renames a column means the old code can’t run anymore, so you can’t roll back. Use the expand/contract pattern (Martin Fowler calls it Parallel Change): first expand — add the new column/table alongside the old, deploy code that writes to both; then migrate the data and switch reads; only later, in a separate release, contract by removing the old thing. At every step, the previous version of your app still works. That’s what makes rollback safe.
  • Are the steps ordered and reversible? If a deploy is “run migration, then deploy code, then flip flag,” I know the reverse order too. Destructive steps go last and get their own release.
  • Is there a one-line runbook? Not a document — three lines in the PR description: how to roll back, what the kill switch is, and what to watch. Future-me, at 11pm, will thank present-me.

If a release can’t pass this, the answer usually isn’t “be more careful.” It’s “split the release so it can.”

4. Observability minimums

You can’t stay calm after a release if you’re blind. But you also don’t need an enterprise observability stack. You need four signals you can check in 30 seconds.

  • Error rate. Is it spiking compared to before the deploy? A baseline you know by heart is worth more than a fancy dashboard you never look at.
  • Latency. Did your key endpoints get slower? AI-generated code loves to add an N+1 query you didn’t notice in review.
  • Conversion / critical funnel. Did the number that pays your bills drop? Signups, checkouts, whatever “success” means for your app. A silent conversion drop is the bug that doesn’t throw an error.
  • One critical user path. Pick the single flow that must work — signup, login, checkout — and actually click through it in production after deploy. Thirty seconds of being a user catches things no metric will.

If you set up nothing else, set up an alert on error rate and bookmark the one funnel number. That’s the difference between finding out from your dashboard and finding out from an angry email.

5. The 30-minute, 2-hour, 24-hour routine

Calm after release isn’t a feeling, it’s a schedule. Instead of refreshing dashboards anxiously for an hour, I do three quick check-ins and otherwise leave it alone.

At 30 minutes. The “did I break it immediately” check. Glance at the error rate, run the one critical user path myself, confirm the feature flag is in the state I think it’s in. Most regressions show up fast — this catches them while the deploy is still fresh in my head.

At 2 hours. The “slow burn” check. Some problems only appear under real traffic — a cache that fills up, a rate limit you hit, a memory leak. I look at latency trends and the conversion number now that enough users have come through. If the staged rollout is partial, this is usually when I decide whether to widen it.

At 24 hours. The “is this actually fine” check, and the cleanup. Did the metrics hold overnight across a full traffic cycle? If yes, I widen the flag to 100% if I haven’t already, and I note any flags or old code paths that are now safe to remove. Closing the loop here is what keeps your codebase from filling up with stale toggles.

Three small check-ins beat one long anxious vigil — and they give you permission to stop watching in between.

6. Common solo-dev mistakes in AI-assisted shipping

The failure modes I see most (and have lived through):

  • Oversized diffs. The AI generates a lot of code fast, and it all looks plausible, so it ships in one giant release nobody fully read. Plausible is not the same as correct. Cap your diff size and split aggressively.
  • No verification gate. “Tests pass” and “the AI says it’s done” are not the same as “I confirmed it works.” Always run the real user path yourself before trusting it.
  • Trusting confidence over behavior. AI-written code is fluent and self-assured even when it’s wrong. Verify behavior, not tone.
  • Irreversible migrations. Shipping a destructive schema change in the same release as the feature, so rollback is impossible. Expand/contract, always.
  • Panic hotfixes. Something breaks, and you push a fast, unreviewed, unflagged fix straight to prod — which breaks something else. A panic hotfix is just another untested release. Flip the kill switch first to stop the bleeding, then fix calmly.

Almost every one of these is solved by the earlier sections. That’s not an accident — discipline is mostly a set of pre-commitments that stop you from making the obvious mistake while stressed.

7. Copy-paste release checklist

Here’s the block I keep in a snippet and paste into every release’s notes:

RELEASE: <one sentence — what ships>
NON-GOALS: <what this release does NOT touch>
WORST CASE: <what breaks if this goes wrong>

PRE-DEPLOY
[ ] Diff is small enough that I read every line
[ ] Risky behavior is behind a feature flag (default OFF)
[ ] Kill switch exists and I've tested turning it off
[ ] DB change is backward-compatible (expand/contract, no drops/renames yet)
[ ] Rollback path confirmed: redeploy previous build OR flip flag
[ ] Runbook (3 lines): how to roll back / kill switch / what to watch

ROLLOUT
[ ] Deploy with feature OFF
[ ] Enable for my own account, use the real flow
[ ] Expand to small cohort / % slice
[ ] Dashboards look clean → widen

OBSERVE
[ ] Error rate normal vs. baseline
[ ] Latency on key endpoints normal
[ ] Conversion / critical funnel number holding
[ ] Walked the one critical user path in production

POST-RELEASE
[ ] +30 min: error rate + critical path + flag state
[ ] +2 hr: latency trend + conversion under real traffic
[ ] +24 hr: metrics held → widen to 100%, remove stale flags/old paths

None of this is heavy. The whole point of release discipline is that it’s light enough to actually do every time — a few sentences, a flag, a rollback plan, three check-ins. Do it consistently and shipping stops being the scary part of your day. You deploy, you do your three checks, and you get the thing I value most as a solo dev: a quiet afternoon.


References: Martin Fowler, Feature Toggles and Parallel Change (the expand/contract pattern for safe, reversible schema changes).


Published by NinaCoder who lives and works in Mexico DF building useful things.