<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Domenico Giordano</title>
    <description>The latest articles on Forem by Domenico Giordano (@domenico_giordano_e441224).</description>
    <link>https://forem.com/domenico_giordano_e441224</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2672712%2F2bd6e425-3412-4f19-8bf3-d48f0bd43609.jpg</url>
      <title>Forem: Domenico Giordano</title>
      <link>https://forem.com/domenico_giordano_e441224</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/domenico_giordano_e441224"/>
    <language>en</language>
    <item>
      <title>Feature Flags Pricing Comparison 2026: Stop Paying Per Seat</title>
      <dc:creator>Domenico Giordano</dc:creator>
      <pubDate>Fri, 03 Apr 2026 12:55:17 +0000</pubDate>
      <link>https://forem.com/domenico_giordano_e441224/feature-flags-pricing-comparison-2026-stop-paying-per-seat-212g</link>
      <guid>https://forem.com/domenico_giordano_e441224/feature-flags-pricing-comparison-2026-stop-paying-per-seat-212g</guid>
      <description>&lt;p&gt;I recently spent a weekend calculating the actual cost of feature flags across every major platform. The difference between the cheapest and most expensive option for the same workload? Over 100x. Here's the full breakdown so you don't have to do the math yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Enterprise Pricing Problem
&lt;/h2&gt;

&lt;p&gt;Feature flags pricing has become absurdly complex. The core concept is simple — a conditional check that's controlled remotely — yet the industry has converged on pricing models that charge five or six figures per year for what is fundamentally a key-value store with targeting rules.&lt;/p&gt;

&lt;p&gt;LaunchDarkly charges per Monthly Active User (MAU). Statsig charges per event. Optimizely bundles feature flags into a full experimentation platform you might not need. For a team of 10 developers with a growing product, the annual cost of feature flags can exceed what you pay for your entire cloud infrastructure.&lt;/p&gt;

&lt;p&gt;This isn't sustainable. And the market is responding — new tools with transparent, predictable pricing are gaining traction precisely because developers are tired of "contact sales" being the only way to find out what something costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flags Pricing Models Explained
&lt;/h2&gt;

&lt;p&gt;There are four main pricing models in the feature flags market:&lt;/p&gt;

&lt;h3&gt;
  
  
  Per Seat (Per Developer)
&lt;/h3&gt;

&lt;p&gt;You pay for each team member who accesses the dashboard. Simple to understand, but it creates a perverse incentive: teams limit who can manage flags, which slows down the release process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who uses it&lt;/strong&gt;: GrowthBook, some Flagsmith plans&lt;/p&gt;

&lt;h3&gt;
  
  
  Per MAU (Monthly Active Users)
&lt;/h3&gt;

&lt;p&gt;You pay based on how many unique users evaluate flags in your application. This punishes success — the more users you acquire, the more you pay for feature flags, even if your flag usage stays constant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who uses it&lt;/strong&gt;: LaunchDarkly, Statsig&lt;/p&gt;

&lt;h3&gt;
  
  
  Per Config Fetch / Event
&lt;/h3&gt;

&lt;p&gt;You pay per API call or flag evaluation. More predictable than MAU, but can still surprise you if you increase polling frequency or add more clients.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who uses it&lt;/strong&gt;: ConfigCat (config fetches)&lt;/p&gt;

&lt;h3&gt;
  
  
  Flat Tier (Per Request Bands)
&lt;/h3&gt;

&lt;p&gt;You pick a plan based on request volume. The price is fixed within each tier, so you know exactly what you'll pay. No surprises when you add users, team members, or flags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who uses it&lt;/strong&gt;: Rollgate&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flags Pricing Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Rollgate&lt;/th&gt;
&lt;th&gt;LaunchDarkly&lt;/th&gt;
&lt;th&gt;Flagsmith&lt;/th&gt;
&lt;th&gt;ConfigCat&lt;/th&gt;
&lt;th&gt;GrowthBook&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500K req/mo, 3 projects, unlimited flags&lt;/td&gt;
&lt;td&gt;Limited trial&lt;/td&gt;
&lt;td&gt;50K req/mo&lt;/td&gt;
&lt;td&gt;10 flags&lt;/td&gt;
&lt;td&gt;Free (self-hosted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Entry plan&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€39/mo (Starter)&lt;/td&gt;
&lt;td&gt;~$700/mo (est.)&lt;/td&gt;
&lt;td&gt;~$45/mo&lt;/td&gt;
&lt;td&gt;~$84/mo&lt;/td&gt;
&lt;td&gt;$99/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mid plan&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€99/mo (Pro)&lt;/td&gt;
&lt;td&gt;Custom quote&lt;/td&gt;
&lt;td&gt;~$125/mo&lt;/td&gt;
&lt;td&gt;Custom&lt;/td&gt;
&lt;td&gt;$199/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€299/mo (Growth)&lt;/td&gt;
&lt;td&gt;$25K-150K/yr&lt;/td&gt;
&lt;td&gt;Custom&lt;/td&gt;
&lt;td&gt;Custom&lt;/td&gt;
&lt;td&gt;Custom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing unit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SDK requests&lt;/td&gt;
&lt;td&gt;MAU&lt;/td&gt;
&lt;td&gt;Requests + seats&lt;/td&gt;
&lt;td&gt;Config fetches&lt;/td&gt;
&lt;td&gt;Seats&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Price scales with&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API traffic&lt;/td&gt;
&lt;td&gt;User growth&lt;/td&gt;
&lt;td&gt;Traffic + team size&lt;/td&gt;
&lt;td&gt;Polling frequency&lt;/td&gt;
&lt;td&gt;Team size&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: Competitor pricing changes frequently. The figures above are estimates based on publicly available information as of March 2026. Always check each vendor's pricing page for current rates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What's Included at Each Rollgate Tier
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Starter (€39-45/mo)&lt;/th&gt;
&lt;th&gt;Pro (€99-119/mo)&lt;/th&gt;
&lt;th&gt;Growth (€299-349/mo)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SDK requests/mo&lt;/td&gt;
&lt;td&gt;500K&lt;/td&gt;
&lt;td&gt;1M&lt;/td&gt;
&lt;td&gt;3M&lt;/td&gt;
&lt;td&gt;12M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flag evaluations/mo&lt;/td&gt;
&lt;td&gt;5M&lt;/td&gt;
&lt;td&gt;10M&lt;/td&gt;
&lt;td&gt;30M&lt;/td&gt;
&lt;td&gt;120M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Projects&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flags&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Environments&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team members&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSE connections&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit log retention&lt;/td&gt;
&lt;td&gt;3 days&lt;/td&gt;
&lt;td&gt;14 days&lt;/td&gt;
&lt;td&gt;90 days&lt;/td&gt;
&lt;td&gt;1 year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheduled changes&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1-click rollback&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RBAC&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLA&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;99.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The annual billing option saves roughly 15-18% on each paid plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost: A 10-Developer Team with 2M Requests/Month
&lt;/h2&gt;

&lt;p&gt;Let's make this concrete. Your team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 developers with dashboard access&lt;/li&gt;
&lt;li&gt;50,000 Monthly Active Users&lt;/li&gt;
&lt;li&gt;2 million SDK requests per month (polling every 30 seconds across web + mobile)&lt;/li&gt;
&lt;li&gt;3 environments (dev, staging, production)&lt;/li&gt;
&lt;li&gt;15 active feature flags&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rollgate: €99/month (Pro)
&lt;/h3&gt;

&lt;p&gt;The Pro plan covers 3M requests/month, 10 projects, 15 team members, and unlimited flags. All environments included. Scheduled changes and rollback included.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Annual: €99 x 12 = €1,188/year&lt;/strong&gt; (or €1,068 with annual billing)&lt;/p&gt;

&lt;h3&gt;
  
  
  LaunchDarkly: Estimated $8,000-12,000/month
&lt;/h3&gt;

&lt;p&gt;LaunchDarkly prices by MAU. At 50K MAU, you're well past the starter tier. Enterprise contracts typically start at $25K/year for small teams and scale significantly with MAU growth. With 50K MAU, expect quotes in the $100K-150K/year range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Annual: $96,000-$150,000/year&lt;/strong&gt; (estimated, check their sales team for exact pricing)&lt;/p&gt;

&lt;h3&gt;
  
  
  Flagsmith: Estimated $125-250/month
&lt;/h3&gt;

&lt;p&gt;Flagsmith's cloud pricing includes per-seat and per-request components. For 10 seats and 2M requests, expect mid-tier pricing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Annual: ~$1,500-$3,000/year&lt;/strong&gt; (estimated)&lt;/p&gt;

&lt;h3&gt;
  
  
  ConfigCat: Estimated $150-300/month
&lt;/h3&gt;

&lt;p&gt;ConfigCat charges per config fetch. With 2M requests/month and 10 team members, you'll likely need a mid-to-high tier plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Annual: ~$1,800-$3,600/year&lt;/strong&gt; (estimated)&lt;/p&gt;

&lt;h3&gt;
  
  
  GrowthBook: $199/month (Pro)
&lt;/h3&gt;

&lt;p&gt;GrowthBook charges per seat. The Pro plan at $199/month covers up to 20 seats with premium features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Annual: $2,388/year&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Summary
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Estimated Annual Cost&lt;/th&gt;
&lt;th&gt;Cost vs Rollgate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rollgate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~€1,100/year&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flagsmith&lt;/td&gt;
&lt;td&gt;~$1,500-3,000/year&lt;/td&gt;
&lt;td&gt;1.4-2.7x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ConfigCat&lt;/td&gt;
&lt;td&gt;~$1,800-3,600/year&lt;/td&gt;
&lt;td&gt;1.6-3.3x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GrowthBook&lt;/td&gt;
&lt;td&gt;~$2,400/year&lt;/td&gt;
&lt;td&gt;2.2x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LaunchDarkly&lt;/td&gt;
&lt;td&gt;~$96,000-150,000/year&lt;/td&gt;
&lt;td&gt;87-136x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;These are rough estimates for comparison purposes. Actual costs depend on your specific usage patterns, negotiated contracts, and plan selection. Rollgate's pricing is publicly listed; for other tools, check their websites or contact their sales teams.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The gap is largest with LaunchDarkly because MAU-based pricing fundamentally scales differently than request-based pricing. As your product grows from 50K to 500K users, your LaunchDarkly bill grows 10x. Your Rollgate bill stays the same — or moves one tier up if your request volume increases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Request-Based Pricing Makes More Sense
&lt;/h2&gt;

&lt;p&gt;MAU-based pricing charges you for users who might evaluate a flag once per session. Request-based pricing charges you for actual API usage. The difference matters because:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your user count grows faster than your flag usage.&lt;/strong&gt; When you go from 10K to 100K users, your feature flag evaluation patterns don't change 10x. You still have the same polling intervals, the same SDKs, the same flags. Your request volume grows, but not linearly with users — especially with local caching and SSE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can control request volume.&lt;/strong&gt; Increase polling interval from 30s to 60s, and you cut requests in half. Enable SSE, and you eliminate most polling requests entirely. You can't control how many users sign up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's predictable.&lt;/strong&gt; A polling client at 30s intervals generates approximately 86K requests per month. Multiply by your client count and you know your tier. With MAU pricing, a viral marketing campaign can triple your bill overnight.&lt;/p&gt;

&lt;p&gt;Here's a typical integration — the SDK handles polling and caching automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RollgateProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RollgateProvider&lt;/span&gt;
      &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rg_client_your_key"&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;pollingInterval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 30s default&lt;/span&gt;
        &lt;span class="na"&gt;enableSSE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// real-time updates, reduces polling&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FeatureFlaggedApp&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RollgateProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;FeatureFlaggedApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showNewUI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redesigned-ui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxUploadSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max-upload-mb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showNewUI&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewUI&lt;/span&gt; &lt;span class="na"&gt;maxUpload&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;maxUploadSize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrentUI&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One SDK connection, one polling interval, all flags cached locally. Whether you have 1,000 or 1,000,000 users, each client makes the same number of requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Calculate Your Feature Flags Cost
&lt;/h2&gt;

&lt;p&gt;Before you commit to a tool, estimate your actual usage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Count your SDK clients&lt;/strong&gt;: How many servers, browser instances, or mobile apps will connect? Each one polls independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Determine your polling interval&lt;/strong&gt;: Default is usually 30 seconds. At 30s, one client = ~86K requests/month. At 60s = ~43K. With SSE, polling is minimal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiply&lt;/strong&gt;: &lt;code&gt;clients x requests_per_client = monthly_requests&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pick the tier&lt;/strong&gt; that covers your volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: You have 3 API servers + 1 web frontend. With 30s polling, that's 4 x 86K = 344K requests/month. Rollgate Free (500K) covers this. You pay nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scaling example&lt;/strong&gt;: Your product grows to 20 API servers + 5 frontend instances. That's 25 x 86K = 2.15M requests/month. Rollgate Pro (3M) at €99/month covers this. On LaunchDarkly, the cost would depend on how many end users those 20 servers handle — potentially tens of thousands of dollars per month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Overpaying for Feature Flags
&lt;/h2&gt;

&lt;p&gt;Feature flags should be a line item, not a line of the budget. The core technology — flag evaluation, targeting rules, SDK communication — isn't complex enough to justify enterprise pricing for most teams.&lt;/p&gt;

&lt;p&gt;Rollgate offers transparent, flat-tier pricing with no surprises. The free tier (500K requests/month) is generous enough for small teams and side projects. Paid plans start at €39/month and include &lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;scheduled releases&lt;/a&gt; and instant rollback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;Check the full pricing at rollgate.io&lt;/a&gt; or &lt;a href="https://demo.rollgate.io" rel="noopener noreferrer"&gt;try the live demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more context on choosing a feature flag tool, see our &lt;a href="https://rollgate.io/blog/launchdarkly-alternative" rel="noopener noreferrer"&gt;LaunchDarkly alternative comparison&lt;/a&gt; and &lt;a href="https://rollgate.io/blog/gradual-rollouts-guide" rel="noopener noreferrer"&gt;gradual rollout strategies&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;Rollgate&lt;/a&gt;, a feature flag platform for developers. If you have questions about feature flags, drop them in the comments — happy to help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Feature Flags vs Feature Branches: When to Use Each</title>
      <dc:creator>Domenico Giordano</dc:creator>
      <pubDate>Fri, 03 Apr 2026 12:55:16 +0000</pubDate>
      <link>https://forem.com/domenico_giordano_e441224/feature-flags-vs-feature-branches-when-to-use-each-5gej</link>
      <guid>https://forem.com/domenico_giordano_e441224/feature-flags-vs-feature-branches-when-to-use-each-5gej</guid>
      <description>&lt;p&gt;I used to think feature branches were the only way to manage releases. Then I joined a team that used feature flags with trunk-based development, and I never looked back. Turns out, the "feature flags vs feature branches" debate is a false dichotomy — here's how to think about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The False Dichotomy
&lt;/h2&gt;

&lt;p&gt;Developers often frame feature flags vs feature branches as an either/or choice. In reality, they solve different problems and work best together. Feature branches manage &lt;strong&gt;code integration&lt;/strong&gt;. Feature flags manage &lt;strong&gt;feature release&lt;/strong&gt;. Understanding this distinction is key to a healthy deployment workflow.&lt;/p&gt;

&lt;p&gt;Whether you call them feature flags, feature toggles, or feature switches, the core idea is the same: decouple deployment from release. And whether you use Git Flow, GitHub Flow, or trunk-based development, branches are about managing code changes. Once you internalize that these tools operate at different layers, the "feature branch vs feature toggle" debate dissolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flags vs Feature Toggles: Are They the Same?
&lt;/h2&gt;

&lt;p&gt;Before we go deeper, let's clear up a common source of confusion. You'll see "feature flags," "feature toggles," "feature switches," and "feature gates" used across blog posts, documentation, and conference talks. &lt;strong&gt;They all refer to the same concept&lt;/strong&gt;: a conditional check in your code that controls whether a piece of functionality is active.&lt;/p&gt;

&lt;p&gt;Martin Fowler popularized the term "feature toggle" in his 2010 article. The term "feature flag" gained traction in the DevOps community and is more common today, especially in SaaS tooling. Some teams use "toggle" for simple on/off switches and "flag" when targeting rules and percentage rollouts are involved, but this distinction isn't universal.&lt;/p&gt;

&lt;p&gt;Throughout this article, we use "feature flag" and "feature toggle" interchangeably. If you've been searching for "feature branch vs feature toggle," you're in the right place.&lt;/p&gt;

&lt;p&gt;For a complete introduction to the concept, see our guide on &lt;a href="https://rollgate.io/blog/what-are-feature-flags" rel="noopener noreferrer"&gt;what feature flags are and how they work&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Feature Branches?
&lt;/h2&gt;

&lt;p&gt;Feature branches are a Git workflow where each new feature is developed on a separate branch. When the feature is ready, the branch is merged into the main branch (usually &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;develop&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/new-payment-flow
&lt;span class="c"&gt;# ... work on the feature ...&lt;/span&gt;
git push origin feature/new-payment-flow
&lt;span class="c"&gt;# Create a pull request, get reviews, merge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Advantages of Feature Branches
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: Changes are isolated until the branch is merged&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review&lt;/strong&gt;: Pull requests enable structured review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI checks&lt;/strong&gt;: Automated tests run on each branch before merging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Familiar&lt;/strong&gt;: Every developer knows Git branching&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Problems with Feature Branches
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Long-lived branches diverge&lt;/strong&gt;: The longer a branch lives, the harder the merge. Conflicts accumulate, and integration becomes painful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delayed feedback&lt;/strong&gt;: You don't know if your feature works in production until it's merged and deployed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All-or-nothing releases&lt;/strong&gt;: Merging a feature branch means releasing it. There's no way to deploy the code but hide the feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge conflicts&lt;/strong&gt;: Large branches touching many files create merge hell, especially on active codebases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Hidden Cost of Long-Lived Feature Branches
&lt;/h2&gt;

&lt;p&gt;The problems above aren't theoretical. Long-lived feature branches impose real, measurable costs on engineering teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merge Conflict Escalation
&lt;/h3&gt;

&lt;p&gt;Research from DORA (DevOps Research and Assessment) consistently shows that teams practicing trunk-based development with short-lived branches ship faster and with fewer failures. The reason is compounding: every day a branch stays open, the probability of a merge conflict increases non-linearly. A branch open for 2 days might have a 10% chance of conflict. At 2 weeks, that number can exceed 80%, depending on team size and codebase activity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Switching Tax
&lt;/h3&gt;

&lt;p&gt;When a developer opens a PR for a 3-week-old branch and receives 47 review comments, the original context is gone. The developer has moved on to other work. Rebuilding mental context to address feedback on stale code is one of the most expensive activities in software development. Studies suggest context switching can cost 20-25 minutes per interruption.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integration Risk Compounds
&lt;/h3&gt;

&lt;p&gt;Consider a team of 6 developers, each working on a separate feature branch for 2 weeks. When all six branches merge in the same sprint, the integration surface is enormous. Features that worked in isolation break when combined. This "merge day" anti-pattern is why many teams dread release weeks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delayed Bug Discovery
&lt;/h3&gt;

&lt;p&gt;A bug introduced on a feature branch stays hidden until merge. If your branch diverged from &lt;code&gt;main&lt;/code&gt; 10 days ago, the bug has had 10 days to become entangled with other changes. Compare this to trunk-based development where the same bug would surface within hours, when it's cheap to fix and the context is fresh.&lt;/p&gt;

&lt;p&gt;The alternative is clear: keep branches short (hours to days, not weeks) and use feature flags for long-running features that span multiple merges.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Feature Flags?
&lt;/h2&gt;

&lt;p&gt;Feature flags wrap new functionality in a conditional check. The code is deployed to production but only activated when the flag is enabled. This decouples deployment from release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PaymentPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showNewPayment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-payment-flow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;showNewPayment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NewPaymentFlow&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CurrentPaymentFlow&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the backend, the same pattern works in any language. Here's Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="n"&gt;rollgate&lt;/span&gt; &lt;span class="s"&gt;"github.com/rollgate/sdk-go"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;paymentHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getUserFromContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rollgate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollgate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rollgate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new-payment-flow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;handleNewPaymentFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;handleCurrentPaymentFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Advantages of Feature Flags
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deploy anytime&lt;/strong&gt;: Code goes to production even if the feature isn't ready for users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradual rollout&lt;/strong&gt;: Enable for 1% of users, then 10%, then 100% — learn more in our &lt;a href="https://rollgate.io/blog/gradual-rollouts-guide" rel="noopener noreferrer"&gt;gradual rollouts guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant rollback&lt;/strong&gt;: Disable a flag in seconds, no redeployment needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Targeting&lt;/strong&gt;: Show features to specific users, teams, or segments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trunk-based development&lt;/strong&gt;: Everyone commits to &lt;code&gt;main&lt;/code&gt;, reducing merge conflicts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled releases&lt;/strong&gt;: Combine flags with time-based rules for &lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;scheduled feature releases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Problems with Feature Flags
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code complexity&lt;/strong&gt;: Two code paths mean more logic to maintain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale flags&lt;/strong&gt;: Unused flags accumulate as technical debt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing surface&lt;/strong&gt;: You need to test both flag states&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requires discipline&lt;/strong&gt;: Flags need to be cleaned up after full rollout&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Companies Like Google and Netflix Use Trunk-Based Development
&lt;/h2&gt;

&lt;p&gt;Trunk-based development with feature flags isn't a niche practice. It's how the world's most productive engineering organizations ship software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google
&lt;/h3&gt;

&lt;p&gt;Google operates one of the largest monorepos in existence, with over 80,000 engineers committing to a single repository. Long-lived feature branches would be impossible at this scale. Instead, Google uses trunk-based development where all engineers commit to &lt;code&gt;head&lt;/code&gt;. Incomplete features are guarded by flags (internally called "experiments" or "flags") that keep them invisible until ready. This approach allows Google to make over 60,000 commits per day without breaking the build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Netflix
&lt;/h3&gt;

&lt;p&gt;Netflix deploys hundreds of times per day across its microservices architecture. Their engineering blog describes how every feature is wrapped in a flag before reaching production. This allows them to test new recommendation algorithms, UI changes, and encoding pipelines with real traffic at controlled percentages. When a new video player feature caused buffering issues in 2019, they disabled it for all users in under 30 seconds — something a rollback deployment would have taken minutes or longer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meta (Facebook)
&lt;/h3&gt;

&lt;p&gt;Meta ships code to production twice daily using a system called Gatekeeper, their internal feature flag platform. Every new feature — from News Feed ranking changes to Messenger updates — goes through a flag-controlled rollout. Engineers can target by geography, device type, employee status, or custom segments. This system handles billions of flag evaluations per day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spotify
&lt;/h3&gt;

&lt;p&gt;Spotify uses feature flags extensively for their "controlled rollout" process. New features are first exposed to internal employees ("dogfooding"), then to a small percentage of users in a single market, then expanded globally. This layered approach catches issues at each stage before they reach the full 500+ million user base.&lt;/p&gt;

&lt;p&gt;The pattern is consistent across these organizations: short-lived branches for code management, feature flags for release management.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Feature Branches
&lt;/h2&gt;

&lt;p&gt;Feature branches are the right choice when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Short-lived work&lt;/strong&gt; (1-3 days): Bug fixes, small features, refactors that can be reviewed and merged quickly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review is essential&lt;/strong&gt;: You want a structured PR workflow with approvals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No production risk&lt;/strong&gt;: The change doesn't need gradual rollout or targeting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-source contributions&lt;/strong&gt;: External contributors need isolated branches for PRs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use Feature Flags
&lt;/h2&gt;

&lt;p&gt;Feature flags are the right choice when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gradual rollout needed&lt;/strong&gt;: You want to release to a percentage of users first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-running features&lt;/strong&gt;: Work that spans multiple sprints or weeks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production testing&lt;/strong&gt;: You need to verify behavior in production before full release&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kill switch required&lt;/strong&gt;: The feature could impact system stability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User targeting&lt;/strong&gt;: Different users should see different experiences&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A/B testing&lt;/strong&gt;: You're running experiments between variants&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Best Approach: Use Both
&lt;/h2&gt;

&lt;p&gt;The most effective teams use short-lived feature branches combined with feature flags:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a short-lived branch&lt;/strong&gt; for a small piece of work (1-2 days)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrap new UI or behavior&lt;/strong&gt; behind a feature flag&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge to main quickly&lt;/strong&gt; — the flag is off, so nothing changes for users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy to production&lt;/strong&gt; — the code is there but hidden&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable the flag gradually&lt;/strong&gt; when the full feature is ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean up the flag&lt;/strong&gt; once the feature is at 100%&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This gives you the best of both worlds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Short branches&lt;/strong&gt; avoid merge conflicts and integration pain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature flags&lt;/strong&gt; give you release control without deployment pressure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trunk-based development&lt;/strong&gt; keeps the main branch always deployable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous delivery&lt;/strong&gt; becomes natural, not scary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Trunk-Based Development with Feature Flags
&lt;/h2&gt;

&lt;p&gt;Trunk-based development (TBD) is the practice of keeping branches short (hours to days) and merging to &lt;code&gt;main&lt;/code&gt; frequently. Feature flags are what make TBD safe for large features:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Day 1: Merge backend API behind flag -&amp;gt; Deploy -&amp;gt; Flag off
Day 2: Merge UI component behind flag -&amp;gt; Deploy -&amp;gt; Flag off
Day 3: Merge integration tests -&amp;gt; Deploy -&amp;gt; Flag off
Day 4: Enable flag for internal team -&amp;gt; Test in production
Day 5: Rollout to 10% -&amp;gt; Monitor metrics
Day 7: Rollout to 100% -&amp;gt; Remove flag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each merge is small, easy to review, and safe to deploy. The feature grows incrementally in production without affecting users until you decide it's ready.&lt;/p&gt;

&lt;p&gt;Here's a concrete Node.js example of a flag-guarded API endpoint that you can merge to &lt;code&gt;main&lt;/code&gt; safely on Day 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Rollgate&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rollgate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Rollgate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ROLLGATE_SERVER_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/checkout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useNewCheckout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;rollgate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-checkout-flow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;useNewCheckout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;handleNewCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;handleLegacyCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Migration Guide: From Feature Branches to Feature Flags
&lt;/h2&gt;

&lt;p&gt;If your team currently relies on long-lived feature branches, migrating to a flag-based workflow doesn't have to happen overnight. Here's a practical step-by-step approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Pick One Feature as a Pilot
&lt;/h3&gt;

&lt;p&gt;Don't try to convert your entire workflow at once. Choose a medium-complexity feature that's about to start development. This gives you a real scenario to learn from without risking critical work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Set Up Your Flag Service
&lt;/h3&gt;

&lt;p&gt;You need a way to create and manage flags. You can start with environment variables or a config file, but a dedicated service like &lt;a href="https://rollgate.io/blog/launchdarkly-alternative" rel="noopener noreferrer"&gt;Rollgate&lt;/a&gt; gives you a dashboard, targeting rules, and audit logs from day one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Adopt the Branch + Flag Pattern
&lt;/h3&gt;

&lt;p&gt;Instead of a single long-lived &lt;code&gt;feature/new-dashboard&lt;/code&gt; branch, break the work into small PRs (each 1-2 days):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# PR 1: Add the flag and the empty shell&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; add-dashboard-flag
&lt;span class="c"&gt;# Create the flag in Rollgate, add the conditional check&lt;/span&gt;
&lt;span class="c"&gt;# Merge to main -- flag is OFF, no user impact&lt;/span&gt;

&lt;span class="c"&gt;# PR 2: Build the data layer&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; dashboard-data-layer
&lt;span class="c"&gt;# Add API endpoints behind the flag&lt;/span&gt;
&lt;span class="c"&gt;# Merge to main -- still invisible to users&lt;/span&gt;

&lt;span class="c"&gt;# PR 3: Build the UI&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; dashboard-ui
&lt;span class="c"&gt;# Add components behind the flag&lt;/span&gt;
&lt;span class="c"&gt;# Merge to main -- still invisible&lt;/span&gt;

&lt;span class="c"&gt;# Ready? Enable the flag for your team first, then gradually roll out.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Establish Flag Hygiene Rules
&lt;/h3&gt;

&lt;p&gt;Agree on team conventions before flags accumulate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Naming&lt;/strong&gt;: Use a consistent pattern like &lt;code&gt;feature.dashboard-v2&lt;/code&gt; or &lt;code&gt;release.new-checkout&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership&lt;/strong&gt;: Every flag has an owner responsible for cleanup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTL&lt;/strong&gt;: Set an expected removal date when creating the flag&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup sprint&lt;/strong&gt;: Dedicate time each sprint to removing fully-rolled-out flags&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Expand to the Full Team
&lt;/h3&gt;

&lt;p&gt;Once the pilot is complete, share lessons learned and repeat the pattern. Most teams report that within 2-3 sprints, the flag-based workflow feels natural and the benefits are obvious: fewer merge conflicts, faster releases, and fewer incidents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Feature Branches Only&lt;/th&gt;
&lt;th&gt;Feature Branches + Flags&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Branch lifetime&lt;/td&gt;
&lt;td&gt;Days to weeks&lt;/td&gt;
&lt;td&gt;Hours to days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge conflicts&lt;/td&gt;
&lt;td&gt;Frequent&lt;/td&gt;
&lt;td&gt;Rare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Release control&lt;/td&gt;
&lt;td&gt;None (merge = release)&lt;/td&gt;
&lt;td&gt;Full (gradual, targeted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback speed&lt;/td&gt;
&lt;td&gt;Minutes (redeploy)&lt;/td&gt;
&lt;td&gt;Seconds (toggle flag)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production testing&lt;/td&gt;
&lt;td&gt;Not possible&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A/B testing&lt;/td&gt;
&lt;td&gt;Not possible&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can I use feature flags without a feature flag service?
&lt;/h3&gt;

&lt;p&gt;Yes. The simplest feature flag is an &lt;code&gt;if&lt;/code&gt; statement checking an environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ENABLE_NEW_DASHBOARD&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showNewDashboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works for basic use cases, but it has limitations. Changing a flag requires redeployment, there's no gradual rollout, no user targeting, and no audit trail. As your team grows and you manage more flags, a dedicated service pays for itself in reduced deployment risk and developer time. Most teams start with env vars and upgrade to a flag service once they hit 5-10 flags.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do feature flags slow down my application?
&lt;/h3&gt;

&lt;p&gt;A well-implemented feature flag adds negligible overhead. The flag evaluation itself is a simple conditional check — microseconds at most. Modern SDKs cache flag values locally and sync in the background, so evaluations don't make network requests on the hot path.&lt;/p&gt;

&lt;p&gt;In Go, a cached flag evaluation looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// This reads from local cache -- no network call&lt;/span&gt;
&lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rollgate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new-feature"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// Typical evaluation time: &amp;lt;1 microsecond&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The performance concern is valid only if your implementation makes a remote API call on every evaluation — which no production-grade SDK does.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I handle database migrations with feature flags?
&lt;/h3&gt;

&lt;p&gt;Database migrations are one of the trickier aspects of flag-based development. The key principle is: &lt;strong&gt;your database schema must support both code paths simultaneously&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's a practical approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Additive migrations only&lt;/strong&gt;: Add new columns or tables, never remove or rename existing ones while the flag is active&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dual-write pattern&lt;/strong&gt;: When the flag is on, write data to both the old and new schema. When off, write only to the old schema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backfill after full rollout&lt;/strong&gt;: Once the flag is at 100% and removed, run a migration to clean up the old schema
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Always write to the existing table&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// When the flag is on, also write to the new normalized tables&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;rollgate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;normalized-orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orderHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orderLines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach avoids the scenario where you roll back a flag and lose access to data written in a new format. Both code paths can read from the same source during the transition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Feature branches and feature flags aren't competing approaches — they're complementary tools. Use feature branches for code management and review. Use feature flags for release management and safety. Together, they enable fast, safe, continuous delivery.&lt;/p&gt;

&lt;p&gt;If you're still doing long-lived feature branches with big-bang releases, consider adding feature flags to your workflow. Start with one flag on your next feature and experience the difference. The teams at Google, Netflix, and Spotify didn't adopt this pattern because it was trendy — they adopted it because it works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.rollgate.io/register" rel="noopener noreferrer"&gt;Get started with Rollgate&lt;/a&gt; — free tier, no credit card required.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;Rollgate&lt;/a&gt;, a feature flag platform for developers. If you have questions about feature flags, drop them in the comments — happy to help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How I Built a Feature Flags SaaS as a Solo Developer</title>
      <dc:creator>Domenico Giordano</dc:creator>
      <pubDate>Fri, 03 Apr 2026 12:55:15 +0000</pubDate>
      <link>https://forem.com/domenico_giordano_e441224/how-i-built-a-feature-flags-saas-as-a-solo-developer-4417</link>
      <guid>https://forem.com/domenico_giordano_e441224/how-i-built-a-feature-flags-saas-as-a-solo-developer-4417</guid>
      <description>&lt;p&gt;I spent a year building a feature flags SaaS from scratch. No co-founder, no VC, just me, Go, and a Hetzner VPS. This post covers the full technical journey — the stack I chose, the features I built, the mistakes I made, and the real numbers behind a solo SaaS. If you're thinking about building your own developer tool, I hope this helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built Rollgate: From Side Project to Feature Flags SaaS
&lt;/h2&gt;

&lt;p&gt;Over the past year, I built Rollgate, a SaaS platform for feature flag management. The goal was simple: offer the same capabilities as LaunchDarkly — gradual rollouts, user targeting, A/B testing, kill switches — without the $70k/year enterprise price tag.&lt;/p&gt;

&lt;p&gt;In this article, I share the technical journey: architectural decisions, all the features I implemented, mistakes made, and the real numbers behind a SaaS built by a single developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Anyone who has worked in a development team knows the situation: you want to release a feature, but you're not sure it works for all users. Traditional deployment is a binary event — either the feature is live for everyone, or for no one.&lt;/p&gt;

&lt;p&gt;Feature flags solve this by separating deployment from release. You can deploy code to production and enable it gradually: first 1% of users, then 5%, then 25%, and so on. If something goes wrong, you turn off the flag in a second — no rollback, no hotfix, no downtime.&lt;/p&gt;

&lt;p&gt;Tools like LaunchDarkly do exactly this, but cost $25k to $150k per year. For a startup or mid-size team, that's prohibitive. I thought: can I build something equivalent and offer it at a fraction of the price?&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Tech Stack
&lt;/h2&gt;

&lt;p&gt;The first fundamental decision was the stack. I had two non-negotiable requirements: low latency (feature flags are evaluated on every request) and operational simplicity (fewer moving parts means fewer things to break).&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend: Go
&lt;/h3&gt;

&lt;p&gt;I chose Go for the backend API for three reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; — A flag evaluation must happen in microseconds. Go compiles to native binary, has no significant GC pauses, and handles thousands of concurrent connections with goroutines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple deployment&lt;/strong&gt; — A single static binary. No runtime, no dependencies. The final Docker image weighs 20MB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excellent stdlib&lt;/strong&gt; — HTTP server, JSON encoding, crypto, testing — all built-in. Fewer external dependencies means less surface area for bugs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The router is Chi, lightweight and net/http-compatible. No heavy frameworks — I prefer composition over convention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend: Next.js
&lt;/h3&gt;

&lt;p&gt;For the dashboard, I chose Next.js with React and Tailwind CSS. It provides SSR/SSG for marketing pages (SEO), API routes for backend proxying, and a smooth dev experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database: PostgreSQL + Redis
&lt;/h3&gt;

&lt;p&gt;PostgreSQL for persistence: JSONB for flag metadata, partial indexes, LISTEN/NOTIFY for cache invalidation. 29 tables, 67 indexes, 29 foreign keys.&lt;/p&gt;

&lt;p&gt;Redis as cache layer for flag evaluations. When an SDK asks "is flag X enabled for user Y?", Redis serves the answer in milliseconds, updated in real-time via pub/sub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rollgate's Feature Set
&lt;/h2&gt;

&lt;p&gt;Rollgate isn't a simple toggle on/off. I implemented a complete set of features covering the entire software release lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature Flags with Multiple Types
&lt;/h3&gt;

&lt;p&gt;Flags support four value types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Boolean&lt;/strong&gt; — Classic on/off. Perfect for kill switches and feature toggles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;String&lt;/strong&gt; — Returns text. Ideal for A/B testing ("variant-a", "variant-b") or dynamic messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Number&lt;/strong&gt; — Returns a numeric value. Useful for configuring limits, percentages, or algorithm parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON&lt;/strong&gt; — Returns a structured object. For complex configurations like layouts, plan-specific feature sets, or business rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Gradual Rollouts
&lt;/h3&gt;

&lt;p&gt;Percentage rollout enables a flag for a specific percentage of users. Distribution uses consistent hashing (MurmurHash3) on the user ID, so the same user always gets the same result without saving state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MurmurHash3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flagKey&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;
&lt;span class="nx"&gt;isEnabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;rolloutPercentage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Precision to 0.01%. You can go from 1% to 5% to 25% to 100% gradually, monitoring metrics at each step.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Targeting and Segments
&lt;/h3&gt;

&lt;p&gt;Targeting enables flags for specific user groups based on attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User attributes&lt;/strong&gt; — Email, plan, country, app version, any custom attribute&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operators&lt;/strong&gt; — equals, contains, startsWith, endsWith, regex, in, greaterThan, lessThan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable segments&lt;/strong&gt; — Define "Beta Users" or "Enterprise Customers" once, use in all flags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combined rules&lt;/strong&gt; — AND/OR logic across multiple conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Kill Switches
&lt;/h3&gt;

&lt;p&gt;The kill switch is the most critical production feature. When something goes wrong — a bug, a performance issue, a third-party integration down — you need to disable a feature instantly.&lt;/p&gt;

&lt;p&gt;In Rollgate, every flag has a toggle that takes effect in seconds via real-time SSE propagation. No deploy needed, no server access required, you don't even need to be a developer. A product manager can kill a feature from the dashboard on their phone.&lt;/p&gt;

&lt;p&gt;I've seen enterprise teams take 30-45 minutes for a traditional rollback (revert commit, CI, deploy, verify). With a kill switch, it's 2 seconds. During a production incident, those 30 minutes can cost thousands in lost revenue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scheduled Changes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;Scheduled changes&lt;/a&gt; let you program flag modifications for a specific date and time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coordinated launch&lt;/strong&gt; — "Enable the new feature Friday at 2 PM when marketing publishes the blog post"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary promotions&lt;/strong&gt; — "Enable the Black Friday banner from Friday to Monday"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic progressive rollout&lt;/strong&gt; — "1% Monday, 10% Wednesday, 50% Friday, 100% next Monday"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature sunset&lt;/strong&gt; — "Disable the old API on April 1st"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each scheduled change appears in the flag's timeline with pending/executed/cancelled status. A server-side cron job checks every minute for changes to apply.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instant Rollback
&lt;/h3&gt;

&lt;p&gt;Every flag modification is saved in history with timestamp, author, and complete state snapshot. Rollback restores the exact flag state at a previous point — not just the value, but also targeting rules, percentages, and scheduled changes.&lt;/p&gt;

&lt;p&gt;It's different from a simple "undo": you can go back 5 changes, or to a specific dated version. The audit log tracks who did what and when.&lt;/p&gt;

&lt;h3&gt;
  
  
  A/B Testing
&lt;/h3&gt;

&lt;p&gt;String variant flags enable native &lt;a href="https://rollgate.io/blog/ab-testing-feature-flags" rel="noopener noreferrer"&gt;A/B testing&lt;/a&gt;. Instead of simple true/false, the flag returns a variant ("control", "variant-a", "variant-b") with configurable percentage distribution.&lt;/p&gt;

&lt;p&gt;Evaluation tracking records which variant was served to each user, with timestamp and context. This allows correlating variants with business metrics in your preferred analytics tool.&lt;/p&gt;

&lt;p&gt;I deliberately didn't build an integrated statistical engine — I prefer teams use their existing analytics tools rather than creating another data silo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Environment
&lt;/h3&gt;

&lt;p&gt;Every project has separate environments: development, staging, production (and as many as you want). Flags are independent per environment — you can have a flag active in staging but off in production.&lt;/p&gt;

&lt;p&gt;Each environment has its own API keys (server and client), targeting rules, and history. This prevents the classic "oops, I modified the production flag thinking it was staging" mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audit Log
&lt;/h3&gt;

&lt;p&gt;Every platform action is recorded in an immutable audit log: who created/modified/deleted a flag, what changed (before/after diff), when (precise timestamp), from which IP and user agent.&lt;/p&gt;

&lt;p&gt;Retention varies by plan: 3 days (Free), 14 days (Starter), 90 days (Pro), 1 year (Growth). For compliance and debugging, having a complete trace is essential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Webhooks
&lt;/h3&gt;

&lt;p&gt;Webhooks notify external systems when a flag changes. Every create, update, or delete sends an HTTP POST to configured URLs with the full event payload.&lt;/p&gt;

&lt;p&gt;Use cases: notify Slack when a production flag changes, trigger a deploy, update monitoring, sync with project management tools. Webhooks have automatic retry with exponential backoff and delivery logging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analytics and Usage Tracking
&lt;/h3&gt;

&lt;p&gt;Rollgate tracks flag evaluations in real-time: how many times evaluated, unique users, true/false distribution, trends over time. Usage limits are per plan: 500K requests/month (Free), 1M (Starter), 3M (Pro), 12M (Growth).&lt;/p&gt;

&lt;h2&gt;
  
  
  13 SDKs
&lt;/h2&gt;

&lt;p&gt;I built 13 SDKs covering all major languages and frameworks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript/TypeScript&lt;/strong&gt; — sdk-core, sdk-node, sdk-browser, sdk-react, sdk-vue, sdk-angular, sdk-svelte&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile&lt;/strong&gt; — sdk-react-native, sdk-flutter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt; — sdk-go, sdk-java, sdk-python, sdk-dotnet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All SDKs share the same features: local cache, circuit breaker, retry with backoff, event buffering, and real-time SSE updates. If the server is down, SDKs continue working with cached values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RollgateProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RollgateProvider&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rg_client_your_key"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RollgateProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showNewFeature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;showNewFeature&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewDashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LegacyDashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client SDK -&amp;gt; API Server (Go) -&amp;gt; Redis Cache -&amp;gt; PostgreSQL
              ^
          SSE Connection (real-time updates)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flag evaluation happens in ~200us. P99 latency is under one millisecond. The system supports tens of thousands of simultaneous SSE connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Race Conditions on Updates
&lt;/h3&gt;

&lt;p&gt;When multiple users modify the same flag simultaneously, I use optimistic locking with a version counter. If someone else modified the flag in the meantime, the operation returns 409 Conflict.&lt;/p&gt;

&lt;h3&gt;
  
  
  Circuit Breaker in SDKs
&lt;/h3&gt;

&lt;p&gt;If the API server is down, SDKs must not crash the host app. The circuit breaker has three states (Closed, Open, Half-Open) with exponential retry and request deduplication.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO for a SaaS App
&lt;/h3&gt;

&lt;p&gt;I separated marketing and dashboard with a domain split: rollgate.io for SEO pages (Server Components) and app.rollgate.io for the authenticated dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resilience and Monitoring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily backups&lt;/strong&gt; — PostgreSQL dump every night to a geographically separate server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt; — Prometheus + Grafana + Alertmanager with real-time alerts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks&lt;/strong&gt; — Automated verification of API, Web, DB, Redis every 60 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disaster recovery&lt;/strong&gt; — Automated script rebuilds the entire stack in ~20 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK resilience&lt;/strong&gt; — Local cache + circuit breaker = works even offline&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Go files (non-test)&lt;/td&gt;
&lt;td&gt;147&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript/TSX files&lt;/td&gt;
&lt;td&gt;168&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API endpoints&lt;/td&gt;
&lt;td&gt;114&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB tables&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total tests&lt;/td&gt;
&lt;td&gt;~850&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Published SDKs&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codebase score&lt;/td&gt;
&lt;td&gt;7.86/10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Simplicity Wins
&lt;/h3&gt;

&lt;p&gt;Kubernetes in production? No, Docker Compose is enough. Microservices? No, a modular monolith is simpler. Every added complexity has a maintenance cost that must justify its weight.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tests Save Lives
&lt;/h3&gt;

&lt;p&gt;With ~850 tests, I can refactor with confidence. CI runs everything on every PR and blocks deployment if something fails.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Billing Is Harder Than the Product
&lt;/h3&gt;

&lt;p&gt;Paddle for payments was surprisingly complex: webhooks, subscription lifecycle, prorating, dunning, tax handling. Use a payment provider that handles everything (Paddle, Lemon Squeezy) rather than raw Stripe.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. SEO Requires Constant Attention
&lt;/h3&gt;

&lt;p&gt;If Google doesn't index you, nobody will find you. I spent weeks on SSR, JSON-LD, sitemaps, meta tags. It never ends.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Building Solo Is Sustainable (With Limits)
&lt;/h3&gt;

&lt;p&gt;Code is the easy part — finding users is the real challenge. Marketing, support, and growth require different skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Market: Competitors and Positioning
&lt;/h2&gt;

&lt;p&gt;The feature flags market is dominated by a few players with aggressive enterprise pricing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Pricing&lt;/th&gt;
&lt;th&gt;Strengths&lt;/th&gt;
&lt;th&gt;Limitations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LaunchDarkly&lt;/td&gt;
&lt;td&gt;From $833/mo&lt;/td&gt;
&lt;td&gt;Market leader, enterprise-ready, vast integrations&lt;/td&gt;
&lt;td&gt;Prohibitive for startups, excessive complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flagsmith&lt;/td&gt;
&lt;td&gt;From $45/mo&lt;/td&gt;
&lt;td&gt;Free self-hosted, API-first&lt;/td&gt;
&lt;td&gt;Less polished UI, fewer SDKs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unleash&lt;/td&gt;
&lt;td&gt;From $80/mo&lt;/td&gt;
&lt;td&gt;Mature self-hosted, good docs&lt;/td&gt;
&lt;td&gt;Complex setup, dated UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostHog&lt;/td&gt;
&lt;td&gt;Usage-based&lt;/td&gt;
&lt;td&gt;Complete suite (analytics + flags), open-source&lt;/td&gt;
&lt;td&gt;Flags aren't the focus, overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollgate&lt;/td&gt;
&lt;td&gt;Free -&amp;gt; €45/mo&lt;/td&gt;
&lt;td&gt;Accessible pricing, 13 SDKs, 5-min setup&lt;/td&gt;
&lt;td&gt;New to market, growing community&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Choosing the Pricing Model
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://rollgate.io/blog/feature-flags-pricing-comparison" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt; was one of the hardest decisions. I studied every competitor and identified three approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Per-seat (LaunchDarkly)&lt;/strong&gt; — Scales with team size, penalizes large companies. $70k/year for 50 developers isn't unusual.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage-based (PostHog)&lt;/strong&gt; — Scales with traffic, unpredictable for budgeting. Can explode with traffic spikes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed tiers (Rollgate)&lt;/strong&gt; — Predictable pricing, scales by features and limits. Customers know exactly what they pay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose fixed tiers because cost predictability is essential for startups and SMBs. The four plans:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Monthly&lt;/th&gt;
&lt;th&gt;Annually&lt;/th&gt;
&lt;th&gt;Requests/mo&lt;/th&gt;
&lt;th&gt;Team&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;€0&lt;/td&gt;
&lt;td&gt;€0&lt;/td&gt;
&lt;td&gt;500K&lt;/td&gt;
&lt;td&gt;3 members&lt;/td&gt;
&lt;td&gt;Side projects, MVPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;€45/mo&lt;/td&gt;
&lt;td&gt;€39/mo&lt;/td&gt;
&lt;td&gt;1M&lt;/td&gt;
&lt;td&gt;5 members&lt;/td&gt;
&lt;td&gt;Early-stage startups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;€119/mo&lt;/td&gt;
&lt;td&gt;€99/mo&lt;/td&gt;
&lt;td&gt;3M&lt;/td&gt;
&lt;td&gt;15 members&lt;/td&gt;
&lt;td&gt;Growing teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Growth&lt;/td&gt;
&lt;td&gt;€349/mo&lt;/td&gt;
&lt;td&gt;€299/mo&lt;/td&gt;
&lt;td&gt;12M&lt;/td&gt;
&lt;td&gt;50 members&lt;/td&gt;
&lt;td&gt;Scale-ups, high traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The free tier is generous by design: 500K requests/month is enough for an app with thousands of active users. The goal is to lower the entry barrier — if a developer tries Rollgate and it works, upgrading to Starter as the project grows is natural.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not Open Source?
&lt;/h2&gt;

&lt;p&gt;I evaluated the open-core model (free core, paid enterprise features), but it requires an active community to work. For a solo project, the risk is giving everything away for free without monetizing. I opted for a SaaS model with a generous free tier, with plans to release a self-hosted version under BSL (Business Source License) — the same approach used by HashiCorp and Sentry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Rollgate is live at &lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;rollgate.io&lt;/a&gt; with a generous free tier (500K requests/month). Next up: advanced A/B testing with auto-winner, teams with SSO, self-hosted version, and complete OpenAPI spec.&lt;/p&gt;

&lt;p&gt;If you're interested in the project or have questions about building a SaaS solo, I'd love to hear from you in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;Rollgate&lt;/a&gt;, a feature flag platform for developers. If you have questions about feature flags, drop them in the comments — happy to help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Best LaunchDarkly Alternative in 2026: Rollgate vs the Rest</title>
      <dc:creator>Domenico Giordano</dc:creator>
      <pubDate>Fri, 03 Apr 2026 12:55:14 +0000</pubDate>
      <link>https://forem.com/domenico_giordano_e441224/the-best-launchdarkly-alternative-in-2026-rollgate-vs-the-rest-3l02</link>
      <guid>https://forem.com/domenico_giordano_e441224/the-best-launchdarkly-alternative-in-2026-rollgate-vs-the-rest-3l02</guid>
      <description>&lt;p&gt;Let's be real: LaunchDarkly is a great product, but the pricing is wild. I was paying more for feature flags than for my entire cloud infrastructure. So I started looking at alternatives, and eventually built one. Here's an honest comparison of what's out there in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Teams Are Looking for a LaunchDarkly Alternative
&lt;/h2&gt;

&lt;p&gt;If you're searching for a LaunchDarkly alternative, you're not alone. LaunchDarkly is the category leader in feature flags, but it's also the most expensive option by a wide margin. Enterprise contracts typically range from $25,000 to $150,000 per year, and pricing scales with Monthly Active Users (MAU) — a metric that punishes success. The more users you have, the more you pay, even if your feature flag usage stays the same.&lt;/p&gt;

&lt;p&gt;For teams with 10 developers and a growing product, the math doesn't work. You're paying enterprise pricing for what is fundamentally a configuration service: a key-value store with targeting rules and an SDK.&lt;/p&gt;

&lt;p&gt;That's why more teams are evaluating alternatives to LaunchDarkly that offer the same core capabilities — &lt;a href="https://rollgate.io/blog/what-are-feature-flags" rel="noopener noreferrer"&gt;feature flags&lt;/a&gt;, targeting, rollback — without the unpredictable pricing model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Look for in a LaunchDarkly Alternative
&lt;/h2&gt;

&lt;p&gt;Not all feature flag tools are created equal. Before you switch, make sure the alternative checks these boxes:&lt;/p&gt;

&lt;h3&gt;
  
  
  Transparent, Predictable Pricing
&lt;/h3&gt;

&lt;p&gt;No "contact sales" as the only option. No MAU-based pricing that explodes when your product grows. You should know exactly what you'll pay before you sign up. For a deeper breakdown of how different vendors charge, see our &lt;a href="https://rollgate.io/blog/feature-flags-pricing-comparison" rel="noopener noreferrer"&gt;feature flags pricing comparison&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Platform SDK Support
&lt;/h3&gt;

&lt;p&gt;Your stack isn't just React. You need SDKs for your backend (Node.js, Go, Python, Java), your frontend (React, Vue, Angular, Svelte), and your mobile apps (React Native, Flutter). The SDKs should include circuit breakers, retry logic, and local caching out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scheduled Releases
&lt;/h3&gt;

&lt;p&gt;The ability to &lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;schedule a flag change&lt;/a&gt; for a specific date and time — without writing cron jobs or staying awake at 3am. This is a feature that LaunchDarkly offers only on higher tiers, and many alternatives don't offer at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instant Rollback
&lt;/h3&gt;

&lt;p&gt;When something breaks in production, you need to revert a flag to its previous state in one click. Not "create a new flag version," not "redeploy" — one click, instant rollback to the exact previous state.&lt;/p&gt;

&lt;h3&gt;
  
  
  GDPR Compliance with EU Data Residency
&lt;/h3&gt;

&lt;p&gt;If you serve European users, your feature flag data should stay in Europe. LaunchDarkly's infrastructure is primarily US-based. For teams that need GDPR compliance without complex DPAs, an EU-hosted alternative is simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  LaunchDarkly Pricing Breakdown: Why MAU Gets Expensive
&lt;/h2&gt;

&lt;p&gt;LaunchDarkly's pricing model revolves around two axes: &lt;strong&gt;seats&lt;/strong&gt; (the developers who manage flags) and &lt;strong&gt;Monthly Active Users&lt;/strong&gt; (the end users your application evaluates flags for). This sounds reasonable until you look at how MAU scales in practice.&lt;/p&gt;

&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Base plan cost&lt;/strong&gt;: LaunchDarkly's Pro plan starts around $10,000/year. Enterprise plans start around $25,000/year and go well over $100,000/year depending on contract terms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAU tiers&lt;/strong&gt;: Each plan includes a base MAU allotment. Once you exceed it, you pay per additional MAU block. The per-MAU overage cost varies by contract, but published estimates range from $0.01 to $0.03 per MAU.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAU counts every unique user&lt;/strong&gt;: Every user who triggers a flag evaluation counts, regardless of how many flags you use. If you have 100,000 active users but only 3 flags, you're still paying for 100,000 MAU.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client-side vs server-side&lt;/strong&gt;: Client-side SDKs report MAU automatically. Server-side SDKs can too, depending on how you pass user contexts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problem is that MAU correlates with product growth, not feature flag complexity. A team with 50,000 MAU and 5 flags pays far more than a team with 1,000 MAU and 200 flags — even though the second team puts more load on the system.&lt;/p&gt;

&lt;p&gt;For startups experiencing growth, this creates budget unpredictability. You might be paying $1,000/month one quarter and $4,000/month the next, simply because your product is succeeding.&lt;/p&gt;

&lt;p&gt;Cheaper alternatives to LaunchDarkly, like Rollgate, avoid this problem entirely by pricing on SDK requests — a metric you can control and predict.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flag Tools Compared: Rollgate vs LaunchDarkly vs Alternatives
&lt;/h2&gt;

&lt;p&gt;Here's a side-by-side comparison of the major feature flag platforms in 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Rollgate&lt;/th&gt;
&lt;th&gt;LaunchDarkly&lt;/th&gt;
&lt;th&gt;Flagsmith&lt;/th&gt;
&lt;th&gt;ConfigCat&lt;/th&gt;
&lt;th&gt;GrowthBook&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500K req/mo&lt;/td&gt;
&lt;td&gt;Limited trial&lt;/td&gt;
&lt;td&gt;50K req/mo&lt;/td&gt;
&lt;td&gt;10 flags&lt;/td&gt;
&lt;td&gt;Unlimited (self-hosted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Paid plans&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;From €39/mo&lt;/td&gt;
&lt;td&gt;From ~$8,333/mo (est.)&lt;/td&gt;
&lt;td&gt;From $45/mo&lt;/td&gt;
&lt;td&gt;From $84/mo&lt;/td&gt;
&lt;td&gt;From $99/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per request (flat)&lt;/td&gt;
&lt;td&gt;Per MAU + seat&lt;/td&gt;
&lt;td&gt;Per request + seat&lt;/td&gt;
&lt;td&gt;Per config fetches&lt;/td&gt;
&lt;td&gt;Per seat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SDKs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;13 official&lt;/td&gt;
&lt;td&gt;25+&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scheduled changes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All paid plans&lt;/td&gt;
&lt;td&gt;Enterprise only&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1-click rollback&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All paid plans&lt;/td&gt;
&lt;td&gt;Flag history only&lt;/td&gt;
&lt;td&gt;Audit log&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-hosted&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Coming soon&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EU data residency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (Germany)&lt;/td&gt;
&lt;td&gt;US-primary&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;td&gt;EU option&lt;/td&gt;
&lt;td&gt;Self-hosted only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A/B testing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (Pro+)&lt;/td&gt;
&lt;td&gt;Yes (add-on)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (core)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-time (SSE)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Polling only&lt;/td&gt;
&lt;td&gt;Polling only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note on competitor pricing&lt;/strong&gt;: Prices change frequently. Check each vendor's website for current pricing. The estimates above are based on publicly available information as of March 2026.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Real Cost Comparison: 10K, 50K, 100K, 500K MAU
&lt;/h2&gt;

&lt;p&gt;One of the biggest reasons teams look for a LaunchDarkly alternative is sticker shock at scale. Here's a realistic cost comparison across different growth stages, assuming a team of 10 developers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;MAU&lt;/th&gt;
&lt;th&gt;Rollgate (est.)&lt;/th&gt;
&lt;th&gt;LaunchDarkly (est.)&lt;/th&gt;
&lt;th&gt;Flagsmith (est.)&lt;/th&gt;
&lt;th&gt;ConfigCat (est.)&lt;/th&gt;
&lt;th&gt;GrowthBook (est.)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;10K&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€39/mo&lt;/td&gt;
&lt;td&gt;~$1,000/mo&lt;/td&gt;
&lt;td&gt;~$45/mo&lt;/td&gt;
&lt;td&gt;~$84/mo&lt;/td&gt;
&lt;td&gt;~$99/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;50K&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€39-99/mo&lt;/td&gt;
&lt;td&gt;~$2,500/mo&lt;/td&gt;
&lt;td&gt;~$200/mo&lt;/td&gt;
&lt;td&gt;~$200/mo&lt;/td&gt;
&lt;td&gt;~$99/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;100K&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€99-119/mo&lt;/td&gt;
&lt;td&gt;~$4,000/mo&lt;/td&gt;
&lt;td&gt;~$400/mo&lt;/td&gt;
&lt;td&gt;~$350/mo&lt;/td&gt;
&lt;td&gt;~$99/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;500K&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€299-349/mo&lt;/td&gt;
&lt;td&gt;~$10,000+/mo&lt;/td&gt;
&lt;td&gt;~$1,200/mo&lt;/td&gt;
&lt;td&gt;~$800/mo&lt;/td&gt;
&lt;td&gt;~$200/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;How to read this table&lt;/strong&gt;: Rollgate prices are based on SDK requests, not MAU, so the correlation is approximate. A typical SPA polling every 30 seconds generates ~86K requests/user/month. With caching and SSE (which Rollgate supports), actual request volume is much lower. LaunchDarkly estimates are based on published pricing and community reports — actual costs depend on your contract.&lt;/p&gt;

&lt;p&gt;The pattern is clear: at every growth tier, LaunchDarkly costs 5-30x more than alternatives. For a team at 100K MAU, the difference between Rollgate (~€99/mo) and LaunchDarkly (~$4,000/mo) is roughly &lt;strong&gt;$46,000/year&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's not a rounding error — that's a senior developer's salary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rollgate Is the LaunchDarkly Alternative Built for Growing Teams
&lt;/h2&gt;

&lt;p&gt;Rollgate was built by developers who got tired of paying five figures for a feature flag service. Here's what makes it different.&lt;/p&gt;

&lt;h3&gt;
  
  
  12 Official SDKs with Built-in Resilience
&lt;/h3&gt;

&lt;p&gt;Every Rollgate SDK ships with circuit breakers, retry with exponential backoff, local caching, and graceful degradation. If the Rollgate API goes down, your flags keep working with cached values.&lt;/p&gt;

&lt;p&gt;Here's a React example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RollgateProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RollgateProvider&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rg_client_your_key"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RollgateProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showNewDashboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;showNewDashboard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewDashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LegacyDashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And on the backend with Node.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RollgateClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RollgateClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ROLLGATE_SERVER_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;enableSSE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// real-time updates&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/pricing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPricing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-pricing-model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPricing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateNewPricing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateLegacyPricing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scheduled Changes as a First-Class Feature
&lt;/h3&gt;

&lt;p&gt;Unlike LaunchDarkly where scheduling is buried in enterprise plans, Rollgate makes &lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;scheduled changes&lt;/a&gt; available on every paid plan. Set &lt;code&gt;enable_at&lt;/code&gt; and &lt;code&gt;disable_at&lt;/code&gt; directly from the dashboard or API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Schedule a flag to enable at midnight UTC on launch day&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.rollgate.io/api/v1/projects/:id/flags/:flagId/schedule &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ROLLGATE_SERVER_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"enable_at": "2026-04-01T00:00:00Z"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also schedule a maintenance window — enable at midnight, disable at 6am — all from the dashboard without writing any code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradual Rollouts Without Complexity
&lt;/h3&gt;

&lt;p&gt;Rollgate supports &lt;a href="https://rollgate.io/blog/gradual-rollouts-guide" rel="noopener noreferrer"&gt;percentage-based gradual rollouts&lt;/a&gt; on every plan. Roll a feature out to 5% of users, monitor your metrics, then ramp to 25%, 50%, and 100%. If something goes wrong at any stage, roll back instantly to the previous percentage.&lt;/p&gt;

&lt;p&gt;LaunchDarkly supports this too, but it's part of their premium pricing. With Rollgate, gradual rollouts are available starting from the free tier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flat, Predictable Pricing
&lt;/h3&gt;

&lt;p&gt;Rollgate pricing is based on SDK requests, not MAU. You know exactly what you'll pay:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Monthly&lt;/th&gt;
&lt;th&gt;SDK Requests&lt;/th&gt;
&lt;th&gt;Projects&lt;/th&gt;
&lt;th&gt;Team Members&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;€0&lt;/td&gt;
&lt;td&gt;500K/mo&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;€39-45/mo&lt;/td&gt;
&lt;td&gt;1M/mo&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;€99-119/mo&lt;/td&gt;
&lt;td&gt;3M/mo&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Growth&lt;/td&gt;
&lt;td&gt;€299-349/mo&lt;/td&gt;
&lt;td&gt;12M/mo&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A team polling every 30 seconds generates about 86K SDK requests per month per client. Even at scale, Rollgate costs a fraction of LaunchDarkly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What LaunchDarkly Does Better
&lt;/h2&gt;

&lt;p&gt;Let's be honest — LaunchDarkly is the market leader for a reason. If you're evaluating alternatives, you should know where LaunchDarkly genuinely excels:&lt;/p&gt;

&lt;h3&gt;
  
  
  Mature Ecosystem and Integrations
&lt;/h3&gt;

&lt;p&gt;LaunchDarkly has 25+ official SDKs covering virtually every language and framework. They also have deep integrations with tools like Jira, Slack, Datadog, Terraform, and dozens more. If you need a Haskell SDK or a Terraform provider on day one, LaunchDarkly has it.&lt;/p&gt;

&lt;p&gt;Rollgate covers the 12 most-used platforms, which handles 95%+ of teams. But if your stack includes niche languages, verify SDK availability first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enterprise Features
&lt;/h3&gt;

&lt;p&gt;LaunchDarkly offers features built for large enterprise organizations: approval workflows, custom roles with granular permissions, audit log exports, SCIM provisioning, and SSO with every major identity provider. If you have a 200-person engineering org with strict compliance requirements, these features matter.&lt;/p&gt;

&lt;p&gt;Rollgate covers team management, role-based access, and audit logging — enough for most teams — but doesn't yet match LaunchDarkly's enterprise governance depth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relay Proxy
&lt;/h3&gt;

&lt;p&gt;LaunchDarkly's Relay Proxy lets you run a local proxy that caches flag data, reducing latency and providing an extra layer of resilience. This is particularly valuable in high-traffic environments or architectures with strict network policies.&lt;/p&gt;

&lt;p&gt;Rollgate's SDKs handle resilience at the SDK level (circuit breakers, local cache, SSE streaming), but a dedicated relay proxy is not yet available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Statistical Experimentation
&lt;/h3&gt;

&lt;p&gt;LaunchDarkly's experimentation add-on includes statistical significance calculations, metric analysis, and guardrail metrics. If you're running high-stakes A/B tests where statistical rigor matters, LaunchDarkly's experimentation is more mature.&lt;/p&gt;

&lt;p&gt;Rollgate offers A/B testing on Pro plans and above, but the statistical analysis tooling is still evolving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line&lt;/strong&gt;: If you're a Fortune 500 company with an unlimited budget and need every possible integration, LaunchDarkly is a safe choice. For everyone else, the question is whether those extras justify 10-30x the cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration from LaunchDarkly to Rollgate
&lt;/h2&gt;

&lt;p&gt;Switching from LaunchDarkly doesn't have to be painful. Here's a practical migration path:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Export Your Flags
&lt;/h3&gt;

&lt;p&gt;Audit your current LaunchDarkly flags. Most teams discover that 30-50% of their flags are stale (old kill switches, completed rollouts, abandoned experiments). Migration is a good time to clean house.&lt;/p&gt;

&lt;p&gt;For each active flag, note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flag key and type (boolean, string, multivariate)&lt;/li&gt;
&lt;li&gt;Targeting rules and segments&lt;/li&gt;
&lt;li&gt;Default values (on/off)&lt;/li&gt;
&lt;li&gt;Which environments use it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Create Flags in Rollgate
&lt;/h3&gt;

&lt;p&gt;Recreate your active flags in the Rollgate dashboard. Rollgate supports the same flag types: boolean, string, number, and JSON. Targeting rules map directly — user attributes, segments, and percentage rollouts all work the same way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Swap the SDK
&lt;/h3&gt;

&lt;p&gt;This is the core change. Here's how LaunchDarkly SDKs map to Rollgate equivalents:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;LaunchDarkly SDK&lt;/th&gt;
&lt;th&gt;Rollgate SDK&lt;/th&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;launchdarkly-js-client-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@rollgate/sdk-browser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Browser/SPA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;launchdarkly-react-client-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@rollgate/sdk-react&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@launchdarkly/node-server-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@rollgate/sdk-node&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Node.js server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;launchdarkly-vue-client-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@rollgate/sdk-vue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Vue 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gopkg.in/launchdarkly/go-server-sdk.v5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;github.com/rollgate/sdk-go&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Go server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;com.launchdarkly:launchdarkly-java-server-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;io.rollgate:sdk-java&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Java server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;launchdarkly-server-sdk&lt;/code&gt; (Python)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rollgate-sdk-python&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Python server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;launchdarkly_flutter_client_sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rollgate_sdk_flutter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Flutter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;launchdarkly-react-native-client-sdk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@rollgate/sdk-react-native&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;React Native&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 4: Update Flag Evaluation Calls
&lt;/h3&gt;

&lt;p&gt;The API surface is intentionally similar. Here's a typical before/after:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LaunchDarkly (React):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFlags&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;launchdarkly-react-client-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;newCheckout&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlags&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newCheckout&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewCheckout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OldCheckout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rollgate (React):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newCheckout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-checkout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newCheckout&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewCheckout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OldCheckout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main differences: Rollgate uses &lt;code&gt;useFlag('key', defaultValue)&lt;/code&gt; instead of destructuring from &lt;code&gt;useFlags()&lt;/code&gt;. This makes default values explicit and avoids issues with undefined flags.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Run Both in Parallel (Optional)
&lt;/h3&gt;

&lt;p&gt;For critical flags, you can run both LaunchDarkly and Rollgate simultaneously during a transition period. Evaluate flags from both services and log any discrepancies. Once you're confident the values match, remove the LaunchDarkly SDK.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Clean Up
&lt;/h3&gt;

&lt;p&gt;Remove LaunchDarkly SDK packages, delete environment variables, and update your CI/CD pipeline. Cancel your LaunchDarkly contract (check your billing cycle — many contracts auto-renew).&lt;/p&gt;

&lt;p&gt;Most teams complete the migration in &lt;strong&gt;1-3 days&lt;/strong&gt; for small projects and &lt;strong&gt;1-2 weeks&lt;/strong&gt; for larger codebases with multiple services.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Choose Each Alternative
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Choose Rollgate if:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You want flat, predictable pricing without MAU penalties&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;Scheduled releases&lt;/a&gt; and instant rollback are core requirements&lt;/li&gt;
&lt;li&gt;You need GDPR compliance with EU-hosted infrastructure (Germany)&lt;/li&gt;
&lt;li&gt;You're a startup or mid-size team (5-50 developers) shipping fast&lt;/li&gt;
&lt;li&gt;You want resilient SDKs with circuit breakers and local caching out of the box&lt;/li&gt;
&lt;li&gt;You care about &lt;a href="https://rollgate.io/blog/gradual-rollouts-guide" rel="noopener noreferrer"&gt;gradual rollouts&lt;/a&gt; as part of your release process&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choose LaunchDarkly if:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're an enterprise with budget for $25K+/year and need maximum integrations&lt;/li&gt;
&lt;li&gt;You need 25+ SDKs including niche languages (Haskell, Erlang, Lua, etc.)&lt;/li&gt;
&lt;li&gt;You need built-in experimentation with statistical significance&lt;/li&gt;
&lt;li&gt;You require enterprise governance: approval workflows, SCIM, custom roles&lt;/li&gt;
&lt;li&gt;You need the Relay Proxy for latency-sensitive, high-traffic architectures&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choose Flagsmith if:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need to self-host today and want an open-source option (MIT license)&lt;/li&gt;
&lt;li&gt;You want remote config in addition to feature flags&lt;/li&gt;
&lt;li&gt;You need an open API and want full control over your flag infrastructure&lt;/li&gt;
&lt;li&gt;You're comfortable managing your own infrastructure and upgrades&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choose ConfigCat if:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You have a small team with very few flags and simple targeting needs&lt;/li&gt;
&lt;li&gt;You primarily need simple boolean toggles without scheduling or rollback&lt;/li&gt;
&lt;li&gt;You want a no-frills tool that does the basics well at a reasonable price&lt;/li&gt;
&lt;li&gt;Polling-based updates (no real-time SSE) are acceptable for your use case&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choose GrowthBook if:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A/B testing and experimentation are your primary use case, not feature management&lt;/li&gt;
&lt;li&gt;You want to self-host and connect your own data warehouse (BigQuery, Snowflake, etc.)&lt;/li&gt;
&lt;li&gt;You need Bayesian statistical analysis built into the platform&lt;/li&gt;
&lt;li&gt;Feature flags are secondary to your experimentation workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Rollgate production-ready?
&lt;/h3&gt;

&lt;p&gt;Yes. Rollgate has been running in production since 2025. The platform handles millions of SDK requests, is hosted on EU infrastructure (Hetzner, Germany), and has built-in resilience at every layer — from the API (health checks, graceful degradation) to the SDKs (circuit breakers, retry logic, local caching). You can &lt;a href="https://demo.rollgate.io" rel="noopener noreferrer"&gt;try the live demo&lt;/a&gt; to see the dashboard and evaluate flags in real time.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long does migration from LaunchDarkly take?
&lt;/h3&gt;

&lt;p&gt;For most teams, &lt;strong&gt;1-3 days&lt;/strong&gt; for a small project (one service, a few flags) and &lt;strong&gt;1-2 weeks&lt;/strong&gt; for larger codebases with multiple services and environments. The SDK APIs are intentionally similar, so the code changes are mostly find-and-replace. The longest part is usually auditing and cleaning up stale flags, which you should do anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Rollgate support Server-Side Rendering (SSR)?
&lt;/h3&gt;

&lt;p&gt;Yes. The &lt;code&gt;@rollgate/sdk-node&lt;/code&gt; package supports server-side flag evaluation, which integrates with Next.js, Nuxt, SvelteKit, and any other SSR framework. You can evaluate flags on the server and pass them to the client as initial props, avoiding layout shifts and flicker. The Node SDK supports SSE for real-time updates, so flag changes propagate without redeployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Rollgate pricing compare to LaunchDarkly for a growing startup?
&lt;/h3&gt;

&lt;p&gt;A startup with 50,000 MAU would pay approximately $2,500/month with LaunchDarkly. With Rollgate, the same team would pay €39-99/month depending on SDK request volume. That's a difference of roughly $28,000/year. See the &lt;a href="https://rollgate.io/blog/feature-flags-pricing-comparison" rel="noopener noreferrer"&gt;full pricing comparison&lt;/a&gt; for details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use Rollgate with my existing analytics stack?
&lt;/h3&gt;

&lt;p&gt;Yes. Rollgate's SDKs emit events that you can forward to your existing analytics tools (Segment, Mixpanel, PostHog, etc.). Flag evaluations include context about which variant was served, making it easy to correlate feature flags with product metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;Rollgate's free tier includes 500K requests per month, 3 projects, all 13 SDKs, and unlimited flags. No credit card required.&lt;/p&gt;

&lt;p&gt;If you're evaluating a LaunchDarkly alternative, &lt;a href="https://app.rollgate.io/register" rel="noopener noreferrer"&gt;create a free account&lt;/a&gt; or &lt;a href="https://demo.rollgate.io" rel="noopener noreferrer"&gt;try the live demo&lt;/a&gt; to see it in action.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;Rollgate&lt;/a&gt;, a feature flag platform for developers. If you have questions about feature flags, drop them in the comments — happy to help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What Are Feature Flags? A Complete Guide for 2026</title>
      <dc:creator>Domenico Giordano</dc:creator>
      <pubDate>Fri, 03 Apr 2026 12:55:13 +0000</pubDate>
      <link>https://forem.com/domenico_giordano_e441224/what-are-feature-flags-a-complete-guide-for-2026-4ck1</link>
      <guid>https://forem.com/domenico_giordano_e441224/what-are-feature-flags-a-complete-guide-for-2026-4ck1</guid>
      <description>&lt;p&gt;I've been using feature flags for years, and I'm still surprised how many teams ship code without them. Whether you're a solo dev or on a 50-person team, feature flags change how you think about deployments. This is the guide I wish I had when I started — practical, with real code examples in 5 languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Feature Flags?
&lt;/h2&gt;

&lt;p&gt;Feature flags (also called feature toggles or feature switches) are a software development technique that lets you enable or disable functionality in your application without deploying new code. Instead of shipping a feature directly to all users, you wrap it behind a conditional check that can be toggled on or off remotely.&lt;/p&gt;

&lt;p&gt;At its simplest, a feature flag looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;featureFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-checkout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showNewCheckout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showOldCheckout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key difference from a regular &lt;code&gt;if&lt;/code&gt; statement is that the flag's value is controlled externally — through a dashboard, API, or configuration service — not hardcoded in your source code. This separation of deployment from release is what makes feature flags so powerful for modern engineering teams.&lt;/p&gt;

&lt;p&gt;Feature flags have become a core practice at companies like Netflix, GitHub, Google, and Spotify. They're not just a convenience — they're infrastructure that enables continuous delivery, experimentation, and operational safety at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flags vs Feature Toggles vs Feature Switches
&lt;/h2&gt;

&lt;p&gt;If you've been researching this topic, you've probably seen all three terms used interchangeably. Here's the short answer: &lt;strong&gt;they're the same thing&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feature flag&lt;/strong&gt; is the most widely used term, especially in North America and in the context of SaaS platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature toggle&lt;/strong&gt; was popularized by Martin Fowler's influential &lt;a href="https://martinfowler.com/articles/feature-toggles.html" rel="noopener noreferrer"&gt;article on feature toggles&lt;/a&gt; and is common in European engineering circles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature switch&lt;/strong&gt; is less common but still used, particularly in mobile development and gaming.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some teams draw subtle distinctions — for example, using "toggle" for simple on/off switches and "flag" for flags with targeting rules and percentage rollouts — but in practice, the industry treats them as synonyms. Throughout this guide, we'll use "feature flag" as the primary term.&lt;/p&gt;

&lt;p&gt;What matters is not the name but the capability: decoupling code deployment from feature release so you can control what users see without redeploying your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Feature Flags?
&lt;/h2&gt;

&lt;p&gt;Feature flags solve several problems that every growing engineering team faces:&lt;/p&gt;

&lt;h3&gt;
  
  
  Ship Faster, Break Less
&lt;/h3&gt;

&lt;p&gt;Without feature flags, deploying code means releasing it to everyone. This creates pressure to batch changes into large releases, which are riskier and harder to debug. Feature flags decouple &lt;strong&gt;deployment&lt;/strong&gt; from &lt;strong&gt;release&lt;/strong&gt;. You can merge code to main, deploy it to production, and only enable it when you're ready.&lt;/p&gt;

&lt;p&gt;This is the foundation of trunk-based development — a practice where all developers commit to a single branch and use feature flags to hide work-in-progress. No more long-lived feature branches, no more merge conflicts, no more "integration hell." If you're curious about how this compares to branching strategies, check out our guide on &lt;a href="https://rollgate.io/blog/feature-flags-vs-feature-branches" rel="noopener noreferrer"&gt;feature flags vs feature branches&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradual Rollouts
&lt;/h3&gt;

&lt;p&gt;Instead of flipping a switch for 100% of users, you can roll out a feature to 1%, then 5%, then 25%, then 100%. If something goes wrong at 5%, you turn it off — no rollback, no hotfix, no downtime.&lt;/p&gt;

&lt;p&gt;Gradual rollouts give you confidence. You can observe real-world behavior with a small audience before committing to a full release. For a deep dive on implementation strategies, see our &lt;a href="https://rollgate.io/blog/gradual-rollouts-guide" rel="noopener noreferrer"&gt;gradual rollouts guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kill Switches
&lt;/h3&gt;

&lt;p&gt;Production incidents happen. A feature flag gives you an instant kill switch. Instead of reverting a commit, waiting for CI, and redeploying, you toggle a flag and the problematic feature is disabled in seconds.&lt;/p&gt;

&lt;p&gt;The difference between a 30-second recovery and a 30-minute recovery is enormous — both for user experience and for your on-call team's stress levels.&lt;/p&gt;

&lt;h3&gt;
  
  
  A/B Testing
&lt;/h3&gt;

&lt;p&gt;Feature flags are the foundation of experimentation. Show variant A to 50% of users and variant B to the other 50%, then measure which performs better. This is how companies like Netflix, Uber, and Spotify make data-driven product decisions.&lt;/p&gt;

&lt;p&gt;With multivariate flags, you can test more than two variants simultaneously — different copy, layouts, pricing displays, or algorithms — and let data guide your decisions. Learn more about combining &lt;a href="https://rollgate.io/blog/ab-testing-feature-flags" rel="noopener noreferrer"&gt;A/B testing with feature flags&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Targeting
&lt;/h3&gt;

&lt;p&gt;Want to enable a feature only for beta testers? Or only for users on the Pro plan? Feature flags with targeting rules let you control exactly who sees what, based on user attributes like email, plan, country, or custom properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scheduled Releases
&lt;/h3&gt;

&lt;p&gt;Some features need to go live at a specific time — a marketing campaign, a product launch, or a compliance deadline. Feature flags with scheduling let you set the exact moment a feature activates without anyone staying up at midnight to press a button. We cover this in detail in our &lt;a href="https://rollgate.io/blog/feature-flags-scheduled-releases" rel="noopener noreferrer"&gt;scheduled releases guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Feature Flags
&lt;/h2&gt;

&lt;p&gt;Not all feature flags are the same. Understanding the different types helps you use them effectively:&lt;/p&gt;

&lt;h3&gt;
  
  
  Release Flags
&lt;/h3&gt;

&lt;p&gt;The most common type. Used to hide incomplete features in production. Short-lived — removed once the feature is fully launched. These flags enable trunk-based development by letting you merge partially complete work without exposing it to users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ops Flags
&lt;/h3&gt;

&lt;p&gt;Used for operational control. Kill switches, circuit breakers, and maintenance modes. These tend to be long-lived and are critical for system reliability. Examples include disabling a non-essential service during peak load or switching to a fallback provider when a third-party API is down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Experiment Flags
&lt;/h3&gt;

&lt;p&gt;Used for A/B tests and multivariate experiments. They assign users to variants and track metrics. Removed after the experiment concludes and a winner is chosen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permission Flags
&lt;/h3&gt;

&lt;p&gt;Control access to features based on user attributes — plan tier, role, geography. Often long-lived, acting as a dynamic permission system. For example, showing advanced analytics only to Pro plan users, or enabling GDPR-specific data handling for EU users.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Feature Flags Work: Architecture Deep Dive
&lt;/h2&gt;

&lt;p&gt;Understanding the architecture behind feature flags helps you make better decisions about implementation. Here's how a typical feature flag system works end to end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│  Dashboard   │────&amp;gt;│  Flag Service    │────&amp;gt;│  Database   │
│  (Web UI)    │     │  (API Server)    │     │  (Postgres) │
└─────────────┘     └──────────────────┘     └─────────────┘
                           │
                    ┌──────┴──────┐
                    │             │
               SSE/Polling    REST API
                    │             │
              ┌─────v─────┐ ┌────v──────┐
              │ Client SDK │ │ Server SDK│
              │ (Browser)  │ │ (Node/Go) │
              └─────┬─────┘ └────┬──────┘
                    │             │
              ┌─────v─────┐ ┌────v──────┐
              │ Your App   │ │ Your API  │
              │ (Frontend) │ │ (Backend) │
              └───────────┘ └───────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Flag Service
&lt;/h3&gt;

&lt;p&gt;At the center is the flag service — the API that stores flag definitions, targeting rules, and percentage allocations. This is where the logic lives: "Enable &lt;code&gt;new-pricing&lt;/code&gt; for 20% of users in the US who are on the Pro plan." The service evaluates rules and returns flag states for a given user context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-Side vs Server-Side Evaluation
&lt;/h3&gt;

&lt;p&gt;There are two fundamental approaches to flag evaluation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server-side evaluation&lt;/strong&gt; — Your backend SDK sends the user context to the flag service (or evaluates locally with a cached ruleset) and returns the computed flag values. This is more secure because targeting rules and flag logic never leave your server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client-side evaluation&lt;/strong&gt; — The browser SDK receives the evaluated flag values from the flag service (not the raw rules). The client knows what's enabled for the current user but doesn't see other users' configurations or your targeting logic.&lt;/p&gt;

&lt;p&gt;Most production setups use both: server-side SDKs for backend logic and API responses, and client-side SDKs for UI rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Polling vs Streaming
&lt;/h3&gt;

&lt;p&gt;How does your SDK know when a flag changes?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Polling&lt;/strong&gt; — The SDK periodically checks the flag service for updates (e.g., every 30 seconds). Simple to implement, but introduces latency. If you toggle a flag, it might take up to 30 seconds to propagate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streaming (SSE/WebSocket)&lt;/strong&gt; — The flag service pushes updates to connected SDKs in real-time via Server-Sent Events or WebSockets. Changes propagate in milliseconds. More complex to operate, but critical for kill switches where seconds matter.&lt;/p&gt;

&lt;p&gt;Most feature flag platforms support both, letting you choose based on your latency requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  The SDK Pattern
&lt;/h3&gt;

&lt;p&gt;Modern feature flag SDKs follow a consistent pattern regardless of language:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Initialize&lt;/strong&gt; with a client key and optional user context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache&lt;/strong&gt; flag values locally (in memory, localStorage, or disk)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluate&lt;/strong&gt; flags synchronously from the local cache&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sync&lt;/strong&gt; with the flag service in the background (polling or streaming)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emit events&lt;/strong&gt; for analytics and experimentation tracking&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means flag evaluation is fast (local cache lookup) and resilient (works even if the flag service is temporarily unavailable).&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flags in Different Languages
&lt;/h2&gt;

&lt;p&gt;Feature flags work across any language and framework. Here's what the integration looks like in practice:&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript / React
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PricingPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showNewPricing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-pricing-page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;showNewPricing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewPricingLayout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrentPricingLayout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RollgateClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollgate/sdk-node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RollgateClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ROLLGATE_SERVER_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/recommendations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useNewAlgorithm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-recommendations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useNewAlgorithm&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;newRecommendationEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;currentRecommendationEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rollgate&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RollgateClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RollgateClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ROLLGATE_SERVER_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;user_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;userId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;attributes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_enabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;new-search-engine&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;new_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;legacy_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/rollgate/sdk-go"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rollgate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserContext&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;UserID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-User-ID"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;&lt;span class="s"&gt;"plan"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pro"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new-dashboard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;serveNewDashboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;serveCurrentDashboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.rollgate.sdk.RollgateClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.rollgate.sdk.UserContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;RollgateClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RollgateClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ROLLGATE_SERVER_KEY"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;UserContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UserContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"plan"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPlan&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEnabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new-payment-flow"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;processWithNewFlow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;processWithCurrentFlow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern is the same everywhere: initialize a client, pass user context, and evaluate a flag. The SDK handles caching, syncing, and resilience under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flag Use Cases
&lt;/h2&gt;

&lt;p&gt;Feature flags are versatile. Here are the most common real-world scenarios where teams use them:&lt;/p&gt;

&lt;h3&gt;
  
  
  Dark Launches
&lt;/h3&gt;

&lt;p&gt;Deploy a feature to production without any user seeing it. The code is live, but the flag is off. This lets you verify that deployment works — database migrations ran, services connect, no errors in logs — before any user is exposed to the change. When you're confident, you flip the flag for a small group.&lt;/p&gt;

&lt;p&gt;Dark launches are especially valuable for major infrastructure changes. You can deploy a new payment provider integration, test it with internal transactions, and gradually shift real traffic without any public announcement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beta Programs and Early Access
&lt;/h3&gt;

&lt;p&gt;Create a segment of beta users who opt in to see new features before general availability. This gives you real feedback from motivated users without the risk of a full release. Flag targeting rules make this trivial: target users where &lt;code&gt;beta_program = true&lt;/code&gt; or where the email ends with &lt;code&gt;@yourcompany.com&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trunk-Based Development
&lt;/h3&gt;

&lt;p&gt;In trunk-based development, all developers commit to &lt;code&gt;main&lt;/code&gt; (or a single trunk branch). Feature flags hide incomplete work so it can be merged without breaking the application. This eliminates long-lived feature branches, reduces merge conflicts, and keeps the codebase in a continuously deployable state.&lt;/p&gt;

&lt;p&gt;The workflow: create a flag, wrap your work-in-progress code behind it, merge to main, deploy. The flag stays off until the feature is complete and tested. Read more about &lt;a href="https://rollgate.io/blog/feature-flags-vs-feature-branches" rel="noopener noreferrer"&gt;feature flags vs feature branches&lt;/a&gt; and why many teams are making this switch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Canary Releases
&lt;/h3&gt;

&lt;p&gt;A canary release routes a small percentage of traffic to the new version while the majority stays on the current version. If the canary shows elevated error rates or latency, you pull it back. Feature flags enable canary releases at the application level — no need for infrastructure-level traffic splitting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operational Kill Switches
&lt;/h3&gt;

&lt;p&gt;Every external dependency in your system should have a kill switch. If your recommendation engine depends on a third-party ML service, wrap it in a flag. When that service has an outage, disable the flag and fall back to a simpler algorithm. Your users see slightly less personalized results instead of an error page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entitlement Management
&lt;/h3&gt;

&lt;p&gt;Use feature flags as a dynamic permission layer. Free users see the basic editor; Pro users see the advanced editor with collaboration features; Enterprise users see admin controls and audit logs. When a user upgrades their plan, their flag evaluations update in real time — no code change needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compliance and Regional Features
&lt;/h3&gt;

&lt;p&gt;Some features are only legal in certain regions, or need to comply with specific regulations. Feature flags targeting by geography let you enable GDPR consent flows for EU users, disable certain data collection in California for CCPA compliance, or roll out features region by region to meet local requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flag Lifecycle
&lt;/h2&gt;

&lt;p&gt;Every feature flag should follow a defined lifecycle. Flags that linger without clear ownership become technical debt. Here's the lifecycle that high-performing teams follow:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Planning
&lt;/h3&gt;

&lt;p&gt;Before creating a flag, define its purpose, type, and expected lifetime. A release flag for a new checkout flow might have a two-week lifespan. An ops flag for a circuit breaker might be permanent. Document this upfront.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Creation
&lt;/h3&gt;

&lt;p&gt;Create the flag in your dashboard with a descriptive name, a description of its purpose, and an owner. Use a consistent naming convention across your team — &lt;code&gt;feature.checkout-v2&lt;/code&gt;, &lt;code&gt;ops.disable-recommendations&lt;/code&gt;, &lt;code&gt;experiment.pricing-page-layout&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Implementation
&lt;/h3&gt;

&lt;p&gt;Wrap the relevant code paths with the flag check. Keep the flag's scope as narrow as possible — one flag should control one feature, not five. Test both the on and off states.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Rollout
&lt;/h3&gt;

&lt;p&gt;Enable the flag progressively. Internal users first, then beta testers, then 5% of production traffic, then wider. Monitor error rates, latency, and business metrics at each stage. Our &lt;a href="https://rollgate.io/blog/gradual-rollouts-guide" rel="noopener noreferrer"&gt;gradual rollouts guide&lt;/a&gt; covers specific strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Full Release
&lt;/h3&gt;

&lt;p&gt;Once you're confident, enable the flag for 100% of users. But you're not done yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Cleanup
&lt;/h3&gt;

&lt;p&gt;This is the step most teams skip — and it's the most important for long-term codebase health. Once a flag has been at 100% for a defined period (one to two weeks is common), remove it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete the flag evaluation from your code&lt;/li&gt;
&lt;li&gt;Remove the &lt;code&gt;else&lt;/code&gt; branch (the old code path)&lt;/li&gt;
&lt;li&gt;Delete the flag from your dashboard&lt;/li&gt;
&lt;li&gt;Update any tests that referenced the flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set a calendar reminder or use your flag service's stale flag detection to ensure cleanup happens. A codebase with 500 stale flags is a codebase no one wants to touch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Feature Flag Mistakes
&lt;/h2&gt;

&lt;p&gt;Feature flags are powerful, but misuse leads to real problems. Here are the mistakes we see most often:&lt;/p&gt;

&lt;h3&gt;
  
  
  Never Cleaning Up Flags
&lt;/h3&gt;

&lt;p&gt;The most common mistake by far. Teams add flags but never remove them. Six months later, no one knows if &lt;code&gt;temp-fix-checkout-2024&lt;/code&gt; is still needed. The code has two paths, both partially tested, and removing either feels risky. Prevent this by assigning an owner and an expiry date to every flag at creation time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flag Sprawl
&lt;/h3&gt;

&lt;p&gt;Creating too many flags without governance leads to combinatorial complexity. If you have 20 flags, there are potentially over a million unique combinations of flag states. Testing all of them is impossible. Keep your active flag count manageable and archive flags aggressively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Only the Happy Path
&lt;/h3&gt;

&lt;p&gt;If your code has a feature flag, it has two code paths. Many teams only test the new path (flag on) and neglect the old path (flag off). When the flag is toggled off in an emergency, the fallback is broken because no one tested it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nesting Flags
&lt;/h3&gt;

&lt;p&gt;Avoid situations where one flag's behavior depends on another flag's state. &lt;code&gt;if (flagA &amp;amp;&amp;amp; flagB)&lt;/code&gt; quickly becomes &lt;code&gt;if (flagA &amp;amp;&amp;amp; flagB &amp;amp;&amp;amp; !flagC)&lt;/code&gt;, and suddenly your application behavior is impossible to reason about. If you find yourself nesting flags, it's a sign your flag design needs simplification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Flags for Permanent Configuration
&lt;/h3&gt;

&lt;p&gt;Feature flags are for temporary conditions. If something will never be removed — like a config value for page size or a timeout duration — use application configuration, not a feature flag. Conflating the two leads to a flag system bloated with pseudo-config values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Monitoring Flag Impact
&lt;/h3&gt;

&lt;p&gt;Toggling a flag without monitoring is flying blind. Always have dashboards or alerts that correlate flag state changes with key metrics (error rate, latency, conversion). If you enable a flag and errors spike, you need to know immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flag Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keep Flags Short-Lived
&lt;/h3&gt;

&lt;p&gt;Every feature flag is technical debt. Once a feature is fully rolled out, remove the flag and the conditional code. Stale flags clutter your codebase and confuse new team members.&lt;/p&gt;

&lt;h3&gt;
  
  
  Name Flags Descriptively
&lt;/h3&gt;

&lt;p&gt;Use clear, consistent naming. &lt;code&gt;enable-new-checkout-flow&lt;/code&gt; is better than &lt;code&gt;flag-42&lt;/code&gt; or &lt;code&gt;test&lt;/code&gt;. Include the feature area and purpose in the name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a Feature Flag Service
&lt;/h3&gt;

&lt;p&gt;Managing flags through config files or environment variables works for a handful of flags but doesn't scale. A dedicated service gives you a dashboard, audit logs, targeting rules, and real-time updates without redeployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Both Paths
&lt;/h3&gt;

&lt;p&gt;If your code has a feature flag, you have two code paths. Test both. Ensure the application works correctly whether the flag is on or off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitor Flag Usage
&lt;/h3&gt;

&lt;p&gt;Track how many users are seeing each variant. Monitor error rates and performance metrics per flag state. This helps you catch issues early during rollouts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Ownership and Expiry
&lt;/h3&gt;

&lt;p&gt;Every flag should have an owner (a person or team) and an expected removal date. Review stale flags weekly. If a flag has been at 100% for more than two weeks and no one can explain why it's still there, it's time to clean it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Flag Tools: The Landscape
&lt;/h2&gt;

&lt;p&gt;There are several feature flag platforms available, ranging from open-source to enterprise SaaS. Here's a brief overview to help you evaluate:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LaunchDarkly&lt;/strong&gt; — The established market leader with enterprise features, strong SDKs, and a mature platform. Well-suited for large organizations. Pricing starts high and scales with seat count and monthly active users (MAUs), which can get expensive quickly. See our &lt;a href="https://rollgate.io/blog/launchdarkly-alternative" rel="noopener noreferrer"&gt;LaunchDarkly alternative comparison&lt;/a&gt; for a detailed breakdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flagsmith&lt;/strong&gt; — Open-source with a hosted option. Good flexibility, supports self-hosting. The interface can feel complex for smaller teams, and some advanced features require the enterprise tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ConfigCat&lt;/strong&gt; — Simple and affordable. Good for teams that want basic flag management without the complexity of a full experimentation platform. Limited targeting and analytics compared to other options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GrowthBook&lt;/strong&gt; — Open-source, strong focus on A/B testing and experimentation. Great if experiments are your primary use case. The feature flagging capabilities are secondary to the experimentation engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rollgate&lt;/strong&gt; — Built for teams that want a fast, developer-focused flag platform without enterprise pricing. First-party analytics, multi-environment support, and SDKs for all major languages and frameworks. Transparent pricing with a generous free tier. For a detailed pricing comparison across platforms, see our &lt;a href="https://rollgate.io/blog/feature-flags-pricing-comparison" rel="noopener noreferrer"&gt;feature flags pricing comparison&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The right tool depends on your team size, budget, and requirements. What matters most is that you use &lt;em&gt;something&lt;/em&gt; — even a simple implementation is better than no feature flags at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Feature Flags
&lt;/h2&gt;

&lt;p&gt;If you're new to feature flags, start simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick a feature flag service&lt;/strong&gt; — Choose one that fits your stack and budget. You can &lt;a href="https://app.rollgate.io/register" rel="noopener noreferrer"&gt;try Rollgate for free&lt;/a&gt; or explore the &lt;a href="https://demo.rollgate.io" rel="noopener noreferrer"&gt;live demo&lt;/a&gt; to see how it works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install the SDK&lt;/strong&gt; for your tech stack — most platforms have SDKs for JavaScript, React, Node.js, Python, Go, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create your first flag&lt;/strong&gt; and wrap a small, low-risk feature — maybe a UI change or a new notification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practice the cycle&lt;/strong&gt;: create flag, deploy code, enable for internal users, monitor, full rollout, clean up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Establish team conventions&lt;/strong&gt; — naming patterns, ownership rules, and cleanup cadence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The learning curve is gentle. Most teams have their first flag in production within an hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Feature flags are more than just &lt;code&gt;if/else&lt;/code&gt; statements. They're a deployment strategy, a safety net, and an experimentation platform rolled into one. Whether you're a solo developer or part of a large engineering team, feature flags help you ship faster, recover from incidents in seconds, and make product decisions backed by real data.&lt;/p&gt;

&lt;p&gt;The pattern is simple — wrap code behind a conditional, control it remotely — but the impact on your delivery velocity and operational confidence is profound. Teams that adopt feature flags consistently report shorter release cycles, fewer production incidents, and more experimentation.&lt;/p&gt;

&lt;p&gt;If you're ready to get started, &lt;a href="https://app.rollgate.io/register" rel="noopener noreferrer"&gt;create a free Rollgate account&lt;/a&gt; or explore the &lt;a href="https://demo.rollgate.io" rel="noopener noreferrer"&gt;interactive demo&lt;/a&gt; to see feature flags in action.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://rollgate.io" rel="noopener noreferrer"&gt;Rollgate&lt;/a&gt;, a feature flag platform for developers. If you have questions about feature flags, drop them in the comments — happy to help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Built Privacy-First Developer Tools That Run 100% in Your Browser</title>
      <dc:creator>Domenico Giordano</dc:creator>
      <pubDate>Thu, 11 Dec 2025 23:02:59 +0000</pubDate>
      <link>https://forem.com/domenico_giordano_e441224/i-built-privacy-first-developer-tools-that-run-100-in-your-browser-544i</link>
      <guid>https://forem.com/domenico_giordano_e441224/i-built-privacy-first-developer-tools-that-run-100-in-your-browser-544i</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every time I needed to format JSON or encode Base64, I had to use online tools that uploaded my data&lt;br&gt;
to unknown servers. For sensitive data, this felt wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;THEJORD&lt;/strong&gt; - a collection of developer tools where everything runs client-side. Your data&lt;br&gt;
never leaves your browser.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://thejord.it/en" rel="noopener noreferrer"&gt;thejord.it&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Included
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON Formatter &amp;amp; Validator&lt;/strong&gt; - Format, validate, beautify with syntax highlighting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF Tools&lt;/strong&gt; - Merge, split, compress PDFs using WebAssembly (no server!)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base64 Encoder/Decoder&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash Generator&lt;/strong&gt; - MD5, SHA-1, SHA-256, SHA-512&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regex Tester&lt;/strong&gt; - Live highlighting and match groups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cron Expression Builder&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diff Checker&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UUID Generator&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;And more...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 16 with Turbopack&lt;/li&gt;
&lt;li&gt;React 19&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;WebAssembly for PDF processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Privacy Matters
&lt;/h2&gt;

&lt;p&gt;When you paste code or data into online tools, you're trusting that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The server doesn't log your data&lt;/li&gt;
&lt;li&gt;The connection is secure&lt;/li&gt;
&lt;li&gt;The company won't be breached&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With client-side processing, none of this matters - your data stays on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;👉 &lt;a href="https://thejord.it/en" rel="noopener noreferrer"&gt;thejord.it&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love to hear your feedback! What tools would you like to see added?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
