🔥 Pragmatic .NET Code Rules Course is on Presale - 40% off!BUY NOW

Feature Flags without redeploying: what people usually get wrong in .NET

A quick word from me

This issue isn't sponsored - I write these deep dives in my free time and keep them free for everyone. If your company sells AI tools, dev tools, courses, or services that .NET developers would actually use, sponsoring an issue is the most direct way to reach them.

Want to reach thousands of .NET developers? Sponsor TheCodeMan →

This issue is made possible thanks to JetBrains, who help keep this newsletter free for everyone. A huge shout-out to them for their support of our community. Let's thank them by entering the link below. Struggling with slow builds, tricky bugs, or hard-to-understand performance issues? dotUltimate fixes all of that. It’s the all-in-one toolbox for serious .NET developers. 👉 Upgrade your .NET workflow.

Introduction

How do you enable or disable features without redeploying the app?

If your first thought is “I’ll just flip a value in appsettings.json” - you’re not alone. But that’s also where most Feature Flag implementations quietly fail.

In the last few days, I shared a short post about Feature Flags in .NET, and the comments were exciting.

They all circled the same confusion:

Do we really avoid redeployment? How does this work with multiple instances? Is appsettings.json enough? Do I still need to run a DevOps release?

Let’s clear this up - with real code that actually works.

First: What “Without Redeploying” Actually Means

Let’s be very explicit.

“Without redeploying” means:

  • ❌ no build
  • ❌ no release pipeline
  • ❌ no app restart
  • ❌ no new container image
  • ✅ behavior changes while the app is running

    If changing a feature flag requires you to click 'Deploy', then you haven’t decoupled deployment from release - you've just moved the toggle.

    Why appsettings.json Is NOT Enough

Yes, you can define feature flags in appsettings.json.

C#
{ "FeatureManagement": { "BetaFeature": true }}

But here’s the problem:

  1. appsettings.json is read at startup
  2. each instance has its own copy
  3. any change requires:
    • file change
    • restart
    • redeploy So this works for:
    • local development
    • demos
    • small experiments

But it does not work for:

  • multiple instances
  • Kubernetes
  • Azure App Service
  • real production traffic

To truly avoid redeployment, feature flags must live outside the application.

The Correct Architecture

Feature Flags must be:

  • centrally stored
  • shared across instances
  • read at runtime
  • refreshable without a restart In .NET, this is exactly what Azure App Configuration + Feature Management gives us. Let’s build this properly.

Step 1: Install Required Packages

These give us:

  • Feature Flags API
  • Azure App Configuration integration
  • runtime refresh support
C#
dotnet add package Microsoft.FeatureManagement.AspNetCoredotnet add package Microsoft.Azure.AppConfiguration.AspNetCore

Step 2: Configure Azure App Configuration

In Azure Portal:

  1. Create Azure App Configuration
  2. Go to Feature Manager
  3. Create a feature flag:

Step 3: Add Connection String

In appsettings.json:

C#
{ "AzureAppConfig": { "ConnectionString": "<YOUR_CONNECTION_STRING>" }}

In real projects, this belongs in Key Vault or environment variables.

Step 4: Configure Program.cs

This is the part most examples skip or oversimplify.

C#
using Microsoft.FeatureManagement;using Microsoft.Extensions.Configuration.AzureAppConfiguration; var builder = WebApplication.CreateBuilder(args); // 1. Connect to Azure App Configurationbuilder.Host.ConfigureAppConfiguration(config =>{ var settings = config.Build(); config.AddAzureAppConfiguration(options => { options .Connect(settings["AzureAppConfig:ConnectionString"]) // Register feature flags .UseFeatureFlags(featureOptions => { featureOptions.CacheExpirationInterval = TimeSpan.FromSeconds(10); }) // Register refresh with a sentinel key .ConfigureRefresh(refresh => { refresh .Register("FeatureFlags:Sentinel", true) .SetCacheExpiration( TimeSpan.FromSeconds(10)); }); });}); // 2. Add Feature Managementbuilder.Services.AddFeatureManagement(); // 3. Add Azure App Config refresh middlewarebuilder.Services.AddAzureAppConfiguration(); var app = builder.Build(); // Enable refresh middlewareapp.UseAzureAppConfiguration(); app.MapGet("/", () => "Feature Flags Demo is running"); // Feature-gated endpointapp.MapGet("/beta", async (IFeatureManager featureManager) =>{ if (await featureManager.IsEnabledAsync("BetaFeature")) { return Results.Ok("Beta feature is ENABLED"); }  return Results.Ok("Beta feature is DISABLED");}); app.Run();

In Azure App Configuration:

Create a key-value pair:

  • Key: FeatureFlags:Sentinel
  • Value: any string (e.g. timestamp)

Whenever you update this value:

  • all feature flags refresh
  • no restart
  • no redeploy

Step 6: See It in Action

Run the app and call GET /beta → ❌ disabled Enable BetaFeature in the Azure Portal Wait ~10 seconds Call /beta again → 🚀 enabled

No redeploy. No restart. No pipeline.

Important Production Gotcha: Caching

Azure App Configuration does cache values.

If you don’t configure refresh:

  • changes may take minutes
  • developers think “it doesn’t work”

That’s why:

  • CacheExpirationInterval
  • sentinel keys
  • refresh middleware

matter a lot.

This is where most “Feature Flags don’t work” stories come from.

What About Multiple Instances?

This setup works perfectly with:

  • multiple app instances
  • load balancers
  • Kubernetes
  • App Service scaling Because:
  • flags are centralized
  • decision logic is deterministic
  • instances are stateless The feature decision does not depend on the instance.

3rd-Party Feature Flag Providers

Azure App Configuration is great if you’re already on Azure.

Other solid options:

  • LaunchDarkly
    • enterprise-grade
  • Unleash
    • open-source & self-hosted
  • Flagsmith
    • SaaS or self-hosted

The provider matters less than the runtime architecture.

When Feature Flags Become a Problem

Feature Flags are powerful - but dangerous if abused:

  • flags that live for years
  • nested if statements everywhere
  • “temporary” flags that never die Best practice:
  • flags should have an owner
  • flags should have a removal date
  • flags should not replace versioning

Wrapping Up

Feature Flags are not about hiding code paths.

hey are about decoupling deployment from release.

If flipping a flag requires a redeploy, you didn’t gain flexibility - you added complexity.

If you want a deeper dive, I’ve already written a full article on Feature Flags in .NET with Azure Feature Management here.

More real-world .NET architecture topics coming soon 🚀 That's all from me for today.


Want to enforce clean code automatically? My Pragmatic .NET Code Rules course shows you how to set up analyzers, CI quality gates, and architecture tests - a production-ready system that keeps your codebase clean without manual reviews. Or grab the free Starter Kit to try it out.

About the Author

Stefan Djokic is a Microsoft MVP and senior .NET engineer with extensive experience designing enterprise-grade systems and teaching architectural best practices.

There are 3 ways I can help you:

1

Pragmatic .NET Code Rules Course

Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.

Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.

2

Design Patterns Ebooks

Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.

Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.

3

Join 20,000+ subscribers

Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.

Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Software Architecture & Best Practices.