diff --git a/docs/encyclopedia/understanding-temporals-architecture.mdx b/docs/encyclopedia/understanding-temporals-architecture.mdx
new file mode 100644
index 0000000000..e4b5670273
--- /dev/null
+++ b/docs/encyclopedia/understanding-temporals-architecture.mdx
@@ -0,0 +1,128 @@
+---
+id: understanding-temporals-architecture
+title: Understanding Temporal's Architecture
+sidebar_label: Understanding Temporal's Architecture
+description: A technical deep dive into the Temporal platform architecture, covering the Temporal Service internals, end-to-end Workflow and Activity lifecycle, and how durable execution is achieved.
+toc_max_heading_level: 4
+keywords:
+ - temporal architecture
+ - temporal service
+ - history service
+ - matching service
+ - workflow lifecycle
+ - activity lifecycle
+ - durable execution
+ - event history
+ - temporal internals
+tags:
+ - Concepts
+ - Temporal Service
+---
+
+import { CaptionedImage, WorkflowLifecycleSequence } from "@site/src/components";
+
+This guide assumes familiarity with core Temporal concepts. It's recommended to read [Understanding Temporal](/evaluate/understanding-temporal) first, along with having a basic understanding of [Workflows](/workflows), [Activities](/activities), [Workers](/workers), [Task Queues](/task-queue), and [Event History](/encyclopedia/event-history/).
+
+Temporal is a tool that abstracts away a lot of difficulty for anyone managing applications that need to be resilient to failures. This guide provides a high-level overview of how Temporal works under the hood.
+
+## Application structure recap
+
+Before diving into the architecture, let's recap what you're responsible for as a developer.
+
+As a developer, you are responsible for the Temporal Application code, which includes writing the Activity Definition, Workflow Definition, and the code to configure and start the Workers that coordinate with a Temporal Service to execute your Workflow and Activity code.
+
+As part of the Temporal Platform, we also have the Temporal Service, which runs the Temporal Server with its database and optional components, and is responsible for orchestrating execution. A Temporal application gains its durability, scalability, and reliability from the support provided by the Temporal Service.
+
+## Overall architecture
+
+
+
+## Client application
+
+A Temporal Client is one aspect of your Temporal application and is provided by a Temporal SDK. It offers a set of APIs to communicate with a Temporal Service. You instantiate and use it in your own application code to start and manage Workflow Executions.
+
+Consider the example of an order processing system. A Temporal Client lets you:
+
+- **Start** a Workflow Execution, for example, when a customer places an order.
+- **Signal** a Workflow Execution to update the order if the customer changes their shipping address.
+- **Query** a Workflow Execution to retrieve the current status of the order.
+- **List** Workflow Executions to view all orders being processed or that have been completed.
+- **Get the result** of a Workflow Execution to retrieve the final outcome of the order processing.
+- **Manage** Workflow Executions by canceling, terminating, or describing them when needed.
+
+In the wider platform, there are three kinds of clients that talk to the Temporal Server:
+
+- Temporal's command-line interface (CLI)
+- Temporal's web-based user interface (Web UI)
+- A Temporal Client embedded into the applications you run
+
+## The Temporal Server
+
+The Temporal Server is the heart of the platform. It's responsible for orchestrating Workflow Execution, maintaining state, and ensuring reliability.
+
+The Temporal Server consists of a frontend and multiple backend services, plus a database as a required external component. A Temporal Server may also include optional components, such as Elasticsearch for advanced search visibility or Grafana for operational dashboards and observability.
+
+### Frontend Service
+
+From your application's perspective, the Frontend Service is the Temporal endpoint your Temporal Client talks to. Your client sends requests (start Workflow, Signal, Query, etc.) to the Frontend, and the Frontend forwards them to the appropriate backend services.
+
+It handles rate limiting, authorization, validation, and routing requests internally to the right subsystem. Clients never communicate directly with backend services or Workers; everything goes through this unified entry point.
+
+### Temporal Service backend
+
+
+
+The backend consists of several specialized services: the History Service, Matching Service, Worker Service, and a Persistence Layer.
+
+#### History Service
+
+The History Service is a central part of how Temporal provides durable execution. It keeps track of everything that happens in each Workflow by writing an ordered Event History to the database, so Temporal always knows what has happened. This includes when a Workflow started, Activities ran, Signals were received, timers fired, and when it completed or failed. Overall, the History Service persists all Workflow Execution state, including the Event History, any mutable state, and internal task queues like timers, transfers, replication, and visibility/indexing.
+
+The Event History is the key to making your application reliable and crash-proof. When an error or failure happens in your app, Temporal will recreate the state by parsing the Event History and replaying each step. That's why determinism and idempotency are important when creating your Workflows.
+
+#### Matching Service
+
+The Matching Service manages most of the coordination between other services, especially Task Queues and Task Queue partitions. This is where Tasks are dispatched to their respective queues before being picked up by the corresponding Workers. Worker polling also takes place here, allowing the service to determine how many more Tasks should be sent to a Worker from a Task Queue.
+
+When a Workflow Task or Activity Task needs to be executed, the Matching Service finds an appropriate Worker polling the queue and hands off the task.
+
+#### Worker Service
+
+The Worker Service handles all of the background functionality that keeps the Temporal Service running smoothly, including internal Workflows, maintenance jobs, cleanup, replication, archival, and visibility indexing. This is different from your application Workers. You won't interact with this layer directly; the Worker Service handles Temporal's own operational tasks, like archiving old Workflow histories or running scheduled maintenance.
+
+#### Persistence Layer
+
+You can configure the database used to store Workflow state, Event History, and Task Queues. Supported options include Cassandra, MySQL, PostgreSQL, and SQLite. This is also where metadata about your Workflows and other data needed for durable execution is stored. This persistence enables recovery and replay: if anything fails, Temporal can reconstruct the exact state of a Workflow from its Event History.
+
+### External services
+
+External services are anything outside of your own application code and outside Temporal itself, such as third-party APIs, databases that store customer data, or messaging systems.
+
+Temporal can also integrate with Elasticsearch to provide advanced search and visibility capabilities for Workflow Executions. Without it, you're limited to basic filtering. Grafana can be used to enable operational dashboards and monitoring for the Temporal Service itself.
+
+## Infrastructure (Worker processes)
+
+This is where the code for your Workers, Workflows, Activities, Signals, Updates, and Queries gets executed on your own infrastructure. This is also where you scale up the number of Workers to increase how many Workflows can run simultaneously.
+
+Your Workflow code is the orchestration layer that defines the structure of your application. It needs to be deterministic so Temporal can help your app survive process crashes, outages, and other failures.
+
+Your Activities are where the actual work happens: invoking tools, making API requests, calling third-party services. These can be as unpredictable and non-deterministic as needed.
+
+That's what makes Temporal so valuable for long-running Workflows. When your Workflow involves multiple steps (calling an endpoint, waiting on customer input, triggering an event based on that input, calling a third-party service, updating the database, sending info to the customer, sending info to an internal user, calling a different endpoint), any of those steps could fail. Durable execution means that Temporal will recreate the chain of events leading up to the failure and resume forward from that point.
+
+## End-to-end lifecycle of a Workflow and Activity
+
+The following sections walk through the complete lifecycle of a Workflow Execution, from the initial client call through Activity completion and final result retrieval.
+
+
+
+## Next steps
+
+- **Developer Guides**: Step-by-step guides for writing Workflows, Activities, and configuring Workers
+- **Temporal Courses**: Structured, in-depth learning paths covering core concepts and best practices
diff --git a/sidebars.js b/sidebars.js
index 8e0c9b5a75..496ed3630a 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -1437,6 +1437,7 @@ module.exports = {
items: [
'encyclopedia/temporal',
'encyclopedia/temporal-sdks',
+ 'encyclopedia/understanding-temporals-architecture',
{
type: 'category',
label: 'Workflows',
diff --git a/src/components/elements/WorkflowLifecycleSequence.js b/src/components/elements/WorkflowLifecycleSequence.js
new file mode 100644
index 0000000000..527e13187c
--- /dev/null
+++ b/src/components/elements/WorkflowLifecycleSequence.js
@@ -0,0 +1,573 @@
+import React, { useState, useEffect, useRef, useCallback } from 'react';
+
+// ── Brand colors ──────────────────────────────────────────────────────────────
+const C = {
+ bg: '#141414',
+ surface: '#1c1c2e',
+ surfaceAlt: '#1e1e2e',
+ border: '#2a2a40',
+ blue: '#444CE7',
+ green: '#1ff1a5',
+ indigo: '#cacbf9',
+ muted: '#576e8f',
+ dim: '#374761',
+ text: '#F8FAFC',
+ textSub: '#9ca3af',
+};
+
+// ── Actor definitions ─────────────────────────────────────────────────────────
+const ACTORS = [
+ { name: 'Your App', sub: 'Client / SDK', color: C.blue },
+ { name: 'Frontend', sub: 'Service', color: C.blue },
+ { name: 'History', sub: 'Service', color: C.blue },
+ { name: 'Matching', sub: 'Service', color: C.blue },
+ { name: 'Worker', sub: 'Your Infrastructure', color: C.green },
+];
+
+// ── Phase definitions ─────────────────────────────────────────────────────────
+const PHASES = [
+ { id: 'workflow', label: 'Workflow Lifecycle', color: C.blue, steps: [0,1,2,3,4,5,6] },
+ { id: 'activity', label: 'Activity Lifecycle', color: C.green, steps: [7,8,9,10] },
+ { id: 'resume', label: 'Resume & Close', color: C.indigo, steps: [11,12,13,14] },
+];
+
+// ── Step data ─────────────────────────────────────────────────────────────────
+// Each arrow: { from, to } — indices into ACTORS (0–4)
+// selfLoop: true → draw a loopback arc on that actor
+const STEPS = [
+ {
+ id: 1,
+ phase: 'workflow',
+ title: 'Client sends StartWorkflowExecution',
+ description: 'Your application calls StartWorkflowExecution on the Temporal gRPC API. The request carries the Workflow type, input arguments, and the Task Queue name. The Frontend Service validates and rate-limits the call, then routes it to the History Service, which will own and track this Workflow Execution.',
+ arrows: [
+ { from: 0, to: 1, label: 'StartWorkflowExecution' },
+ { from: 1, to: 2, label: 'route to History' },
+ ],
+ events: [],
+ },
+ {
+ id: 2,
+ phase: 'workflow',
+ title: 'History initializes the Workflow Execution',
+ description: 'The History Service creates a new Workflow Execution record in the database and starts the Event History with two events: WorkflowExecutionStarted (capturing all inputs) and WorkflowTaskScheduled (signaling that a Worker needs to run). It also creates an internal Transfer Task telling the system to enqueue a Workflow Task.',
+ arrows: [
+ { from: 2, to: 2, label: 'persist + init Event History', selfLoop: true },
+ ],
+ events: ['WorkflowExecutionStarted', 'WorkflowTaskScheduled'],
+ },
+ {
+ id: 3,
+ phase: 'workflow',
+ title: 'Workflow Task is placed on the Task Queue',
+ description: 'A background queue processor inside the History Service reads the Transfer Task and calls the Matching Service to enqueue a Workflow Task for the specified Task Queue. The Task Queue now holds one pending task, waiting for a Worker to pick it up.',
+ arrows: [
+ { from: 2, to: 3, label: 'AddWorkflowTask' },
+ ],
+ events: [],
+ },
+ {
+ id: 4,
+ phase: 'workflow',
+ title: 'Worker polls and receives the Workflow Task',
+ description: 'A Worker process is already long-polling the Task Queue via PollWorkflowTask. The Frontend forwards the poll to the Matching Service. Matching selects the pending task, notifies History (which appends WorkflowTaskStarted), and returns the Workflow Task plus the full Event History to the Worker through the Frontend.',
+ arrows: [
+ { from: 4, to: 1, label: 'PollWorkflowTask (long-poll)' },
+ { from: 1, to: 3, label: 'forward to Matching' },
+ { from: 2, to: 1, label: 'WorkflowTask + Event History' },
+ { from: 1, to: 4, label: 'deliver task to Worker' },
+ ],
+ events: ['WorkflowTaskStarted'],
+ },
+ {
+ id: 5,
+ phase: 'workflow',
+ title: 'Worker replays history and runs your Workflow code',
+ description: 'The SDK replays the Event History to reconstruct the Workflow\'s logical state — this is the cornerstone of durable execution. After replay, it executes your Workflow function. The Workflow runs until it either returns or reaches an await point (waiting for an Activity, timer, or Signal).',
+ arrows: [
+ { from: 4, to: 4, label: 'replay history → execute Workflow code', selfLoop: true },
+ ],
+ events: [],
+ },
+ {
+ id: 6,
+ phase: 'workflow',
+ title: 'Workflow issues Commands back to History',
+ description: 'When your Workflow calls a Temporal API (e.g. executeActivity), the SDK records a Command — like ScheduleActivityTask — instead of executing it immediately. Once the Workflow can make no more progress, the Worker sends RespondWorkflowTaskCompleted carrying the list of Commands to the Frontend, which forwards them to History.',
+ arrows: [
+ { from: 4, to: 1, label: 'RespondWorkflowTaskCompleted + Commands' },
+ { from: 1, to: 2, label: 'forward Commands' },
+ ],
+ events: [],
+ },
+ {
+ id: 7,
+ phase: 'workflow',
+ title: 'History converts Commands into Events and new Tasks',
+ description: 'History turns each Command into durable Events — appending WorkflowTaskCompleted and ActivityTaskScheduled. It then creates Transfer Tasks, which queue processors use to call the Matching Service and place Activity Tasks on the Activity Task Queue. The Workflow is now suspended, waiting for the Activity to complete.',
+ arrows: [
+ { from: 2, to: 3, label: 'AddActivityTask (via queue processor)' },
+ ],
+ events: ['WorkflowTaskCompleted', 'ActivityTaskScheduled'],
+ },
+ {
+ id: 8,
+ phase: 'activity',
+ title: 'Activity Task queued in Matching',
+ description: 'For each ActivityTaskScheduled event, a queue processor in the History Service calls the Matching Service to add an Activity Task to the Activity Task Queue. The task waits here until an Activity Worker polls for it.',
+ arrows: [
+ { from: 2, to: 3, label: 'AddActivityTask' },
+ ],
+ events: [],
+ },
+ {
+ id: 9,
+ phase: 'activity',
+ title: 'Worker polls and receives the Activity Task',
+ description: 'A Worker (possibly a different host from the Workflow Worker) long-polls the Activity Task Queue via PollActivityTask. Matching selects the task, History appends ActivityTaskStarted and sets up timeout timers (schedule-to-close, start-to-close). The Activity Task and its inputs are returned to the Worker via the Frontend.',
+ arrows: [
+ { from: 4, to: 1, label: 'PollActivityTask (long-poll)' },
+ { from: 1, to: 3, label: 'forward to Matching' },
+ { from: 2, to: 1, label: 'ActivityTask + inputs' },
+ { from: 1, to: 4, label: 'deliver task to Worker' },
+ ],
+ events: ['ActivityTaskStarted'],
+ },
+ {
+ id: 10,
+ phase: 'activity',
+ title: 'Worker executes your Activity code',
+ description: 'The Worker calls your Activity function with the inputs from the task. Unlike Workflow code, Activity code is never replayed — it can perform I/O, call external APIs, write to databases, or do anything non-deterministic. This is where the real work of your application happens.',
+ arrows: [
+ { from: 4, to: 4, label: 'execute Activity code (I/O, APIs, side effects)', selfLoop: true },
+ ],
+ events: [],
+ },
+ {
+ id: 11,
+ phase: 'activity',
+ title: 'Activity reports result to History',
+ description: 'On success, the Worker sends RespondActivityTaskCompleted with the result. On failure, it sends RespondActivityTaskFailed. History appends ActivityTaskCompleted (or ActivityTaskFailed) and either schedules a retry or appends WorkflowTaskScheduled to wake the waiting Workflow. The Activity\'s lifecycle is now complete.',
+ arrows: [
+ { from: 4, to: 1, label: 'RespondActivityTaskCompleted (result)' },
+ { from: 1, to: 2, label: 'forward result' },
+ ],
+ events: ['ActivityTaskCompleted', 'WorkflowTaskScheduled'],
+ },
+ {
+ id: 12,
+ phase: 'resume',
+ title: 'New Workflow Task scheduled for resume',
+ description: 'Because the Activity completed, History has appended new events and scheduled a fresh Workflow Task. A queue processor calls the Matching Service to add this task to the Workflow Task Queue. The Workflow is about to wake up.',
+ arrows: [
+ { from: 2, to: 3, label: 'AddWorkflowTask (resume)' },
+ ],
+ events: [],
+ },
+ {
+ id: 13,
+ phase: 'resume',
+ title: 'Worker resumes the Workflow',
+ description: 'A Worker polls the Workflow Task Queue again. History appends WorkflowTaskStarted and returns the updated Event History. The SDK replays the history up to the current point, unblocks the awaited Activity call with its result, and your Workflow function continues executing from the new state.',
+ arrows: [
+ { from: 4, to: 1, label: 'PollWorkflowTask' },
+ { from: 2, to: 4, label: 'updated Event History' },
+ ],
+ events: ['WorkflowTaskStarted'],
+ },
+ {
+ id: 14,
+ phase: 'resume',
+ title: 'Workflow closes',
+ description: 'The cycle — Workflow Task → Commands → Events → new Tasks — repeats until the Workflow function returns. The Worker sends CompleteWorkflowExecution. History appends WorkflowTaskCompleted and WorkflowExecutionCompleted, permanently closing the execution. A Workflow can also close via failure, cancellation, termination, or Continue-As-New.',
+ arrows: [
+ { from: 4, to: 1, label: 'RespondWorkflowTaskCompleted + CompleteWorkflowExecution' },
+ { from: 1, to: 2, label: 'forward' },
+ ],
+ events: ['WorkflowTaskCompleted', 'WorkflowExecutionCompleted'],
+ },
+ {
+ id: 15,
+ phase: 'resume',
+ title: 'Client retrieves the final result',
+ description: 'While a Workflow is open, Clients can Query it (read-only state) and send Signals to it. After it closes, a Client requests the result via the SDK. The SDK calls the Frontend, which reads the result from the History Service and Persistence Layer, and returns it to your application.',
+ arrows: [
+ { from: 0, to: 1, label: 'GetWorkflowResult' },
+ { from: 1, to: 2, label: 'read from Persistence' },
+ { from: 1, to: 0, label: 'final result' },
+ ],
+ events: [],
+ },
+];
+
+// ── SVG layout constants ──────────────────────────────────────────────────────
+const SVG_W = 700;
+const ACTOR_X = [54, 189, 336, 483, 630];
+const ACTOR_BOX_W = 92;
+const ACTOR_BOX_H = 46;
+const LIFELINE_TOP = ACTOR_BOX_H;
+const SVG_PADDING_BOTTOM = 16;
+
+function getArrowYs(count) {
+ if (count === 1) return [110];
+ if (count === 2) return [88, 128];
+ if (count === 3) return [76, 108, 140];
+ return [68, 96, 124, 152];
+}
+
+function getSvgHeight(arrowCount) {
+ const ys = getArrowYs(arrowCount);
+ return Math.max(180, ys[ys.length - 1] + SVG_PADDING_BOTTOM + 30);
+}
+
+// ── Arrow SVG element ─────────────────────────────────────────────────────────
+function Arrow({ from, to, label, y, animKey, phaseColor, selfLoop, index }) {
+ const x1 = ACTOR_X[from];
+ const x2 = ACTOR_X[to];
+ const animId = `arrow-${animKey}-${index}`;
+ const delay = `${index * 0.18}s`;
+
+ if (selfLoop) {
+ const markerId = `ah-sl-${animKey}-${index}`;
+ const center = x1 + ACTOR_BOX_W / 2;
+ // Rightmost actor (Worker) loops left so it stays in-bounds; all others loop right
+ const goLeft = from === ACTORS.length - 1;
+ const loopX = goLeft ? center - 56 : center + 56;
+ const textX = goLeft ? loopX - 6 : loopX + 6;
+ const pathD = `M ${center} ${y - 10} Q ${loopX} ${y - 10} ${loopX} ${y} Q ${loopX} ${y + 10} ${center} ${y + 10}`;
+ return (
+
+
+
+
+
+
+
+ {label}
+
+ );
+ }
+
+ const goingRight = x2 > x1;
+ const startX = goingRight ? x1 + ACTOR_BOX_W / 2 : x1 + ACTOR_BOX_W / 2;
+ const endX = goingRight ? x2 + ACTOR_BOX_W / 2 : x2 + ACTOR_BOX_W / 2;
+ const midX = (startX + endX) / 2;
+ const lineLen = Math.abs(endX - startX);
+
+ return (
+
+
+
+
+
+
+
+
+ {label}
+
+
+ );
+}
+
+// ── Main component ────────────────────────────────────────────────────────────
+export default function WorkflowLifecycleSequence() {
+ const [stepIdx, setStepIdx] = useState(0);
+ const [animKey, setAnimKey] = useState(0);
+ const [playing, setPlaying] = useState(false);
+ const timerRef = useRef(null);
+
+ const step = STEPS[stepIdx];
+ const phase = PHASES.find(p => p.id === step.phase);
+
+ const activeSet = new Set(step.arrows.flatMap(a => [a.from, a.to]));
+
+ const goTo = useCallback((idx) => {
+ setStepIdx(idx);
+ setAnimKey(k => k + 1);
+ }, []);
+
+ const next = useCallback(() => { if (stepIdx < STEPS.length - 1) goTo(stepIdx + 1); }, [stepIdx, goTo]);
+ const prev = useCallback(() => { if (stepIdx > 0) goTo(stepIdx - 1); }, [stepIdx, goTo]);
+
+ useEffect(() => {
+ if (playing) {
+ timerRef.current = setInterval(() => {
+ setStepIdx(idx => {
+ if (idx >= STEPS.length - 1) {
+ setPlaying(false);
+ clearInterval(timerRef.current);
+ return idx;
+ }
+ setAnimKey(k => k + 1);
+ return idx + 1;
+ });
+ }, 2800);
+ } else {
+ clearInterval(timerRef.current);
+ }
+ return () => clearInterval(timerRef.current);
+ }, [playing]);
+
+ // Keyboard navigation
+ useEffect(() => {
+ const handler = (e) => {
+ if (e.key === 'ArrowRight') next();
+ if (e.key === 'ArrowLeft') prev();
+ if (e.key === ' ') { e.preventDefault(); setPlaying(p => !p); }
+ };
+ window.addEventListener('keydown', handler);
+ return () => window.removeEventListener('keydown', handler);
+ }, [next, prev]);
+
+ const arrowYs = getArrowYs(step.arrows.length);
+ const svgH = getSvgHeight(step.arrows.length);
+
+ return (
+