Dynamic Feature Flags with ConfigCat

Stanislav Saprankov
11 min readOct 24, 2021

Hello and welcome everyone! In this article we will look at a tool called ConfigCat, which is used to control the configuration of your feature flags in a dynamic way.

We will use React and Next.js, but our attention will be less on the code and more on ConfigCat’s features. We will answer the following questions:

  • What is ConfigCat and why would you use it?
  • How to implement ConfigCat client-side?
  • Why doing the latter may not be what you want?
  • How to implement ConfigCat server-side?

Disclaimer: this article is not a tutorial on ConfigCat. For that its developers made very decent documentation with examples in particular SDKs, including both server- and client-side JavaScript. With that being said let’s dive into the topic of today.

So what is ConfigCat?

The direct answer is simple — it is software as a service, which allows you to dynamically configure feature flags for your applications. By ‘dynamically’ I mean that you can enable a certain feature for some target group of customers, then change the logic and enable it for a different target group — without having to redeploy the code of your application.

Long story short — the decision making logic gets outsourced from your application to ConfigCat.

Let’s stick to the following use case in this article in order to give some context to what we are going to do.

We’ve got a website for selling ferry tickets. The website is being accessed from all over Europe. At some point you get a feature request to implement a new opt-in checkbox. Passengers that check it will be charged an environmental fee so they can make their journey climate neutral.

Before you make this checkbox visible to everyone you want to make sure that it will not impact the number of successful bookings in a negative way. Or maybe checking this box triggers validation of the surrounding components and you want to ensure it doesn’t cause any unexpected errors.

At least for the above reasons you may want to first enable this feature for a limited amount of customers, say, 10% of your total traffic.

One way to implement this logic is to add conditional expressions to your code and change them every time you want to fine-tune your test. I believe the drawbacks of this decision to be obvious.

What if you could avoid this pain with a simple API call? Not bad, but it makes you call a 3rd party service with every customer request, which may come out expensive. Well, what if we could instead have the feature flag configuration in our own cache and only update it when needed? That is more or less where ConfigCat would come in handy.

1. Decision Making

Coming back to our example: a customer requests the page with the new opt-in. We need to decide whether or not we show the opt-in to this particular request, so we gather the necessary request data and send them to ConfigCat.

2. Caching

Our call first hits the local cache and only if the answer is not found there will it proceed to the ConfigCat itself.

3. Feature Flag Configuration

After some time we may want to update the setting. Let’s say the test was successful and we now want to show the opt-in to 50% of customers as opposed to just 10. This is where a feature called webhooks comes into play.

Here is how it goes: we change the feature flag setting in the web UI, ConfigCat calls our service to notify it about the change, finally our service brings the local cache up-to-date. That’s the whole magic.

All those details will become clear once we see the code.

Setting up your ConfigCat Account and Feature Flags

1. ConfigCat Components

Let’s take a moment to review the basic components of configcat.

setting — a particular decision maker. In this article we will use the terms

feature flag and setting interchangeably, but in reality a setting of boolean type is called feature flag.

config — a logical collection of settings

environment — a flavour of your flags. Usually it will correspond to your application’s environment like dev, staging or production. When you add a setting — you add it for all environments in a particular config. You will have same environments in all the configs of a certain product.

product — a wrapper over a set of configs and environments

2. Setting up the Account

We start with the setup of our feature flag in ConfigCat’s web UI. Let’s head to https://app.configcat.com/ and create a free account.

The free plan has some limitations but is more than enough for the purpose of this demo and even for a simple project with small number of flags.

After registration you should get a default product. If you haven’t — create one. Next, create a config. Just keep the default name which in my case is ‘Main Config’.

1. Creating first feature flag configuration

Next, in the top left corner of the page content select the option ‘+ Add Feature Flag’. As mentioned before, this is a setting that returns either true or false. It perfectly fits our use case since we only want to know if we should show a checkbox to a particular user. Name the flag ‘show_carbon_neutral_checkbox’ and leave everything else on default.

3. ConfigCat Dashboard

Now let’s observe the dashboard of our new config.

In the navigation on the top you will see the name of your environment as the last item. It will likely be either ‘Prod’ or ‘Dev’.

Config cat has prepared two environments for us by default. Let’s just leave them as is. In your own application you may want to rename them or add a couple more for your stagings. Keep in mind, however, that configcat’s free tier currently only allows two enviroments.

Below the top navigation bar you will see the option to add more flags and the section with our newly created one. If you left the default settings — it is currently disabled for all users.

Have a look at the button in the top right corner saying ‘View SDK Key’. An SDK Key is pretty much an API key to access ConfigCat. It is unique per combination of config and environment. Our application will use the SDK key to access a particular instance of ConfigCat configuration. Make sure not to mix up staging and production SDK keys when you’re working on a real feature.

2. ConfigCat top navigation bar and feaure flags section

4. ConfigCat Decision Making Logic

Let’s now enable the feature for half of our users. It corresponds to just flipping a coin whenever a new request comes to our website.

Notice that there is a special part of the setting for unidentified users. ConfigCat performs the decision making logic only if the user is identified.

What that means for us is that configcat expects a user object to be included in the request. ConfigCat proposes three fields for such an object— identifier, country and email — but they are all optional. You can also include a nested object called ‘custom’ and put any properties there that are relevant for decision making in your use case.

An identified user is any user that has some information in its user object submitted to configcat — whether identifier, country, email or some custom field provided by us.

3. Enabling the feature flag for 50% of identified users

Calling ConfigCat from the Front-End Code

Now let’s move to our project. It is a front-end React application created with create-react-app from which I removed everything that is not required for this demo.

We need to install ConfigCat as dependency with:

npm i configcat-js

We will keep things terribly simple. You won’t ship a web form like that to a client, but for our demo it will do the job. Here’s the code of the component:

1. Create the Client

We create a client that utilizes lazy load mode. In that mode a client will poll the server for config and store it in browser cache for a time specified in the settings. It will, of course, poll it automatically for every new user, since new users do not have that value in their cache. The other two modes are manual — when you are responsible for getting data from server — and automate — when the config is polled every certain amount of seconds.

Method that creates the client accepts the SDK key which we’ve seen earlier.

2. Call ConfigCat for decision Making

On each render of the component we make a call to ConfigCat. We include a user object in our request. This object only has an identifier that is bound to a certain browser tab. When you first load the page in a browser tab — the feature flag value (not config) is stored in local storage with TTL that equals 60 seconds. The checkbox is either there or not depending on how lucky we are to get into the 50% target group of our experiment. However often you refresh that single tab — at least during 60 seconds nothing changes. If you switch to another tab — you basically flip the coin again.

Goes without saying that your production identifier shouldn’t be based on a browser tab. Instead it should be some unique session ID of a particular user.

Finally we build an input tag for the environmental fee checkbox and only show it if configcat says it is enabled for the current user.

Why ConfigCat in the Front-End is not the best Idea

Now that we’ve successfully implemented the flag let’s speak about the main drawback of doing it in the front-end — which is the absence of proper caching. We would basically perform a call to configcat every time a new user accesses our page, not to talk about cache reload or possible stale cache.

As a configcat customer you have a certain quota of API calls. Going beyond that might become expensive very quickly. You can see your current usage by going to the configcat website and selecting ‘Usage and Quota’ in the product menu.

4. Usage and quota tab — I got two configs here, you should only see one

Which is why a better decision is to call ConfigCat from our back-end and let the front-end render the page based on what it gets from server and nothing else.

Calling ConfigCat from the Back-End

Let’s look at another example where we have our page built server-side and sent to the client.

But first — let us change the configuration logic of our feature flag to be slightly more complex. Now, instead of simply flipping a coin we would like to know whether or not a user request comes from a mobile device. For that we are going to need the custom section of the user object — that’s where we basically can put anything. Let’s come up with a simple boolean parameter called isMobile.

5. A more complex example — not just flip a coin but inspect user object and make decision based on its fields

1. Take care of Caching

Have a look at the following file where we define the cache for our ConfigCat client. By default it would use in-memory cache. In a real application you would use a more sophisticated solution, like Redis. Here we simply use a json file in our server’s file system.

2. Create the Client

Finally here’s our code for getting the client instance. I’ve put it to a different file to keep the codebase a bit cleaner.

Our server-side application is very simple even if you’re unfamiliar with Next.js. We’ve got a React component and getServerSideProps method. This method runs on the server. It accepts the user request and handles the communication with ConfigCat. It then passes the obtained feature flag value to the React component, which is now pure and simply renders whatever it is fed.

Start the server with npm start and refresh the page as much as you want — the config is now fetched from the file and no requests are made to the remote server. You can prove it by looking into the usage & quota tab from time to time. You can also lookup the raw configuration in the local file.

3. Take care of Cache Updates

At some point the configuration in our cache will become stale. Notice how we’ve set the cache TTL to almost infinity. How then will we ever be able to react to the configuration updates?

The answer is simple — webhooks.

Webhooks are configured in the ConfigCat UI in a couple of clicks. You can specify one or multiple webhooks for a client — i.e. for a combination of config and environment.

What that means is that whenever any of your flags gets updated a request will be sent to the endpoint you specified in the webhook. In the request body you will find the name of the setting that was changed as well as some other useful details. Here’s the link to the respective documentation:

6. Setting up a webhook

When handling such a request on your server you would usually tell your ConfigCat client to force refresh — i.e. fetch the new configuration values from ConfigCat’s remote.

Let’s make sure our config works and we don’t get the checkbox displayed when using desktop browser. Remember — we currently only show it to mobile users.

7. No checkbox

Now let’s move back to the ConfigCat UI and change the configuration of our flag. This time we only want to display the checkbox if a user is NOT using a mobile device, so we want to match the isMobile field against the string ‘false’ as opposed to ‘true’.

Since I develop on localhost and the url I specified in the webhook is just a fake, I will call the endpoint of my local server from the terminal. You may take my word that ConfigCat would do exactly the same thing remotely.

curl http://localhost:3000/api/configcatwebhook

Now let us refresh the page.

8. Console log result displayed after our client fetched config from configcat

The console log now tells us that according to the new configuration the feature flag is enabled for our request and we can see the checkbox input — success.

Summing it up

In this article I intended to show what ConfigCat is capable of. We went through basic setup of the settings and webhooks, that enable you to control your feature flags in a dynamic way.

What we haven’t covered though are deep dives like different comparator functions, different types of feature flags, webhook’s request body and so on. That would be too much for one article so I leave it to your curiosity.

I hope this information was useful to you and wish you a great time coding!

--

--