·6 min read

Announcing Edge Flags

Andreas ThomasAndreas ThomasSoftware Engineer @Upstash

Whether you want to ship without breaking things, run A/B tests or just want to test in production, feature flags are a great way to dynamically change the behaviour of your app without redeploying. We're excited to announce the public beta release of our new feature flagging library: @upstash/edge-flags.

Edge Flags, as the name implies, is a feature flag solution built to run at the edge. It is using Upstash Redis, a globally replicated serverless Redis service, to store configuration and is designed to work with Next.js and Vercel. We want to support other frameworks in the future, so if you have a suggestion, please let us know!

With the ability to toggle features on and off at the edge, you can quickly respond to user feedback and optimize the user experience. Whether you are looking to perform A/B testing, gradually roll out a new feature, or simply have the ability to turn things off in case of an issue, our feature flagging library has you covered.

How it works

There are two components to this: The console to manage flags and the typescript sdk to use them in your code.

Console

Flag

When you go to console.upstash.com/edge-flags for the first time, you need to select a Redis database to use. This database will be used to store the feature flags. If you don't have a Redis database yet, you can create one for free.

In the console, you can create, update and delete flags or temporarily toggle them on or off. Each flag can have a percentage defined, allowing you to rollout flags gradually to a random subset of your users.

In addition to the percentage, you are able to add rules. Rules can be used to target specific users or groups of users. For example, you can target users geographically or users that have a specific email address domain. To learn more about differen rule types, please check out the rules documentation.

Your App

Adding @upstash/edge-flags to your Next.js application is easy: All we need to do is to install the package, create a simple edge handler and then use the flag in our frontend.

For a full tutorial, please check out the quickstart.

1. Create a Redis database and copy the credentials

If you haven't already, create a new Redis database in the console. Choose Global for the best read latency performance, or select a single region.

Make sure to copy the UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN to your .env file.

2. Install @upstash/edge-flags with your favourite package manager:

npm install @upstash/edge-flags
npm install @upstash/edge-flags

3. Create a new edge function in your Next.js application

/pages/api/edge-flags.ts
import { createEdgeHandler } from "@upstash/edge-flags";
 
export default createEdgeHandler({
  // cache time in seconds, 0 disables the cache
  cacheMaxAge: 0,
 
  // you can omit these to load from env automatically
  redisUrl: process.env.UPSTASH_REDIS_REST_URL!,
  redisToken: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
 
export const config = {
  runtime: "edge",
};
/pages/api/edge-flags.ts
import { createEdgeHandler } from "@upstash/edge-flags";
 
export default createEdgeHandler({
  // cache time in seconds, 0 disables the cache
  cacheMaxAge: 0,
 
  // you can omit these to load from env automatically
  redisUrl: process.env.UPSTASH_REDIS_REST_URL!,
  redisToken: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
 
export const config = {
  runtime: "edge",
};

That's it, all of the evaluation, fetching and caching logic is now handled by the edge function. It will extract the geolocation parameters from the request and use them together with your custom attributes to evaluate the flag.

You can set the cacheMaxAge to a positive integer to try and cache flags in the memory of the edge function. While the edge function remains hot, it does not require a lookup to Redis and can return a result instantly. Caching like this inside functions is quite volatile, as there is no guarantee for how long the edge function remains hot. We will be adding more caching strategies during the beta.

4. Use the flag in your frontend

The last step is to use the flag. The useFlag hook allows you to query a flag in your frontend

In this example we want to modify the navigation to only show a link to beta users.

/app/page.tsx
import { useFlag } from "@upstash/edge-flags";
 
export default function Page() {
  const { isEnabled, loading, error } = useFlag("beta-users", {
    // optional custom attributes
    userId: "chronark",
    company: "Upstash",
  });
 
  if (error) {
    return <div>Something went wrong: {error}</div>;
  }
  if (loading) {
    return <div>Loading...</div>;
  }
  return (
    <div>
      <Link href="/home">Home</Link>
      <Link href="/settings">Settings</Link>
      {/* Only display the beta navigation to beta users */}
      {isEnabled ? <Link href="/beta">Beta</Link> : null}
    </div>
  );
}
/app/page.tsx
import { useFlag } from "@upstash/edge-flags";
 
export default function Page() {
  const { isEnabled, loading, error } = useFlag("beta-users", {
    // optional custom attributes
    userId: "chronark",
    company: "Upstash",
  });
 
  if (error) {
    return <div>Something went wrong: {error}</div>;
  }
  if (loading) {
    return <div>Loading...</div>;
  }
  return (
    <div>
      <Link href="/home">Home</Link>
      <Link href="/settings">Settings</Link>
      {/* Only display the beta navigation to beta users */}
      {isEnabled ? <Link href="/beta">Beta</Link> : null}
    </div>
  );
}

The useFlag hook will query the edge function and return the evaluated result.

Pricing

Using the @upstash/edge-flags sdk and console is 100% free. You only pay for the underlying database that is used to store the flags. Our Redis free tier allows 10,000 requests per day for free. If you need more, you can upgrade and pay $0.20 per 100,000 requests.

We want to reduce the cost even further by adding more caching strategies during the beta. See below for more details.

Documentation

For a full list of features and some explanations, please check out the documentation and stay tuned for a technical deep dive blog post soonTM. If something is not clear or you have any questions, please let us know!

Road to v1

We are currently in beta and are looking for feedback and ideas. The core logic is implemented and tested but there are still opportunities for improvement.

Here are some of the things we are planning to add:

Caching strategies

To reduce the requests made to redis and thus decreasing your bill at the end of the month, we will be adding different ways to cache flags. Caching flags is a double edged sword: The longer the cache time, the fewer requests to Redis need to be made. But at the same time changes to flags will take longer to propagate.

We're currently evaluating the following caching strategies:

  • Cookies
  • Vercel's edge CDN
  • React context

There are pros and cons to each and we would appreciate if you share your feedback and ideas.

Support more frameworks and platforms

Right now edge-flags only works well with Next.js. But the underlying logic is already platform agnostic. We are planning to add support for other frameworks and platforms in the future. Let us know what platform you would like to see next.

Wrapping up

Thank you for checking out edge-flags. If you have any questions or feedback, please reach out to us on Twitter or Discord.

Relevant links: