Reminders
A reminder stores a periodic schedule for one logical grain. The configured reminder provider preserves the definition, and Orleans delivers ticks through normal grain request scheduling. A tick activates the grain when it has no current activation.
Use a reminder for work whose schedule must survive activation changes and cluster restarts. Reminders suit periods measured in minutes, hours, or days. A reminder can wake a grain which then creates a grain timer for finer-grained activation-scoped work.
Receive reminder ticks
Section titled “Receive reminder ticks”A grain receiving reminders implements IRemindable:
public sealed class ReportGrain : Grain, IReportGrain, IRemindable{ public Task ReceiveReminder( string reminderName, TickStatus status) { return GenerateReport(); }
private Task GenerateReport() => Task.CompletedTask;}Orleans invokes ReceiveReminder with the reminder name and TickStatus. The callback executes as a grain request and follows the grain’s scheduling and reentrancy rules.
When reminder work can run longer than a grain call timeout, use the long-running reminder recipe to start a restartable worker and return promptly.
Register or update a reminder
Section titled “Register or update a reminder”Register a named reminder from the grain:
IGrainReminder reminder = await this.RegisterOrUpdateReminder( "daily-report", dueTime: TimeSpan.FromMinutes(1), period: TimeSpan.FromDays(1));RegisterOrUpdateReminder creates the durable definition. Registering the same name again replaces its due time and period.
The returned IGrainReminder is a handle to the current registration. Persist the reminder name in application state and retrieve a current handle after activation when needed.
Retrieve or remove a reminder
Section titled “Retrieve or remove a reminder”Retrieve the current handle and unregister the reminder:
IGrainReminder? reminder = await this.GetReminder("daily-report");
if (reminder is not null){ await this.UnregisterReminder(reminder);}Use GetReminder for one named reminder and GetReminders for all reminders registered by the grain.
Reminder behavior
Section titled “Reminder behavior”The reminder provider durably stores each definition. The responsible silo loads the definition, calculates occurrences from its persisted start time and period, and sends tick requests to the grain.
Individual tick messages are transient. Cluster unavailability or ownership movement can leave a scheduled occurrence undelivered, while the durable definition continues producing later occurrences. Ownership convergence can also produce duplicate callback execution. Process each callback idempotently and reconcile work from durable business state.
FirstTickTime and Period identify the theoretical schedule. CurrentTickTime records when the runtime initiated the current delivery. Applications can compare those values with persisted progress to detect and reconcile missed occurrences.
Orleans delivers reminders to one activation of the grain identity. Delivery activates the grain when needed, including after the previous activation was collected or its silo stopped.
Reminder timing constraints
Section titled “Reminder timing constraints”Reminder registration accepts schedules with these boundaries:
dueTimeis Zero or greater. Zero schedules the first tick immediately.dueTimefits within the remaining DateTime range from registration time.periodis positive and at least ReminderOptions.MinimumReminderPeriod.- The default minimum period is one minute.
The runtime rejects negative values and InfiniteTimeSpan. It also rejects a dueTime which places the first tick after MaxValue.
For one scheduled execution, register a valid positive period and unregister the reminder in its first callback after the durable work succeeds.
Configure reminder storage
Section titled “Configure reminder storage”Every silo configures the same reminder provider so ownership can move across the cluster. Production deployments use a durable provider such as Azure Table, ADO.NET, Redis, Amazon DynamoDB, or Cosmos DB. The in-memory provider stores definitions for the lifetime of the cluster and supports local development and tests.
Configure each provider through the API supplied by its package. See Configure Amazon DynamoDB reminders for a compiled example which configures DynamoDB clustering and reminder storage independently. When composing resources with Aspire, see Orleans and Aspire integration.
The reminder table is part of silo startup. Provider availability and consistency determine whether the service can load, update, and reconcile registrations. See Reminder implementation for ownership, refresh, and delivery internals.
POCO grains
Section titled “POCO grains”Grains implementing IGrainBase directly use the same GrainReminderExtensions APIs. Inject IReminderRegistry when infrastructure code needs lower-level access through the current grain context.
See POCO grains for the interface-only grain model.
Troubleshoot reminders
Section titled “Troubleshoot reminders”| Observed behavior | Runtime behavior and action |
|---|---|
| Registration reports that the reminder service is not configured. | Configure one reminder provider on every silo before registering reminders. |
| Registration rejects the period. | Use a positive period at or above ReminderOptions.MinimumReminderPeriod. |
| A tick arrives after a long cluster interruption. | Reconcile the theoretical schedule in TickStatus with durable progress and process the outstanding business work. |
| The callback executes more than once for the same business interval. | Reminder ownership converges during membership changes. Use an idempotency key or durable completion marker for each interval. |
| Definitions disappear after a full cluster restart. | The in-memory provider scopes definitions to the cluster lifetime. Configure a durable production provider. |
| High-frequency work needs sub-minute intervals. | Use the reminder to activate the grain, then register a grain timer for the active phase. |
