Local Activity
What is a Local Activity?
A Local Activity is an Activity Execution that executes in the same Worker process as the Workflow Execution that schedules it.
Unlike a regular Activity, a Local Activity never enters an Activity Task Queue. Instead, the Workflow Worker executes it directly in an in-process queue. Because it avoids the round trip through the Temporal Service, a Local Activity has significantly lower latency and produces fewer Event History entries than a regular Activity.
Local Activities help with performance optimization and are not a replacement for regular Activities.
Consider using a Local Activity only when the operation:
- is short-lived (completes in a few seconds), including retries
- can execute in the same binary as the Workflow
- does not require routing to a specific Worker or Task Queue
- does not require global rate limiting
- is idempotent
For most production workloads, regular Activities remain the recommended default.
Use Local Activities only when your use case requires the performance optimization they provide, such as high-throughput Workflows with many very short-lived operations. For most business logic, regular Activities are the better choice.
How Local Activities execute
Regular Activities are coordinated through the Temporal Service.
The execution flow is:
- A Workflow schedules an Activity.
- The Workflow completes its Workflow Task by sending a
ScheduleActivityTaskcommand to the Temporal Service. - The Temporal Service creates an Activity Task.
- An Activity Worker polls the Activity Task Queue and executes the Activity.
- The Activity result is recorded in Event history.
- The Workflow resumes in a new Workflow Task.
Local Activities follow a shorter execution path:
- A Workflow schedules a Local Activity.
- The Local Activity is placed into an in-process queue within the Workflow Worker.
- The Workflow Worker executes the Local Activity immediately.
- The result is returned directly to the Workflow.
- When the Workflow Task completes, the Worker records a
MarkerRecordedevent containing the Local Activity result.
Unlike regular Activities, scheduling and execution occur entirely within the Worker process. Only the final marker is persisted to Event history.
Workflow Task heartbeating
Local Activities do not support Activity heartbeats. Instead, the SDK supports Workflow Task heartbeating.
Workflow Task heartbeating means that if a Local Activity approaches approximately 80% of the Workflow Task Timeout (10 seconds by default), the Worker completes the current Workflow Task and requests a new one from the Temporal Service. This renews the Worker's authorization to continue executing the Workflow and allows the Local Activity to keep running without exceeding the Workflow Task Timeout.
This enables Local Activities to run longer than a single Workflow Task timeout, but it comes with tradeoffs:
- Each Workflow Task heartbeat adds additional Events to the Event history.
- Signals and other external Workflow events are not processed until the Local Activities finish.
- Commands generated by the Workflow are not sent to the Temporal Service until one of the following occurs:
- the Local Activity completes
- the next Workflow Task heartbeat occurs
If your operation regularly approaches the Workflow Task timeout, it is usually better implemented as a regular Activity.
Failure and durability
Regular Activities are durably tracked by the Temporal Service. Scheduling, completion, retries, and failures are all recorded in the Event history. If a Worker crashes after an Activity completes, the completed Activity is not executed again.
Local Activities behave differently. A Local Activity result becomes durable only when the enclosing Workflow Task successfully completes and records a MarkerRecorded event. Until then, execution exists only in Worker memory.
If the Worker crashes before the Workflow Task completes, the Workflow Task is retried, causing Local Activities executed during that Workflow Task to run again.
Because of this behavior, Local Activities provide at-least-once execution semantics and should always be idempotent.
Once a MarkerRecorded event has been written to the Event history, replay uses the recorded result rather than executing the Local Activity again.
Mixing Local Activities and regular Activities
A Workflow can freely combine Local Activities and regular Activities.
For example:
Local Activity A
Local Activity B
Regular Activity C
When the Workflow Task completes after scheduling Activity C, the Worker sends commands similar to:
MarkerRecorded(Local Activity A)MarkerRecorded(Local Activity B)ScheduleActivityTask(Activity C)
If Activity C later fails or retries, the Workflow replays using the recorded markers for A and B. Those completed Local Activities are not executed again because their results have already been persisted in the Event history. Only Activity C is retried according to its Retry Policy.
The only time completed Local Activities execute again is if the Worker fails before their completion markers are recorded.
Limitations
Compared to regular Activities, Local Activities have several important limitations:
- They execute on the Workflow Worker rather than an Activity Worker.
- They do not support Activity heartbeating.
- Long retry intervals are inefficient because retries eventually require Workflow Timers and additional Event history entries.
- They delay Signal processing while the Workflow Task is executing.
- They provide at-least-once execution semantics until their completion markers are recorded.
These tradeoffs make Local Activities unsuitable for long-running operations or most interactions with external systems.
Choosing between regular Activities and Local Activities
Choose a regular Activity unless you have a specific need for the performance optimization that Local Activities provide.
Use a Local Activity when:
- execution completes in a few seconds
- retries are expected to be short
- the operation is idempotent
- low latency is more important than full durability
- routing, rate limiting, and separate Activity Workers are unnecessary
Use a regular Activity when:
- interacting with external systems
- execution may take longer than a few seconds
- retries may span minutes or hours
- Activity heartbeating is required
- strong durability guarantees are important
Regular Activities are the right choice for most applications. Local Activities are an optimization for specialized, high-throughput workloads where minimizing latency and Event history size outweighs their reduced durability guarantees.
Use cases for Local Activities
Good use cases for Local Activities include:
- Lightweight data transformations
- Small computations
- Reading from an in-memory cache
- Fast local filesystem operations
- High-throughput Workflows with many very short-lived operations
Use regular Activities for:
- Network requests
- Database operations
- External API calls
- Long-running work
- Operations requiring durable retries
- Operations that benefit from Task Queue routing or rate limiting
Activity vs. Local Activity
| Feature | Activity | Local Activity |
|---|---|---|
| Execution | Activity Worker | Workflow Worker |
| Task Queue | Yes | No |
| Service round trip | Required | Not required |
| Latency | Higher | Lower |
| Event history | Fully recorded | MarkerRecorded on completion |
| Heartbeating | Activity heartbeats | Workflow Task heartbeating |
| Retry durability | Durable | At-least-once until marker is recorded |
| Signal responsiveness | Unaffected | Delayed while the Workflow Task executes |
| Best for | General-purpose work | Short, high-throughput operations |