Skip to content

Upgrade Orleans 9.x to 10.x

This guide assumes:

  • The application runs on the latest Orleans 9.x patch, preferably Orleans 9.2.1.
  • The application and its dependencies support .NET 8 or .NET 10.
  • All Orleans packages in the solution will move to the same current Orleans 10.x patch.
  • Provider schemas are current for the deployed Orleans 9.x version.

Orleans 10 packages target both .NET 8 and .NET 10. Retargeting the application to .NET 10 can be a separate change; keeping the application on .NET 8 reduces the number of variables in the Orleans upgrade.

AreaOrleans 10 impactRequired action
Source and analyzersUnorderedAttribute and OrleansConstructorAttribute are obsoleteRemove UnorderedAttribute. Replace OrleansConstructorAttribute only when DI constructor selection is required.
BehaviorCancelRequestOnTimeout now defaults to falseSet it explicitly if the application depends on cancellation being sent after a timeout.
ADO.NET providersSQL Server now uses Microsoft.Data.SqlClient and its invariant name by defaultReplace System.Data.SqlClient, update the invariant, and test every ADO.NET provider.
Serialization and stateOrleans 10 doesn’t require a wire-format or grain-state rewrite from Orleans 9Preserve serializer IDs, aliases, provider serializer settings, and stored type compatibility.
HostingThe generic-host UseOrleans and UseOrleansClient model remains currentNo hosting rewrite is required for an Orleans 9 application already using these APIs.
PlacementOrleans 9.2 already changed the default to ResourceOptimizedPlacementKeep it, or register RandomPlacement explicitly before the upgrade if deterministic continuity is required.
CancellationOrleans 10 adds cancellation support for observers and system targetsKeep at most one CancellationToken parameter per grain method and test timeout/cancellation races.
TimersNo new Orleans 10 timer breakContinue using RegisterGrainTimer; RegisterTimer was already obsolete in Orleans 8.2.
Call filtersNo new Orleans 10 filter registration modelContinue registering incoming and outgoing filters on ISiloBuilder or IClientBuilder.
DeploymentCross-major mixed clusters aren’t covered by the documented compatibility guaranteeUse a parallel Orleans 10 cluster unless your exact mixed-version topology has been qualified.

Keep package versions aligned. For example, with NuGet Central Package Management:

<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<OrleansVersion>10.2.2</OrleansVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Orleans.Client" Version="$(OrleansVersion)" />
<PackageVersion Include="Microsoft.Orleans.Sdk" Version="$(OrleansVersion)" />
<PackageVersion Include="Microsoft.Orleans.Server" Version="$(OrleansVersion)" />
</ItemGroup>
</Project>

Use the current stable Orleans 10.x patch when you perform the migration. Add every provider package used by the solution to the same central file, using the same Orleans version.

UnorderedAttribute has no effect because Orleans doesn’t guarantee message ordering based on this attribute. Remove it from grain interfaces.

OrleansConstructorAttribute is no longer recognized by Orleans. If a serializable type needs a constructor selected for dependency injection, use GeneratedActivatorConstructorAttribute or ActivatorUtilitiesConstructorAttribute. These attributes don’t select a constructor for deserializing data members.

Don’t change member IDs or constructor-visible state as part of this cleanup.

Orleans 10 defaults CancelRequestOnTimeout to false. A timed-out caller therefore stops waiting, but Orleans doesn’t automatically send cancellation to the target.

public static void ConfigureTimeoutCancellation(ISiloBuilder siloBuilder)
{
siloBuilder.Configure<SiloMessagingOptions>(options =>
{
options.CancelRequestOnTimeout = true;
});
}
public static void ConfigureTimeoutCancellation(IClientBuilder clientBuilder)
{
clientBuilder.Configure<ClientMessagingOptions>(options =>
{
options.CancelRequestOnTimeout = true;
});
}

Set this option on clients and silos that originate calls. A timeout isn’t proof that the target stopped executing, regardless of this option, so grain methods must remain safe to retry.

Orleans 10 ADO.NET clustering, persistence, reminders, and streaming use Microsoft.Data.SqlClient for SQL Server.

  1. Remove direct System.Data.SqlClient package references.
  2. Add Microsoft.Data.SqlClient through your central package policy. Use a current version supported by your application; don’t copy an old pinned version from an earlier migration guide.
  3. Change the provider invariant from System.Data.SqlClient to Microsoft.Data.SqlClient.
  4. Apply any provider migration scripts required between the schema version currently deployed and the target Orleans version.
  5. Test clustering, grain storage, reminders, and streams independently.

Use the repository migration directories for clustering, persistence, and reminders. Select the scripts for your database and apply them in version order.

The client-library switch doesn’t itself change your grain-state payload format. It can change connection defaults and authentication behavior, so validate connection encryption, certificates, authentication, retry policy, and transaction behavior in staging.

Preserve serialization and state compatibility

Section titled “Preserve serialization and state compatibility”

No Orleans 9-to-10 migration step requires renumbering IdAttribute values or rewriting state. Preserve the existing contract:

  • Don’t reuse or renumber IdAttribute values.
  • Keep AliasAttribute values stable when types or assemblies move.
  • Don’t reorder record primary-constructor parameters used as implicit serializer IDs.
  • Keep the configured grain-storage serializer unchanged during the runtime upgrade.
  • Read representative old state, write it with Orleans 10, and verify that the rollback build can still read it before allowing production writes.
  • Apply ADO.NET schema scripts in order and verify rollback compatibility before applying any irreversible script.

For the version-tolerance rules, see Orleans serialization.

Confirm hosting, placement, timers, and filters

Section titled “Confirm hosting, placement, timers, and filters”

An Orleans 9 application already using CreateApplicationBuilder, UseOrleans, or UseOrleansClient doesn’t need a hosting rewrite.

Orleans 9.2 made ResourceOptimizedPlacement the default. If the production cluster still relies on RandomPlacement, make that policy explicit:

public static void KeepRandomPlacement(ISiloBuilder siloBuilder)
{
siloBuilder.Services.AddSingleton<PlacementStrategy, RandomPlacement>();
}

Continue using RegisterGrainTimer. When preserving behavior from the old RegisterTimer API, set Interleave to true; the new API defaults to non-interleaving callbacks.

public override Task OnActivateAsync(CancellationToken cancellationToken)
{
_timer = this.RegisterGrainTimer(
callback: DoWorkAsync,
options: new GrainTimerCreationOptions
{
DueTime = TimeSpan.FromSeconds(1),
Period = TimeSpan.FromSeconds(10),
Interleave = true
});
return Task.CompletedTask;
}
private static Task DoWorkAsync(CancellationToken cancellationToken) =>
Task.CompletedTask;

Register call filters on the Orleans builders, not directly on IServiceCollection:

public static void ConfigureCallFilters(ISiloBuilder siloBuilder)
{
siloBuilder.AddIncomingGrainCallFilter(async context =>
{
await context.Invoke();
});
siloBuilder.AddOutgoingGrainCallFilter<MyOutgoingCallFilter>();
}

Follow Upgrade deployment and rollback. Use a separate Orleans 10 cluster by default. Keep the Orleans 9 cluster and its last compatible state recovery point until:

  • Orleans 10 clients and silos have passed smoke and load tests.
  • Provider data written by Orleans 10 is proven readable by the rollback build.
  • No queued or streamed payload contains a type shape unavailable to Orleans 9.
  • Metrics show stable activation placement, call latency, cancellation, reminder, and storage behavior.
  • Update to the latest Orleans 9.x patch and remove build warnings.
  • Align every Microsoft.Orleans.* package on one current 10.x patch.
  • Keep .NET 8 for the first deployment, or qualify the .NET 10 retarget separately.
  • Remove UnorderedAttribute and replace valid OrleansConstructorAttribute uses.
  • Set CancelRequestOnTimeout explicitly.
  • Replace System.Data.SqlClient and its invariant if SQL Server is used.
  • Preserve serializer IDs, aliases, and grain-storage serializer settings.
  • Confirm the intended placement strategy, timer interleaving, and call-filter registration.
  • Validate provider schemas and representative persisted state.
  • Prepare and rehearse a parallel-cluster deployment and rollback.