During standup, a distributed systems engineer explains workflow signals in Temporal. How do they work?
Signals are fire-and-forget: client.signal_workflow(workflow_id, signal_name, args). The workflow registers @workflow.signal handlers that mutate state (e.g. appending to a queue). Because Temporal replays history, signals are durably delivered even if the workflow was blocked on an await asyncio.sleep() or waiting for an activity.
2 / 5
In a PR review, the team debates queries vs updates in Temporal. What's the difference?
Queries (@workflow.query) are read-only and synchronous — they return the current workflow state immediately without changing it or being recorded in event history. Updates (@workflow.update) can modify state and return a result, and are recorded in history — unlike signals they provide a response to the caller confirming the state change.
3 / 5
An incident requires implementing the saga pattern with compensations in Temporal. How is this done?
Saga in Temporal is implemented manually: execute activities in sequence, push compensating activities to a list, and in the except block iterate the list in reverse to run compensations. Temporal's durable execution guarantees the compensation activities will run even if the worker crashes mid-compensation — the workflow replays from the event history.
4 / 5
In a design review, the team needs to prevent event history bloat for a long-running workflow. What does continue-as-new do?
continue_as_new() is Temporal's solution to infinite-loop workflows. It atomically completes the current execution and starts a new one with the same workflow ID, passing the current state as the new input. Event history resets to zero, preventing the history from growing past Temporal's ~50,000 event limit. Essential for perpetual workflows like cron jobs or event processing loops.
5 / 5
During a code review, a long-running activity doesn't call heartbeat. Why does this matter?
activity.heartbeat(details) serves two purposes: it proves the activity is alive (Temporal reschedules if heartbeat_timeout elapses without one), and it saves a checkpoint. After rescheduling on a new worker, activity.get_heartbeat_details() retrieves the last saved details so the activity can resume from where it left off rather than starting over.