How Temporal works
In a Temporal application, the Client, Server, and Worker are three separate parts that talk to each other and each one has a clear purpose. To understand the internal mechanics of Temporal, it helps to follow what happens when you start a Workflow or schedule Tasks.
Relationship between the Client, Server, and Worker
Server
The Temporal Server is a group of backend services that together form the core Temporal system. It exposes a Frontend Service, which is the network API that everything else connects to, and backend services like the History Service, which keeps the full Event History and state for each Workflow Execution, and the Matching Service, which manages Task Queues that hold pending work items for Workers.
All of this state is written to a database, so the Server can remember what has happened even if processes or machines fail. You can run the Server yourself (self‑hosted cluster) or use Temporal Cloud, which is the same kind of service but operated for you.
Client
A Temporal Client is a library object from a Temporal SDK that your application code uses to talk to the Temporal Server's Frontend. It opens a network connection (using gRPC) to the Server and sends requests like "start this Workflow with these inputs", "cancel this Workflow", "send this Signal to a running Workflow", "run this Query on a Workflow", or "get the result of this Workflow".
The Client does not run Workflow or Activity code; it only sends and receives these control requests. This is important because it gives your existing services, CLIs, or UIs a simple and consistent way to interact with Temporal without knowing anything about how Tasks, Task Queues, or Event histories are implemented inside the Server.
Worker
A Worker is a long‑running process that you run on your own machines, built with a Temporal SDK, and it is the part that actually executes your Workflow and Activity code. The Worker connects to the Server and polls Task Queues managed by the Matching Service to ask "do you have work for me?".
When it receives a Workflow Task, it replays the Workflow's event history and runs your Workflow code until it either completes or reaches a point where it must wait (for example, waiting for an Activity or a Timer). It then sends Commands back to the Server that describe what should happen next, such as "schedule this Activity" or "start this Timer".
When it receives an Activity Task, it calls your Activity function or method and then sends the outcome (success or failure and any additional result data) back to the Server, which records this as Events in the Event history. Temporal explicitly does not run your Workflow or Activity code inside the Server; that code only runs in Workers, which are under your control.
The Server records all state and creates Workflow and Activity Tasks in Task Queues. Workers poll those queues, run your Workflow and Activity code, and send back Commands and results. The Server uses this information to update the Event history so that any Client can later read the current status or the final result, and execution can safely continue (or replay) even if individual Worker processes or machines fail.
This is the heart of how durable execution works.
Example of the End-to-End Lifecycle of a Workflow or Activity
Here's a fifteen step process involving the end to end lifecycle of a Workflow and Activity.
Interactive demo
Temporal Architecture: 15-Step Lifecycle
Interactive visualization of how the Client, Frontend Service, History Service, Matching Service, Workers, and Database collaborate to execute Workflows and Activities.
Client requests Workflow start
Your application calls StartWorkflowExecution on the Temporal API (gRPC) exposed by the Frontend Service.
How to use: Click through the steps to see how each component in Temporal interacts during a Workflow and Activity execution. The diagram highlights which components are communicating in each step.
Workflow lifecycle
Step 1: The Temporal Client asks Temporal to start a Workflow
Your application calls StartWorkflowExecution on the Temporal API (gRPC) exposed by the Frontend Service. The request includes the Workflow type (which Workflow function/class to run), Input arguments, and the Task Queue name. Frontend forwards the request to the History Service, which owns this Workflow Execution.
Step 2: The History Service creates the Workflow Execution
History creates a new Workflow Execution in the database and initializes its Event History with: WorkflowExecutionStarted and WorkflowTaskScheduled (to tell a Worker to run Workflow code). It also creates an internal Transfer Task telling the system to put a Workflow Task on the specified Task Queue.
Step 3: The Matching Service adds a Workflow Task to the Task Queue
A background queue processor in the History Service reads the Transfer Task and calls the Matching Service to AddWorkflowTask for that Task Queue. The Task Queue now has one pending Workflow Task for this Workflow Execution.
Step 4: A Worker polls for a Workflow Task
A Worker process (your code + SDK) is already polling that Task Queue using PollWorkflowTask via Frontend Service. The Frontend Service asks Matching for a task. The Matching Service picks this Workflow Task and tells the History Service that it was started. The History Service appends WorkflowTaskStarted to the Event History and returns the Workflow Task (plus history) to the Worker through Frontend.
Step 5: The Worker runs your Workflow code
The SDK replays the Event History to reconstruct logical Workflow state, then starts your Workflow function/method. The Workflow runs until either returns a result or until it needs to wait (for an Activity, timer, signal, etc.).
Step 6: Your Workflow asks for work via Commands
When your Workflow calls Temporal APIs (for example, "execute Activity"), the SDK records Commands like ScheduleActivityTask or StartTimer instead of executing them directly. When the Workflow cannot make more progress right now, the Worker sends RespondWorkflowTaskCompleted to Frontend, carrying the list of Commands and then the Frontend forwards this to History.
Step 7: The History Service turns Commands into Events and new Tasks
The History appends Events based on the Commands and updates state, for example: For ScheduleActivityTask: WorkflowTaskCompleted, then ActivityTaskScheduled. It then creates new internal tasks (Transfer/Timer tasks) and, through the queue processors, calls Matching to add Activity Tasks to Activity Task Queues or later add more Workflow Tasks when needed.
At this point, the Workflow is waiting on whatever it asked for (Activities, timers, etc.). When those complete, the Workflow will resume.
Activity lifecycle
Step 8: The Matching Service puts an Activity Task on the Activity Task Queue
For each ActivityTaskScheduled Event, a queue processor in History calls Matching to AddActivityTask on the corresponding Activity Task Queue.
Step 9: An Activity Worker polls and starts the Activity
A (possibly different) Worker is polling that Activity Task Queue using PollActivityTask via Frontend. Frontend asks Matching; Matching selects the Activity Task and notifies History that it has started. History appends ActivityTaskStarted and sets up any Activity timeout timers (for example, schedule-to-close). The Activity Task is then returned to the Worker via Frontend.
Step 10: Worker runs your Activity code
The Worker calls your Activity function/method with the inputs from the task. This code can do I/O, call external services, etc., because it is not replayed the same way as Workflow code.
Step 11: Activity reports success or failure
On success, the Worker sends RespondActivityTaskCompleted (with the result) to Frontend; Frontend forwards it to History. The History appends: ActivityTaskCompleted (including the result) and WorkflowTaskScheduled (to wake up the Workflow), and adds a Transfer Task to create the next Workflow Task.
On failure, the Worker sends RespondActivityTaskFailed; History appends ActivityTaskFailed and either will append a new ActivityTaskScheduled (for a retry), or leaves the failure to propagate to the Workflow, depending on retry settings.
Workflow resumes and finishes
Step 12: A new Workflow Task is scheduled
Because of the Activity completion (or other events like timers), History has appended Events and scheduled a new Workflow Task. A queue processor in History calls Matching to add that Workflow Task to the Workflow Task Queue.
Step 13: Worker picks up the next Workflow Task and continues
A Worker polls the Workflow Task Queue again (PollWorkflowTask). The Matching Service selects the task; the History Service appends WorkflowTaskStarted. The Worker receives the updated Event History via Frontend. The SDK replays the history, unblocks the waiting Activity or timer, and your Workflow code continues from this new state.
Step 14: Workflow eventually closes
This cycle (Workflow Task → Commands → Events → new Tasks) repeats as many times as needed. When the Workflow function/method returns a result, the Worker sends RespondWorkflowTaskCompleted with a CompleteWorkflowExecution command. The History Service appends WorkflowTaskCompleted and WorkflowExecutionCompleted and marks the Workflow Execution as closed. Workflows can also close via failure, cancellation, termination, or "continue-as-new," but in all cases they move from open to closed and do not reopen.
Step 15: The Client reads the result or status from the Frontend Service
While the Workflow is open, Clients can query it (read-only inspection of state) and send Signals to it. After it is closed, a Client can request the final result or failure by calling the SDK, which talks to Frontend; the Frontend Service reads the necessary data from the History Service/Persistence Layer and returns it.