Temporal gives you flexibility to define different task queues to route workflows and activities to specific workers. When a worker starts up, it is configured to consume from a specific task queue by name, along with the activities and workflows it is capable of running.

For example:

import asyncio import concurrent.futures from activities import my_good_activity from temporalio.client import Client from temporalio.worker import Worker from workflows import MyGoodWorkflow async def main(): client = await Client(...) with concurrent.futures.ThreadPoolExecutor(max_workers=100) as activity_executor: worker = Worker( client, task_queue="my-task-queue", workflows=[MyGoodWorkflow], activities=[my_good_activity], activity_executor=activity_executor, ) await worker.run() if __name__ == "__main__": print("Starting worker") asyncio.run(main())

Let’s say we wanted to execute the workflows using one task queue and the activities with another. We could write two separate workers, like this.

For workflows:

import asyncio import concurrent.futures from temporalio.client import Client from temporalio.worker import Worker from workflows import MyGoodWorkflow async def main(): client = await Client(...) worker = Worker( client, task_queue="my-workflow-task-queue", workflows=[MyGoodWorkflow], activities=[], ) await worker.run() if __name__ == "__main__": print("Starting workflow worker") asyncio.run(main())

For activities:

import asyncio import concurrent.futures from activities import my_good_activity from temporalio.client import Client from temporalio.worker import Worker async def main(): client = await Client(...) with concurrent.futures.ThreadPoolExecutor(max_workers=100) as activity_executor: worker = Worker( client, task_queue="my-activity-task-queue", workflows=[], activities=[my_good_activity], activity_executor=activity_executor, ) await worker.run() if __name__ == "__main__": print("Starting activity worker") asyncio.run(main())

If we run each of these workers independently

python -m run_workflow_worker
python -m run_activity_worker

now we can start a workflow and the two worker processes will execute the workflow and activity code:

import asyncio import uuid from temporalio.client import Client from workflows import MyGoodWorkflow, MyWorkflowGoodArgs async def main(): client = await Client(...) result = await client.execute_workflow( MyGoodWorkflow.run, MyWorkflowArgs( arg1="good", arg2="workflow", ), id=str(uuid.uuid4()), task_queue="my-workflow-task-queue", ) print(f"Workflow completed with result: {result}") if __name__ == "__main__": asyncio.run(main())

If we did it right, when we run a workflow, we can see each task queue show up separately in the Temporal UI.

Temporal UI showing different task queue names

Note: the Temporal samples-python has a multi-language example of this pattern using Python and Go.