Code releases stressing you out? Here’s a clever technique I use to take the edge off of releases

Tom Maslen
5 min readOct 13, 2021

Yes, this involves feature flags.

Making a change to your live environment is always risky. Not only is there a risk that you can introduce new bugs into existing features, but the new feature you’re trying to release will behave differently in an environment it’s not been in before.

Even if you have great test coverage, a different environment brings with it different use cases as data and usage will vary. And at almost every stage of the software development cycle if you find a problem you have to fix it by starting from scratch — making a change in your local dev environment — before continuing.

The closer to your live environment you get, the more riskier this change becomes, as you are not only potentially damaging your product but the fix takes longer to resolve at the stage where you found the problem.

In a typical release cycle, almost every stage potentially means implementing a fix from the beginning to resolve an issue.

After every deploy its typical for us to give the new feature a quick manual test. This is always the test that makes you feel better: seeing the new feature work in your live environment.

However I’ve often found errors in my code only when they’ve been deployed to the live environment. And the only way to resolve it was to either quickly deploy a fix (so more change into the live environment) or roll the code back to the previous version (more change).

What would be great would be a process where you could deploy the change to your live environment but have the new functionality disabled until you were able to verify that it worked, and then make the feature live for everyone. This is possible when you use feature flags.

Take the edge off releases

I’ve blogged in the past about how to use featureflag.tech. featureflag.tech is my own company but it’s not the only one and there are other great alternatives out there for you.

The key benefit of using feature flags is that it allows you to make changes to your codebase without releasing new features into your live environment. Changes go into production disabled, and only become available to your users when you are ready.

In a release cycle that includes feature flags, you separate the act of making a code change and releasing a feature.

Decoupling the deployment of code from the release of a new feature massively de-risks releases. When your new feature is live, a feature flag system means that if there is a problem you can quickly disable the new feature at a moments notice too.

You don’t have to make changes to your code base to undo the feature. There is no rollback involved. There is no need to start at the beginning of the development cycle and introduce more change.

However even with this release cycle model you still don’t really know if your change is good until you flick that switch and see the feature in action with your live environment.

Make your release feel less like a release

One of the features of the featureflag.tech SDK is that you can override flag values using an options object that is passed in when the class is instantiated.

new FeatureFlagTechClient( credentials, overrideValues );

This means regardless of what value is set from the featureflag.tech UI, you can force a feature to be enabled or disabled in that one specific instance. Your new feature could be disabled by default in your live environment, but you can enable it just for yourself when you visit the web application.

With this release cycle model in place, you can do all your QAing in your live environment to give yourself confidence that the change is correct.

Switching features on just for you means you can do all your QA work in your live environment, giving you massive confidence that the change you want to make meets its requirements.

An example

We use featureflag.tech to release new features for featureflag.tech, and we actually use this technique ourselves. As an example I’ve added a flag that you can use yourself right now to manually enable/disable a feature on the service.

One of the flags set in featureflag.tech is called showFoxy (Foxy is our mascot). Switching this flag via the UI makes Foxy show. He is disabled by default.

When instantiating the featureflag.tech client we pass in the override values from the query string:

const f2t = new FeatureFlagTechClient( {
apiKey: process.env[ "FEATURE_FLAG_API" ]
},
getOverrideValues( req.query )
);

This is how we parse the override values from the query string:

function getOverrideValues ( query ) {
let overrideValues = {};
for ( const [ key, value ] of Object.entries( query ) ) {
if (
key.startsWith( 'override-' ) &&
[ 'true', 'false' ].includes( value )
) {
overrideValues[ key.replace( 'override-', '' ) ] = ( value === 'true' );
}
}
return overrideValues;
}

In our code base we decide whether or not to add the reference to Foxy based on the flag value:

{ f2t.get( "Show Foxy" ) &&
<img src="{ links.staticHost }/img/foxy.webp" />
}

As the feature is disabled by default, when we log into featureflag.tech we don’t see Foxy…

https://admin.featureflag.tech/feature-flags

We can force Foxy to appear by adding Show%20Foxy=true onto the query string.

https://admin.featureflag.tech/feature-flags?override-Show%20Foxy=true

With this functionality in place we now have the following advantages over a more typical development life cycle:

  • I can test the new feature in my live environment, seeing how it behaves in this context and catching issues I would not have until the feature was released.
  • Testing will take less time as there are less steps — and less formality — when getting the change into the live environment.
  • There is less risk as we will have more confidence about the change.
  • Releasing the feature is simple and quick as it is done with a button press in the featureflag.tech UI.

--

--