Feature flags are a tool which can be used by software developers to separate a feature from the rest of the code surrounding it. It's a very simple concept with some very powerful consequences.
First let's look at what a feature flag is:
I don't understand what is going on.
Assume you're building a website and you create a new section of your site. It's a new feature so you section off the link from the rest of your site using a feature flag:
<nav> <a href="/home">Home</a> <a href="/profile">Profile</a> <% if Feature.active? :dashboard %> <a href="/dashboard">Dashboard</a> <% end %> <a href="/logout">Logout</a> </nav>
That's it! You simply create a conditional which will activate that new link or not.
There are a variety of reasons why you might want to use this technique for your code.
- It makes deploying immature features a no-risk proposition.
- It makes working with other developers easier.
- It makes rolling out features to users gradually an actual possibility.
Deploying immature features
With a feature flag you can deploy a feature which might not be quite ready for prime-time yet. Deploying early, and often is a good way to keep your team's progress moving forward. There's nothing that kills productivity faster than working on the same feature for a really long time without deploying it.
Now, some people might argue that deploying a feature before it's ready is an anti-pattern. I'm not saying that we should deploy things which don't work, I'm saying that we should deploy features as soon as they address a user need, and are an improvement over whatever tools the user currently has.
For example: If your users want a metrics dashboard in your application your first version might not be perfect but if it allows users to gain some insights then it's probably worthwhile showing them so they are able to give you feedback.
With a feature flag you can enable and disable your immature features without deploying, this means that it's easier to disable an immature feature if there are problems. Effectively by using a feature flag you're able to reverse/rollback a change readily:
Feature flags make reversing changes easy.
Working with other developers
One of the best reasons for using a feature flag is that it makes working with other developers significantly easier.
At reinteractive we mostly follow the standard git branching practice of:
- master is deployed to production
- develop is deployed to staging
- feature branches are merged into develop
Consider the scenario where I'm working on the metrics dashboard feature we talked about above. I submit my pull request and it's considered ready for review by the client in our staging environment.
Meanwhile, Geoff is working on a bunch of smaller fixes which need review but are directly affecting users in production. Because I've already merged my feature branch which requires a significant amount of time for review in staging Geoff's fixes will get held up behind my feature.
This means that we have the following changes waiting:
* 3aa36c7 - (HEAD) Fix semi-critical user login issue (19 hours ago) * 73d9ab4 - Change color on user profile page (21 hours ago) * a258c75 - Add large metrics dashboard feature (23 hours ago) * 640b7b1 - (origin/master, master) Add previous feature
640b7b1 is already deployed to production. But you can see that the commit
a258c75 is blocking the two other commits from being merged into master and deployed to production. We could
cherry-pick these changes across, but this can be tiresome to manage and could cause unexpected issues if there's an unknown dependency between those picked commits and ones that haven't been merged into master.
However, if the metrics dashboard feature is protected by a feature flag we can safely merge
a258c75 to master without worrying that users will see the potentially half-finished work.
By using a feature flag we can more easily work in larger teams on larger applications without slowing down the deployment of our team-mates features. This makes for a happier team and a happier client.
Gradual feature rollout
One exciting consequence of feature flags is that it's possible to enable the feature for a subset of users. When you're activating the feature it's possible to activate it for a single user, a group of users or even more complex systems like 50% of the users who encounter the feature.
This means we can gradually rollout a new feature and monitor any impacts it has on the rest of the system. If issues are detected we can quickly disable the feature while we find a fix.
This is also an effective way of creating a feature for a specific client. If you have a multi-tenanted application you might want to enable a specific feature for only one of your users. A feature flag might be a good choice in this circumstance too.
Feature flags are great! You should use them.
How to implement Feature flags
In the next post I'll go over how to implement feature flags in Rails.