Moving Azure Functions to the isolated worker model
Support for the in-process model ends in November 2026. The isolated worker model is where new .NET versions and features land, and the move is mostly mechanical.
Azure Functions has two ways to run .NET code. In the in-process model, your functions run inside the Functions host itself. In the isolated worker model, they run in a separate .NET process that you control.
Microsoft has announced that support for the in-process model ends on November 10, 2026. In-process apps are also limited to .NET 8. If you have in-process apps, now is the time to plan the move.
Why isolated is better anyway
- You choose the .NET version, independent of the host, including new releases as soon as they're supported.
- Normal .NET startup. A
Program.cswith the same dependency injection, configuration and logging you use in ASP.NET Core. - Middleware. Cross-cutting code, such as correlation IDs or exception handling, runs around every function.
- No assembly conflicts with the host's own dependencies.
What changes
Project settings and packages. Reference Microsoft.Azure.Functions.Worker and Microsoft.Azure.Functions.Worker.Sdk, plus the matching Microsoft.Azure.Functions.Worker.Extensions.* packages for your triggers, and set <OutputType>Exe</OutputType>. The app setting FUNCTIONS_WORKER_RUNTIME becomes dotnet-isolated.
A Program.cs:
var builder = FunctionsApplication.CreateBuilder(args);
builder.Services.AddApplicationInsightsTelemetryWorkerService();
builder.Services.AddHttpClient<CrmClient>();
builder.Build().Run();
Attributes and signatures. [FunctionName] becomes [Function], and functions are usually instance methods on a class that receives services through its constructor:
public class OrderFunctions(CrmClient crm, ILogger<OrderFunctions> logger)
{
[Function("SyncOrder")]
public async Task Run(
[ServiceBusTrigger("orders", Connection = "ServiceBusConnection", AutoCompleteMessages = false)]
ServiceBusReceivedMessage message,
ServiceBusMessageActions actions,
CancellationToken ct)
{
var order = message.Body.ToObjectFromJson<OrderPlaced>();
await crm.UpsertOrderAsync(order, ct);
await actions.CompleteMessageAsync(message, ct);
}
}
Setting AutoCompleteMessages = false means the message is completed only by your code, after the work succeeds.
HTTP triggers. With ASP.NET Core integration enabled (builder.ConfigureFunctionsWebApplication()), HTTP functions use the familiar HttpRequest and IActionResult types.
How to migrate safely
- Move one Function App at a time, starting with the simplest.
- Convert the project, then go through each function's bindings. Output bindings work differently in the isolated model, so check each one.
- Deploy to a staging slot, run it against real traffic or a test environment, then swap.
- Check logging. Log levels and Application Insights configuration live in
Program.csandhost.jsonnow, and it's easy to end up with less logging than before.
Takeaway
The in-process model has an end date and is stuck on .NET 8. The isolated worker model gives you current .NET versions, normal dependency injection and middleware. The migration is mostly mechanical, so do it one app at a time, well before the deadline.