Your TaskActor now maintains state across activations. Tasks persist. Conversation history survives. But what about scheduling? How do you fire a callback 24 hours after a task is created to check if it's overdue? How do you send a heartbeat every 30 seconds while an actor is active?
In traditional systems, you'd reach for cron jobs, external schedulers, or background task queues. These work, but they introduce operational complexity: separate services to deploy, monitor, and coordinate with your actors. What if scheduling was built into the actor model itself?
Dapr actors provide two scheduling mechanisms:
Timers: Lightweight callbacks that fire while the actor is active. Lost when the actor deactivates or the pod restarts. Perfect for heartbeats, timeouts, and short-lived monitoring.
Reminders: Persistent callbacks that survive actor deactivation, pod restarts, and even cluster failures. Perfect for deadlines, follow-ups, and mission-critical scheduled work.
The distinction matters. Choose wrong, and your deadline notifications vanish when Kubernetes reschedules your pod. Choose right, and your scheduling just works.
Before diving into implementation, understand what you're trading:
The rule of thumb: If losing the scheduled callback would cause business problems, use a reminder. If it's just operational convenience, use a timer.
Timers are in-memory callbacks. When your actor deactivates (idle timeout, pod restart, scale-down), all timers are lost. The actor must re-register them on the next activation if needed.
Output: Heartbeat for TaskActor task-123: {'context': 'monitoring'}
Output: Timer 'heartbeat' unregistered for TaskActor task-123
Dapr accepts multiple formats for due_time and period:
Reminders are persistent callbacks. Dapr stores reminder metadata in the Scheduler service, which persists to your state store. When your actor deactivates, the reminder survives. When the reminder fires, Dapr activates the actor and invokes the callback.
Output: Reminder 'deadline' registered for TaskActor task-123
Unlike timers, all reminders invoke a single method: receive_reminder. You dispatch based on the reminder name:
Dapr provides CLI commands to inspect and manage reminders externally:
Use this framework when deciding:
Ask yourself:
Does your dapr-deployment skill understand actor scheduling patterns?
"Using my dapr-deployment skill, explain when I should use an actor timer versus a reminder for sending a weekly summary every Monday."
"Explain the difference between Dapr actor timers and reminders. What happens if I register a timer and a reminder for 1 hour from now, but the pod reschedules after 30 minutes?"
"Help me implement a task deadline system for my TaskActor. I need to register a reminder for 24 hours, cancel it if the task completes early, and mark it 'overdue' if it fires."
"Help me design a monitoring system for my actors. Which parts (heartbeat, health check, stale detection) should use timers vs reminders and why?"