Elixir/Phoenix Integration Guide

Elixir Feature Flags

Feature flags for Phoenix and Elixir — GenServer caching and LiveView integration

Quick Start

1. Get your API key

Sign up at flagbit.anethoth.com to get your SDK key. The free tier includes 1,000 evaluations/day.

2. Install (optional)

# Add to mix.exs: {:req, "~> 0.4"}

3. Evaluate flags

defmodule MyApp.FlagBit do
  use GenServer

  @url "https://flagbit.anethoth.com/api/v1/evaluate"
  @cache_ttl :timer.seconds(60)

  def start_link(_), do: GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
  def init(state), do: {:ok, state}

  def enabled?(flag_key, context \\ %{}) do
    cache_key = {flag_key, context}
    case GenServer.call(__MODULE__, {:get, cache_key}) do
      {:ok, value} -> value
      :miss ->
        value = fetch_flag(flag_key, context)
        GenServer.cast(__MODULE__, {:put, cache_key, value})
        value
    end
  end

  def handle_call({:get, key}, _from, state) do
    case Map.get(state, key) do
      {value, expires} when expires > System.monotonic_time(:millisecond) ->
        {:reply, {:ok, value}, state}
      _ -> {:reply, :miss, state}
    end
  end

  def handle_cast({:put, key, value}, state) do
    expires = System.monotonic_time(:millisecond) + @cache_ttl
    {:noreply, Map.put(state, key, {value, expires})}
  end

  defp fetch_flag(flag_key, context) do
    sdk_key = Application.get_env(:my_app, :flagbit_sdk_key)
    case Req.post(@url,
      json: %{flag_key: flag_key, context: context},
      headers: [{"x-sdk-key", sdk_key}],
      receive_timeout: 5000
    ) do
      {:ok, %{body: %{"value" => value}}} -> value
      _ -> false
    end
  end
end

# Phoenix controller
defmodule MyAppWeb.DashboardController do
  use MyAppWeb, :controller

  def index(conn, _params) do
    user_id = conn.assigns.current_user.id |> to_string()
    if MyApp.FlagBit.enabled?("new-dashboard", %{"user_id" => user_id}) do
      render(conn, :index_v2)
    else
      render(conn, :index)
    end
  end
end

# LiveView
defmodule MyAppWeb.HomeLive do
  use MyAppWeb, :live_view

  def mount(_params, session, socket) do
    show_beta = MyApp.FlagBit.enabled?("beta-features",
      %{"user_id" => session["user_id"]})
    {:ok, assign(socket, show_beta: show_beta)}
  end
end

Use Cases for Elixir/Phoenix

Hot Code Upgrades

Feature flags complement BEAM's hot code loading — toggle features without even restarting the VM.

LiveView Experiments

A/B test different LiveView component implementations in real-time.

GenServer Migrations

Gradually migrate from one GenServer implementation to another with percentage rollouts.

Cluster-Wide Toggles

Use distributed Erlang to sync flag states across all nodes in your cluster.

How FlagBit Works

1

Create a Flag

Define flags in your FlagBit dashboard with targeting rules and rollout percentages.

2

Evaluate in Code

Call the evaluate endpoint from your Elixir/Phoenix app with user context for targeted rollouts.

3

Toggle Instantly

Enable, disable, or adjust rollouts in real-time. No redeployment needed.

FAQ

GenServer is Elixir-native — no external cache needed. It handles concurrent access safely and integrates with OTP supervision.

Yes — evaluate flags in mount/3 and assign the result. The flag value persists for the LiveView session.

Yes — ETS gives concurrent reads without bottlenecking on GenServer calls. Better for high-throughput scenarios.

Evaluate flags in channel join/3 to gate WebSocket features per user.

Start using feature flags in Elixir/Phoenix

Free tier includes 1 project, 10 flags, and 1,000 evaluations/day. No credit card required.

Get Your Free API Key