.NET  

Migrate C# Azure Functions from In-Process to the Isolated Worker Model

Microsoft Azure Functions has been a popular platform for building serverless applications in .NET using the in-process execution model. However, with the evolution of .NET and the need for greater control, isolation, and long-term support, Microsoft now recommends migrating to the .NET isolated worker model.

In this article, we’ll walk through why this migration is necessary, what drivers make it critical for enterprises, how the in-process and isolated worker models differ, the trade-offs and cost impact, and a practical step-by-step migration approach with code samples based on Microsoft’s official guidance.

Why This Migration Is Necessary

Azure Functions were originally built using an in-process execution model, meaning your function logic ran inside the Functions host process. This architecture had benefits, such as tight coupling with the Azure Functions runtime and automatic binding support. But it also brought limitations, especially when it comes to modern .NET practices.

Microsoft has announced that the in-process model will no longer be supported after November 10, 2026. That makes migration not just recommended — but essential — to ensure ongoing support, security updates, and compatibility with future .NET versions.

Additionally:

  • The in-process model ties your app directly to the Functions host.

  • You lose control over runtime versions.

  • It limits advanced dependency injection and middleware flexibility.

  • It can limit observability and structured logging.

Driving Factors for Migration

Several key forces are pushing developers and teams toward the isolated worker model:

1. End of Support

Microsoft’s official support lifecycle ends for in-process functions — meaning no updates or security patches after November 2026.

2. Runtime Control

The isolated model runs your function app as its own .NET process, giving you control over:

  • Host startup behavior

  • Dependency injection

  • Logging

  • Configuration

3. Modern .NET Features

Because the isolated model runs separately, you can adopt the latest .NET features and libraries without risk of runtime conflict.

4. Better Observability

Isolated workers improve structured logging and telemetry, which is especially important for cloud-native applications in production.

Use Cases for the Isolated Worker Model

While all C# functions should migrate eventually, the isolated worker model is ideal for:

  • Enterprise-level applications: Where observability, startup control, and dependency injection matter.

  • Microservices architectures: That rely on separation of concerns.

  • Advanced hosting models: Like Kubernetes via KEDA or containerized deployments.

  • Apps with complex dependency graphs: That require modern .NET features.

  • Critical business workloads: Where operational stability and transparency are requirements.

Current (In-Process) vs Target (Isolated Worker)

CharacteristicIn-Process ModelIsolated Worker Model
ExecutionRuns inside Functions hostRuns in a separate .NET process
Runtime controlLimitedFull control
LoggingLess structuredBetter structured and configurable
Dependency InjectionLimitedFull DI support
Dependency conflictsPossibleLess likely
Support beyond 2026NoYes
Startup controlBasicAdvanced

In short, the isolated model gives you the best of modern .NET development practices — with the added benefits of observability and future-proofing.

Trade-Offs and Cost Impacts

Engineering Effort

Migrating is not automatic — code changes are required. Depending on the size of your application and the number of functions, migration can take hours to weeks per app.

Learning Curve

Teams may need time to understand the new startup model and how to manage dependencies, logging, and DI in a new way.

Performance

Because the isolated model runs your logic in a separate .NET process, cold starts may be slightly longer in some cases. But for mission-critical workloads, this is often acceptable and can be mitigated with Premium plans.

Azure Cost

  • Compute: Slight increase due to additional process overhead.

  • Monitoring: Potentially more telemetry data.

  • Hosting: No forced requirement to change plan, but Premium or App Service may be beneficial for performance.

Long-Term Benefit

Despite short-term costs, the long-term benefit of support, control, and maintainability makes migration a sound investment.

Migration Approach – A Step-by-Step Guide

Below is a practical roadmap to take your .NET Azure Functions from in-process to the isolated worker model.

1. Update Project File

Start by editing your .csproj file:

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
  <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.15.0" />
  <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" />
  <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
</ItemGroup>

Remove all Microsoft.NET.Sdk.Functions and WebJobs references — these are used by the in-process model.

2. Create Program.cs

Replace the legacy FunctionsStartup and host.json-driven startup with a new Program.cs:

using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
    })
    .Build();

host.Run();

This file is now the entry point for your function app.

3. Update Function Classes

Change your function signatures to match the isolated model:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System.Net;

public class MyFunction
{
    private readonly ILogger<MyFunction> _logger;

    public MyFunction(ILogger<MyFunction> logger)
    {
        _logger = logger;
    }

    [Function("MyHttpTrigger")]
    public HttpResponseData Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
    {
        _logger.LogInformation("Processing request...");
        var response = req.CreateResponse(HttpStatusCode.OK);
        response.WriteString("Hello, isolated world!");
        return response;
    }
}

Notable changes:

  • Functions are decorated with [Function], not [FunctionName].

  • Logging uses generic ILogger<T> injected via dependency injection.

4. Update Bindings

Replace binding attributes from WebJobs to the isolated equivalents:

In-ProcessIsolated
[BlobTrigger][BlobInput] / [BlobOutput]
[QueueTrigger][QueueTrigger] (different namespace)
[ServiceBusTrigger][ServiceBusTrigger] (from Worker package)

Make sure to reference the appropriate packages:

  • Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues

  • Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs

  • Microsoft.Azure.Functions.Worker.Extensions.ServiceBus

These may require additional NuGet packages.

5. Local Testing

Use the latest Azure Functions Core Tools v4 to test locally:

func start

Verify:

  • Functions load successfully.

  • Triggers fire correctly.

  • Logs appear as expected.

6. Deployment Preparation

Update your Azure Function App configuration:

  • Set FUNCTIONS_WORKER_RUNTIME to dotnet-isolated.

  • Deploy using your CI/CD pipeline.

  • Validate runtime version and app settings.

7. Validate in Azure

Once deployed:

  • Open the Azure Portal.

  • Confirm functions are listed.

  • Trigger them manually or via events.

  • Check logs in Application Insights.

Wrap-Up

Migration from the in-process model to the isolated worker model represents a strategic shift in how .NET Azure Functions run. It unlocks greater long-term value in terms of supportability, control, and alignment with modern .NET development patterns.

If you plan ahead, use automation, and follow a structured approach like this one, you can complete the migration without risking production stability or team burnout.