ShutdownDeadlineBuffer configuration for Lambda Workers
ShutdownDeadlineBuffer is specific to the temporal-aws-lambda module and controls the full shutdown window reserved at the end of the Lambda invocation, including graceful shutdown time, shutdown hooks, and service stub cleanup. The default is GracefulShutdownTimeout (5s) + 2s. If you change GracefulShutdownTimeout without explicitly setting ShutdownDeadlineBuffer, the buffer is recomputed as GracefulShutdownTimeout + 2s. If you explicitly set ShutdownDeadlineBuffer, it must be greater than or equal to GracefulShutdownTimeout.
Serverless Worker on AWS Lambda using temporal-aws-lambda module
The temporal-aws-lambda contrib module allows you to run a Temporal Serverless Worker on AWS Lambda. Deploy your Worker code as a Lambda function, and Temporal Cloud invokes it when Tasks arrive. Each invocation starts a Worker, polls for Tasks, then gracefully shuts down before a configurable invocation deadline. Workflows and Activities are registered the same way as with a standard Worker.
Lambda Worker handler implementation pattern
Create a class that implements AWS Lambda's RequestHandler interface and delegates to LambdaWorker.run in a static field. Pass a WorkerDeploymentVersion and a configure callback that registers your Workflows and Activities. Assign the handler to a static field so it is created once during Lambda cold start and reused across invocations.
Lambda Worker implementation example
package io.temporal.samples.lambdaworker;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import io.temporal.aws.lambda.LambdaWorker;
import io.temporal.common.WorkerDeploymentVersion;
/** AWS Lambda entry point for the Temporal worker. */
public class LambdaFunction implements RequestHandler<Object, Void> {
private static final RequestHandler<Object, Void> WORKER =
LambdaWorker.run(
new WorkerDeploymentVersion(
LambdaWorkerSample.deploymentName(), LambdaWorkerSample.buildId()),
LambdaWorkerSample::configure);
@Override
public Void handleRequest(Object input, Context context) {
return WORKER.handleRequest(input, context);
}
}
This example shows how to implement a Lambda entry point that delegates to LambdaWorker.run with a WorkerDeploymentVersion and configuration callback.
Lambda Worker configuration callback methods
The configure callback receives a LambdaWorkerOptions.Builder with the same registration methods as a standard Worker: registerWorkflowImplementationTypes, registerActivitiesImplementations, and registerDynamicWorkflowImplementationType. If you need to assemble options outside the callback, call LambdaWorkerOptions.newBuilderFromEnvironment(), configure the builder, and pass the built options to LambdaWorker.newHandler(...).
Temporal configuration loading for Lambda
The temporal-aws-lambda module automatically loads Temporal client configuration from a TOML config file and environment variables. The config file location is resolved in this order: 1) TEMPORAL_CONFIG_FILE environment variable if set, 2) temporal.toml in $LAMBDA_TASK_ROOT (typically /var/task), 3) temporal.toml in the current working directory. The file is optional; if absent, only environment variables are used.
PHP SDK Temporal Client documentation location
The Temporal Client for the PHP SDK is documented under the Client section. The main entry point for implementing the Temporal Client with the PHP SDK is the Temporal Client page.
PHP SDK platform documentation structure
The PHP SDK platform documentation covers two main areas: Observability and Enriching the UI. These topics are available under the develop/php/platform section of the Temporal documentation.
PHP SDK Workers documentation structure
The PHP SDK Workers documentation section includes a guide on how to run worker processes. The main topic covered is implementing workers with the PHP SDK.
PHP version check command
To verify PHP is installed, run `php -v` in your terminal.
GRPC extension required for RoadRunner
The GRPC extension (ext-grpc) is required to work with the RoadRunner application server.
RoadRunner server startup command
Start the RoadRunner application server by running `./rr serve` in a new terminal window.
Example Worker registration in PHP
A Worker file example (worker.php) that creates a WorkerFactory, creates a Worker, registers Workflow and Activity types, and runs the factory: ```php
<?php
declare(strict_types=1);
use Temporal\WorkerFactory;
ini_set('display_errors', 'stderr');
require "vendor/autoload.php";
$factory = WorkerFactory::create();
$worker = $factory->newWorker();
// Register Workflows
$worker->registerWorkflowTypes(\App\SayHelloWorkflow::class);
// Register Activities
$worker->registerActivity(\App\GreetingActivity::class);
$factory->run();
```
Worker registration example
In the worker.php file, create a WorkerFactory instance, create a new Worker, and register Workflow and Activity types using $worker->registerWorkflowTypes() and $worker->registerActivity(). Then call $factory->run() to start the Worker.
RoadRunner installation via CLI
Download RoadRunner using `./vendor/bin/rr get`. When prompted to create a default .rr.yaml configuration file, answer yes. The configuration will be replaced with proper settings in the next step.
RoadRunner configuration file structure
Create a .rr.yaml configuration file with the following content:
version: "3"
rpc: listen: tcp://127.0.0.1:6001
server: command: "php worker.php"
temporal: address: "127.0.0.1:7233"
logs: level: info
GRPC installation on macOS with Apple Silicon
On macOS with Apple Silicon (M1/M2/M3/M4) and PHP 8.3, `pecl install grpc` may appear to hang. If this happens, install a specific version with `pecl install channel://pecl.php.net/grpc-1.78.0RC2`. Check pecl.php.net/package/grpc for the latest versions.
Temporal PHP SDK installation
Install the Temporal PHP SDK with the command `composer require temporal/sdk`. The current version constraint is ^2.16.
PSR-4 autoloading configuration
In composer.json, add PSR-4 autoloading with the "App\\" namespace mapped to the "src/" directory. After updating composer.json, run `composer dump-autoload` to regenerate the autoloader.
Configure Worker options using WorkerOptions
Additional Worker options can be configured using Temporal\Worker\WorkerOptions. Example: $worker = $factory->newWorker('your-task-queue', WorkerOptions::new()->withMaxConcurrentWorkflowTaskPollers(10));
RoadRunner .rr.yaml configuration for Temporal Worker
RoadRunner requires a .rr.yaml configuration file that specifies the worker command, RPC settings, and Temporal service address. The configuration includes: rpc.listen (e.g., tcp://127.0.0.1:6001), server.command (e.g., 'php worker.php'), temporal.address (e.g., 'temporal:7233'), and temporal.activities.num_workers (e.g., 10).
Create multiple Task Queue connections in single Worker Process
You can create as many Task Queue connections inside a single Worker Process as needed. Each connection would use $factory->newWorker() with different task queue names or configurations.
HTTP endpoints with RoadRunner server setup
You can serve HTTP endpoints using the same RoadRunner server setup alongside Temporal Worker configuration.
Provide API key to RoadRunner for Temporal Cloud
To provide an API key to RoadRunner when creating WorkerFactory for Temporal Cloud, use ServiceCredentials DTO. Example: $workerFactory = \Temporal\WorkerFactory::create(credentials: ServiceCredentials::create()->withApiKey('your-api-key'));
Start Worker primary loop
After registering workflow and activity types, start the worker primary loop using $factory->run().
Worker type registration consistency across Task Queue
All Workers listening to the same Task Queue name must be registered to handle the exact same Workflow Types and Activity Types.
Task failure when Worker lacks required type
If a Worker polls a Task for a Workflow Type or Activity Type it does not know about, it fails that Task. However, the failure of the Task does not cause the associated Workflow Execution to fail.
Register Activity with dependency injection factory
If an activity class requires external dependencies, provide a callback factory that creates or builds a new activity instance. The factory should be a callable which accepts an instance of ReflectionClass with the activity class to be created. Example: $worker->registerActivity(App\DemoActivity::class, fn(ReflectionClass $class) => $container->create($class->getName()));
Configure Task Queue name for Worker
Configure the task queue name by passing it as the first argument to WorkerFactory->newWorker(). Example: $worker = $factory->newWorker('your-task-queue');
Create Worker with WorkerFactory in PHP
To create a worker in PHP, use Temporal\WorkerFactory. The factory initiates and runs task queue specific activity and workflow workers. Example: $factory = WorkerFactory::create(); $worker = $factory->newWorker();
Worker Entity contains Workflow Worker and/or Activity Worker
A Worker Entity contains a Workflow Worker and/or an Activity Worker. The Workflow Worker makes progress on Workflow Executions, while the Activity Worker makes progress on Activity Executions.
RoadRunner application server with PHP Worker processes
The RoadRunner application server launches multiple Temporal PHP Worker processes based on provided .rr.yaml configuration. Each Worker might connect to one or multiple Task Queues.
Worker polling and task communication
Workers poll the Temporal Service for tasks, perform those tasks, and communicate task execution results back to the Temporal Service.
Register Workflow Types in PHP Worker
Workflows are stateful and require a type to create instances. Register workflow types using $worker->registerWorkflowTypes() with the workflow class name. Example: $worker->registerWorkflowTypes(App\DemoWorkflow::class);
Worker Entity definition and relationship to Task Queue
A Worker Entity is a component within a Worker Process that listens to a specific Task Queue. Each Worker Entity must register the exact Workflow Types and Activity Types it may execute. Each Worker Entity must associate itself with exactly one Task Queue. Multiple Worker Entities can exist in a single Worker Process, but a single Worker Entity per Worker Process may be sufficient. Each Worker Entity polling the same Task Queue must be registered with the same Workflow Types and Activity Types.
Register Activity in PHP Worker
Activities are stateless and thread safe, so a shared instance is used. Register activities using $worker->registerActivity() with the activity class name. Example: $worker->registerActivity(App\DemoActivity::class);
Worker setup for Standalone Activities
Example Worker setup for Standalone Activities: Create Worker with client, task_queue='my-standalone-activity-task-queue', activities=[compose_greeting], activity_executor=ThreadPoolExecutor(5). Requires ClientConfig.load_client_connect_config() to load connection config from environment variables or TOML files, with default target_host='localhost:7233'.
Configure Worker with ThreadPoolExecutor for synchronous Activities
When running synchronous Activities, the Worker needs to have an activity_executor. Temporal recommends using a ThreadPoolExecutor:
```python
with ThreadPoolExecutor(max_workers=42) as executor:
worker = Worker(
# ...
activity_executor=executor,
# ...
)
```
Separate Activity and Workflow Workers reduces blocking risk
Some users choose to deploy separate Workers for Workflow Tasks and Activity Tasks to reduce the risk of event loops or executors getting blocked.
Python SDK Worker execution architecture components
Python workers have three components: your event loop which runs Tasks from async Activities plus the rest of the Temporal Worker such as communicating with the server; an executor for executing Activity Tasks from synchronous Activities (a thread pool executor is recommended); and a thread pool executor for executing Workflow Tasks.
Ways to use multiple CPU cores in Python Worker
The only ways to use more than one core in a Python Worker, considering Python's GIL, are: run more than one Worker Process, or run synchronous Activities in a process pool executor (though a thread pool executor is recommended).
Temporal Client in Python SDK
The Python SDK provides a Temporal Client for implementing client functionality. The client is documented in the develop/python/client/temporal-client section.
Workers section in Python SDK documentation
The Workers section of the Python SDK documentation covers two main topics: worker processes and interceptors.
Worker processes documentation
The Python SDK documentation includes a page on worker processes located at /develop/python/workers/run-worker-process.
Interceptors documentation
The Python SDK documentation includes a page on interceptors located at /develop/python/workers/interceptors.
Install Temporal CLI on Linux
On Linux, download the Temporal CLI archive for your architecture (amd64 or arm64) from temporal.download/cli/archive/latest, extract the archive, and move the temporal binary into your PATH using a command like `sudo mv temporal /usr/local/bin`.
Install Temporal CLI on macOS
On macOS, install Temporal CLI using Homebrew with the command `brew install temporal`.
Create Worker with task queue and components
Create a Worker by instantiating the Worker class with a connected Client, a task_queue name, a list of workflows, and a list of activities. The Worker polls the task queue for work and executes Workflow and Activity tasks.
Python version requirement for Temporal SDK
The Temporal Python SDK requires Python 3.13.3 or compatible version. Check your Python version with the command `python3 -V`.
Example Worker setup in Python
```python
import asyncio
from temporalio.client import Client
from temporalio.worker import Worker
from temporalio import workflow
with workflow.unsafe.imports_passed_through():
from workflows import SayHelloWorkflow
from activities import greet
async def main():
client = await Client.connect("localhost:7233")
worker = Worker(
client,
task_queue="my-task-queue",
workflows=[SayHelloWorkflow],
activities=[greet],
)
print("Worker started.")
await worker.run()
if __name__ == "__main__":
asyncio.run(main())
```
This example shows how to create and start a Worker that connects to localhost:7233 and polls the my-task-queue task queue.
Worker role in Temporal applications
Workers are a crucial part of Temporal applications. A Worker polls a configured Task Queue looking for Workflow and Activity tasks, dequeues them, and executes them.
Install Temporal Python SDK using pip
Install the Temporal Python SDK with pip using the command `pip install temporalio`. Use a Python virtual environment for your project.
Connect to Temporal Service with Client.connect
Connect to a Temporal Service using `await Client.connect(address)` where address is the Temporal Service address. For a local development server, use "localhost:7233".
Temporal Web UI access
Access the Temporal Web UI to view Workflow Execution details. By default, the Web UI is available at http://localhost:8233 when running the development server.
Register interceptor on Worker
Pass interceptors in the interceptors argument of Worker() to register them on the Worker. Worker interceptors modify inbound and outbound Workflow and Activity calls. If your interceptor class inherits from both client.Interceptor and worker.Interceptor, pass it to Client.connect() rather than the Worker() constructor, as the Worker will use interceptors from its underlying Client automatically.
Worker with interceptors example code
worker = Worker(
client,
task_queue="my-task-queue",
interceptors=[SomeWorkerInterceptor()],
# ...
)
Worker interceptor implementation pattern
To modify inbound and outbound Workflow and Activity calls, define a class inheriting from worker.Interceptor. This interface has two methods named intercept_activity and workflow_interceptor_class, which you can use to configure interceptions of Activity and Workflow calls respectively. intercept_activity returns an ActivityInboundInterceptor, and workflow_interceptor_class returns a WorkflowInboundInterceptor.
Create and run a Worker in Python
To create a Worker in Python, instantiate a Worker with a Temporal Client, specify the task queue to poll, and provide lists of Workflows and Activities it can execute. Call `await worker.run()` to start polling. The run() method does not return on its own; it polls until shutdown() is called.
Worker as async context manager in Python
A Worker in Python is an async context manager that can be used with `async with worker:` syntax. This automatically starts the Worker on entry and shuts it down on exit, eliminating the need to manually call shutdown().
Worker configuration options in Python
The Worker constructor accepts keyword arguments that control concurrency limits, pollers, timeouts, and caching. Key options include `max_concurrent_activities`, `max_concurrent_workflow_tasks`, and `max_cached_workflows`. The defaults work for most cases. To tune these values against real load, see Worker performance and the Worker tuning reference.