Runtime Feature Toggling in .NET Core Apps with Azure App Configuration
Learn how to toggle .NET Core app features at runtime using Azure App Configuration, with a step‑by‑step CLI and code example, plus limits and typical pitfalls.
27 Jun 2026, 17:07 UTC

Useful answer
You can change the behavior of a running .NET Core application without redeploying it by using Azure App Configuration feature flags. The flag value is stored in the App Configuration service, and the .NET SDK polls for updates (default every 30 seconds) so a change made in the Azure portal takes effect while the app continues to serve traffic.
Worked configuration and code example
1. Create an App Configuration store
Run the following Azure CLI commands in a terminal where you have az login completed and sufficient permissions (e.g., Contributor or the built‑in App Configuration Data Reader role). Replace placeholders with your own values.
# Create a resource group (if you don’t already have one)
az group create --name --location eastus
# Create the App Configuration store
az appconfig create \
--name \
--resource-group \
--location eastus \
--sku Standard
After creation, note the endpoint URL shown in the output (e.g., https://.azconfig.io). You will need this for the .NET app.
2. Add a feature flag
Add a flag named NewFeature that is initially off. You can also attach a filter (e.g., for a percentage rollout) later.
az appconfig kv set \
--name \
--resource-group \
--key "feature.NewFeature" \
--value "false" \
--content-type "application/vnd.microsoft.appconfig.featureflag+json;version=1"
The --content-type tells the service that the value is a feature flag definition.
3. Configure the .NET Core project
In your ASP.NET Core 6+ project, add the required NuGet packages:
dotnet add package Microsoft.FeatureManagement.AspNetCore
dotnet add package Microsoft.Configuration.ConfigurationProvider.AzureAppConfiguration
Update Program.cs (or Startup.cs for older templates) to register App Configuration and Feature Management:
using Microsoft.FeatureManagement;
using Microsoft.Configuration.ConfigurationProvider.AzureAppConfiguration;
var builder = WebApplication.CreateBuilder(args);
// Add Azure App Configuration
builder.Configuration.AddAzureAppConfiguration(options =>
options.Connect(builder.Configuration["ConnectionStrings:AppConfig"])
.UseFeatureFlags() // enables feature flag support
.ConfigureRefresh(refresh =>
refresh.Register("feature.NewFeature", refreshAll: true)
.SetCacheTimeout(TimeSpan.FromSeconds(30)))); // default 30 s
// Add Feature Management
builder.Services.AddFeatureManagement();
var app = builder.Build();
app.MapGet("/", async (IFeatureManager featureManager) =>
await featureManager.IsEnabledAsync("NewFeature")
? Results.Text("New feature is ON")
: Results.Text("New feature is OFF"));
app.Run();
Set the connection string as an app setting or environment variable named ConnectionStrings:AppConfig with the value Endpoint=https://.azconfig.io;Id=;Secret=. You can obtain the credential/secret from the Access keys blade in the portal or via a managed identity.
4. Toggle the flag at runtime
In the Azure portal, navigate to your App Configuration store → Explorer → feature/NewFeature and change the value to true. Save. The .NET SDK will pick up the change after the next refresh interval (default 30 s). No restart or redeployment is required.
Limits and quotas
- Each App Configuration store supports up to 100 000 key‑value entries; feature flags count as keys toward this limit.
- A subscription has a default quota of 10 App Configuration stores (request a increase via support if needed).
- Throughput is limited to 1 000 requests per second per store. Exceeding this results in HTTP 429 responses; the SDK will retry with exponential back‑off.
- Feature flag JSON must follow the
application/vnd.microsoft.appconfig.featureflag+json;version=1content type; malformed payloads are rejected.
Common mistakes and how to avoid them
1. Registering Feature Management after App Configuration
If you call builder.Services.AddFeatureManagement() before AddAzureAppConfiguration (or omit the .UseFeatureFlags() call), the feature flag provider is ignored and the flag value never updates. Fix: Ensure UseFeatureFlags() is chained to the App Configuration options before building the provider.
2. Using the synchronous IsEnabled method
Calling IFeatureManager.IsEnabled("NewFeature") (instead of the async version) blocks the thread while waiting for the latest flag value, which can degrade performance under load. Fix: Always use IsEnabledAsync in ASP.NET Core middleware, controllers, or services.
3. Ignoring the refresh interval
Assuming a flag change takes effect instantly can lead to confusion. The default poll interval is 30 seconds; you can shorten it with SetCacheTimeout, but setting it too low increases request volume and may hit the 1 000 rps limit. Fix: Choose a refresh interval that balances latency needs with throughput limits, and monitor the App Configuration metrics (request count, latency) in Azure Monitor.
4. Missing or incorrect content type
Storing a flag as a plain string (e.g., true) without the special content type causes the SDK to treat it as a regular key‑value, not a feature flag, so IsEnabledAsync always returns false. Fix: Always set --content-type "application/vnd.microsoft.appconfig.featureflag+json;version=1" when creating or updating flags via CLI, SDK, or portal.
Practical verification steps
- Deploy the sample app to an Azure App Service or run it locally with the connection string configured.
- Confirm the initial endpoint returns “New feature is OFF”.
- In the portal, toggle the flag to
trueand save. - Wait up to the configured refresh interval (default 30 s) and reload the endpoint; you should see “New feature is ON”.
- Check the App Configuration diagnostic logs (enable Diagnostic Settings → Send to Log Analytics) for successful GET requests to
feature.NewFeatureand a 200 response.
If the flag does not change, review the common mistakes above, verify the connection string, and ensure the App Configuration service is not throttling (look for 429 responses in logs).
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.