Blog Post

Apps on Azure Blog
5 MIN READ

Introducing On-demand Sandboxes for Azure Durable Task Scheduler (Private Preview)

NickGreenfield's avatar
Jun 02, 2026

Every durable workflow has that one activity you wish you could run somewhere else...

Maybe it needs a native toolchain. Maybe it runs untrusted customer or LLM-generated code. Maybe it needs Python from a .NET orchestrator, or bursty compute that should scale to zero when the work is done.

Today, we're thrilled to announce On-demand Sandboxes for Azure Durable Task Scheduler, now available in private preview. On-demand Sandboxes lets you move those individual workflow steps to managed, isolated compute while your orchestrator stays exactly where it is. Tell DTS which steps should run in isolation, provide a container image with the step code, and DTS handles provisioning, scaling, and teardown. No infrastructure to manage, no idle costs, no orchestrator changes.

Sign up for On-demand Sandboxes Private Preview Today →

Availability: On-demand Sandboxes targets the standalone Durable Task SDKs used outside the Azure Functions host — for apps running on Azure Container Apps, Azure Kubernetes Service, App Service, or anywhere else you self-host. The private preview supports the .NET and Python Durable Task SDKs, with additional language SDKs and Azure Functions support coming soon.

What is Azure Durable Task Scheduler?

The Durable Task Scheduler is a fully managed backend for durable execution on Azure. It can serve as the backend for a Durable Function App using the Durable Functions extension, or as the backend for an app leveraging the Durable Task SDKs in other compute environments, such as Azure Container Apps, Azure Kubernetes Service, or Azure App Service. For a deeper introduction, see the Durable Task Scheduler overview or the full Durable Task documentation.

Why On-demand Sandboxes?

Most activities belong in-process. They're fast, simple, and co-located with your orchestrator. But sometimes you hit a step that doesn't fit: it needs a native binary, a different language runtime, per-invocation isolation, or bursty compute you don't want to keep warm. On-demand Sandboxes gives you a way to handle those exceptions without spinning up dedicated infrastructure or managing scaling policies in Azure Kubernetes Service or Azure Container Apps.

  • Activity-level granularity. Move individual steps to managed compute, not your whole app.
  • Per-activity or per-invocation isolation. Each execution runs in a clean, microVM-backed sandbox. Ideal for untrusted code, customer plugins, or LLM-generated logic.
  • Cross-runtime flexibility. Run a Python inference step from a .NET orchestrator. No compromise on either side.
  • Scale-to-zero. Pay for CPU and memory per second of execution, not infrastructure that waits.
  • No orchestrator changes. Your orchestration code and hosting model don't change at all.

Here are a few scenarios where On-demand Sandboxes shines:

  • Native toolchains. Package ffmpeg, LibreOffice, or Pandoc in a container without dragging them into your main app.
  • CPU-heavy preprocessing. OCR, layout extraction, or image processing can scale independently of the rest of your workflow.
  • Cross-runtime workflows. A .NET orchestrator dispatches a Python inference step. No compromises.
  • Sandboxed code execution. Run customer plugins or LLM-generated code with a clean boundary on every invocation.
  • Multi-tenant isolation. Tenant-specific steps get dedicated boundaries while everything else stays in-process.
  • Bursty event-driven workloads. Steps that spike hard but rarely may not justify always-on infrastructure. Sub-second cold starts mean you get capacity when you need it without paying to keep it warm.

How it works

On-demand Sandboxes uses a two-part model: a worker profile in your orchestrator app that tells DTS which activities to offload, and a worker image that contains those activity implementations. Your orchestrator still calls activities the same way it always has; the decision to run one activity in a sandbox lives in the profile configuration.

1. Declare a sandbox worker profile

In the app that hosts your orchestrator, define a sandbox worker profile. The profile gives DTS the container image, resource shape, concurrency setting, and activity names that should run in a sandbox:

using Microsoft.DurableTask.Worker.AzureManaged.Sandbox;

[SandboxWorkerProfile("code-executor")]
internal sealed class CodeSandboxWorkerProfile : ISandboxWorkerProfile
{
    public void Configure(SandboxOptions options)
    {
        options.ContainerImage = Environment.GetEnvironmentVariable("DTS_SANDBOX_IMAGE")
            ?? throw new InvalidOperationException("DTS_SANDBOX_IMAGE is required.");
        options.Cpu = "1000m";
        options.Memory = "2048Mi";
        options.MaxConcurrentActivities = 1;
        options.AddActivity(TaskNames.ExecuteCode);
    }
}

Then enable on-demand sandbox discovery when you configure the Durable Task worker in the main app:

workerBuilder.AddTasks(tasks => tasks.AddAllGeneratedTasks());
workerBuilder.UseDurableTaskScheduler(options =>
{
    options.EndpointAddress = Environment.GetEnvironmentVariable("DTS_ENDPOINT");
    options.TaskHubName = Environment.GetEnvironmentVariable("DTS_TASK_HUB");
    options.Credential = credential;
});
workerBuilder.EnableSandboxes();

Here's what the profile configuration does:

  • SandboxWorkerProfile: a friendly profile id for this sandbox setup. It groups the activity, image, and resource settings for monitoring and reuse across deployments.
  • ContainerImage: the container image (from your registry) that contains the activity implementations.
  • Cpu / Memory: the resource shape for each worker instance. Sized per your activity's needs.
  • MaxConcurrentActivities: how many activities a single worker instance can process concurrently.
  • AddActivity: the specific activity to offload. Only activities added to a sandbox worker profile execute in DTS-managed isolated compute; everything else stays in-process.

The orchestrator call site doesn't change:

ExecuteCodeOutput execution = await context.CallActivityAsync<ExecuteCodeOutput>(
    TaskNames.ExecuteCode,
    new ExecuteCodeInput(pythonCode, input.CsvData));

ExecuteCode is not registered in the main app's in-process activity list. When the orchestrator calls it, DTS uses the codegen profile to route the work to the sandbox image.

2. Build the worker image

The worker image is a container you own. In most apps, this worker lives in a separate project from the orchestrator host so it can have its own entry point, dependencies, and container image. It registers the activity implementations it can run and opts in to managed execution with UseSandboxWorker():

builder.Services.AddDurableTaskWorker(workerBuilder =>
{
    workerBuilder.AddTasks(tasks =>
    {
        tasks.AddActivity<ExecuteCodeActivity>();
    });

    workerBuilder.UseSandboxWorker();
});

UseSandboxWorker() is the key line. It signals that this worker runs in DTS-managed compute. The sandbox worker does not need to configure the DTS endpoint, task hub, profile id, or credentials; DTS injects the runtime settings when it starts the container.

The activity implementations themselves are standard Durable Task activities. There's nothing special about the activity code: it can call a runtime with different dependencies, such as Python and pandas, while running in an isolated container instead of in your main app's process.

Package the image like any containerized service, including whatever runtimes and native tools the activity needs. Push it to your container registry (e.g., Azure Container Registry) and reference the image in the worker profile's ContainerImage option.

View logs in the DTS dashboard 

Once your sandbox activities are running, you can view their execution logs directly in the Durable Task Scheduler dashboard. The dashboard shows real-time output from your managed workers, including stdout, stderr, and activity lifecycle events. This gives you full visibility into what's happening inside the sandbox without needing to configure external log sinks or set up your own observability pipeline.

Demo

 

Get started 

On-demand Sandboxes is in private preview. To get access, sign up here. We'll enable the feature on your scheduler and help you get your first sandbox activity running.

Once you're in, the workflow is straightforward: declare a sandbox worker profile in your orchestrator app, build and push a worker image, and DTS takes care of the rest.

Sign up for On-demand Sandboxes Private Preview Today →

Documentation: Durable Task Scheduler overview

Samples: Azure-Samples/Durable-Task-Scheduler

Pricing: Azure Durable Task Scheduler pricing

Questions, feedback, or ideas? Open an issue in the Durable-Task-Scheduler GitHub repo. We'd love to hear from you.

Updated Jun 01, 2026
Version 1.0
No CommentsBe the first to comment