Skip to content

Typical Orleans configurations

Choose the smallest hosting model that matches the deployment.

ScenarioHosting modelClusteringState and reminders
One-process developmentCo-hosted silo and clientUseLocalhostClusteringMemory providers
Local distributed developmentAspire with multiple silo replicasLocal container or emulatorLocal container or emulator
Production service with HTTP/API entry pointsCo-host ASP.NET Core and Orleans in each silo when resource isolation isn’t requiredPlatform-appropriate durable providerDurable providers
Isolated frontend and worker tierExternal Orleans client in frontend; silo-only worker tierSame durable provider and cluster identity in both tiersDurable providers on silos
public static async Task LocalSiloAndClient(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.UseOrleans(siloBuilder =>
{
siloBuilder.UseLocalhostClustering();
siloBuilder.AddMemoryGrainStorageAsDefault();
siloBuilder.UseInMemoryReminderService();
});
var app = builder.Build();
app.MapGet("/hello/{name}", async (string name, IClusterClient client) =>
await client.GetGrain<IHelloGrain>(name).SayHello());
await app.RunAsync();
}

This is intentionally disposable. See Local development configuration before adding more local silos.

The compiled AppHost examples define Orleans resources and their dependencies:

public static void OrleansWithStorageAndReminders(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.AddRedis("orleans-redis");
var orleans = builder.AddOrleans("cluster")
.WithClustering(redis)
.WithGrainStorage("Default", redis)
.WithGrainStorage("PubSubStore", redis)
.WithReminders(redis);
builder.AddProject<Projects.Silo>("silo")
.WithReference(orleans)
.WaitFor(redis)
.WithReplicas(3);
builder.Build().Run();
}

The silo registers the Aspire service clients and lets Orleans consume injected configuration:

public static void BasicSiloConfiguration(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
// Add Aspire service defaults (OpenTelemetry, health checks, etc.)
builder.AddServiceDefaults();
// Add the Aspire Redis client for Orleans
builder.AddKeyedRedisClient("orleans-redis");
// Configure Orleans - Aspire injects all configuration automatically
builder.UseOrleans();
builder.Build().Run();
}

Use .WithReplicas(...) to model multiple silos. Local Redis containers and Azurite are useful development dependencies, but production deployments must bind those resources to managed or otherwise durable services. Don’t call .RunAsEmulator() in a production AppHost configuration.

A production configuration should make these choices explicit:

  1. Pick a durable clustering provider supported by the platform.
  2. Set stable ServiceId and environment/deployment-specific ClusterId values.
  3. Configure advertised addresses that every silo and client can route to.
  4. Add durable storage, reminders, streams, and grain directories only for features the application uses.
  5. Supply credentials through the deployment environment, preferably using workload identity.
  6. Configure health/readiness, telemetry, graceful termination, CPU, memory, and server GC.

For example, an Azure deployment can use Azure Table Storage for clustering and reminders and Azure Blob or Table Storage for grain state. An AWS deployment can use DynamoDB. A database-centered deployment can use ADO.NET. Redis, Cosmos DB, Consul, and ZooKeeper providers are also available for the capabilities their packages implement. Kubernetes deployments can use the separate Kubernetes hosting integration with one of these clustering providers.

The provider used for clustering doesn’t need to match the grain storage or reminder provider. Select each based on durability, latency, operational ownership, and cost.

Use an external client when the frontend and silo tier need separate scaling, security boundaries, deployments, or resource isolation. Configure UseOrleansClient with exactly the same service identity, cluster identity, and clustering backend as the silo tier. The client reaches gateway endpoints, so expose and secure those routes separately from silo-to-silo endpoints.

Avoid development configuration in production

Section titled “Avoid development configuration in production”

Don’t use any of the following in production:

  • UseLocalhostClustering, development clustering, or static gateway lists.
  • Memory grain storage or memory reminders when data must survive.
  • Azurite or other emulator endpoints.
  • Loopback or wildcard addresses as advertised endpoints.
  • Unbounded custom client connection retries.

See Server configuration, Client configuration, and Orleans and Aspire integration for implementation details.