Typical Orleans configurations
Choose the smallest hosting model that matches the deployment.
| Scenario | Hosting model | Clustering | State and reminders |
|---|---|---|---|
| One-process development | Co-hosted silo and client | UseLocalhostClustering | Memory providers |
| Local distributed development | Aspire with multiple silo replicas | Local container or emulator | Local container or emulator |
| Production service with HTTP/API entry points | Co-host ASP.NET Core and Orleans in each silo when resource isolation isn’t required | Platform-appropriate durable provider | Durable providers |
| Isolated frontend and worker tier | External Orleans client in frontend; silo-only worker tier | Same durable provider and cluster identity in both tiers | Durable providers on silos |
Local development
Section titled “Local development”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.
Recommended: Aspire configuration
Section titled “Recommended: Aspire configuration”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.
Production configuration
Section titled “Production configuration”A production configuration should make these choices explicit:
- Pick a durable clustering provider supported by the platform.
- Set stable ServiceId and environment/deployment-specific ClusterId values.
- Configure advertised addresses that every silo and client can route to.
- Add durable storage, reminders, streams, and grain directories only for features the application uses.
- Supply credentials through the deployment environment, preferably using workload identity.
- 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.
Separate external client
Section titled “Separate external client”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.
