Local development configuration
Silo configuration
Section titled “Silo configuration”For the shortest development loop, host grains and the calling code in one process and use localhost clustering:
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();}UseOrleans registers a co-hosted IClusterClient, so controllers, endpoints, hosted services, and other dependency-injected components can call grains without a separate client process.
UseLocalhostClustering configures loopback networking and development clustering. Memory storage and memory reminders are also development-only: their data is lost when the process stops.
Client configuration
Section titled “Client configuration”Use a separate process when the production architecture requires client and silo isolation:
public static async Task LocalExternalClient(string[] args){ var builder = Host.CreateApplicationBuilder(args);
builder.UseOrleansClient(clientBuilder => { clientBuilder.UseLocalhostClustering(); });
await builder.Build().RunAsync();}The client and silo must use matching gateway ports, ServiceId, and ClusterId. UseLocalhostClustering supplies matching defaults when both run on the same machine.
Run multiple local silos
Section titled “Run multiple local silos”UseLocalhostClustering is optimized for a single local silo. To exercise membership changes or failover, use one of these approaches:
- Use Aspire with a containerized Redis or other supported clustering resource and multiple silo replicas.
- Configure a shared development clustering primary and assign each silo unique silo and gateway ports.
- Run the same production clustering provider against a local container or emulator.
Aspire is usually the easiest option because it allocates endpoints, starts dependencies, injects configuration, and displays logs for every replica.
Choose local backing services
Section titled “Choose local backing services”Use in-memory providers for fast unit-level iteration. Use containers or emulators when you need to test provider behavior, serialization formats, schema setup, or restart durability. Keep the same provider package and configuration shape that production uses whenever practical.
For integration tests that create in-process clusters, use the Microsoft.Orleans.TestingHost package and TestClusterBuilder instead of manually assigning ports. For complete applications, see the Orleans samples.
