Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
2fa885e
Add self-hosted Nexus guidance for Global Namespace failover
stephanos Jul 17, 2026
4ac3d82
Update temporal-nexus.mdx
stephanos Jul 17, 2026
5cab211
Apply docs style pass and note split-active-Cluster failover
stephanos Jul 17, 2026
81c5e94
Refine failover section: target-types note and Vale fixes
stephanos Jul 17, 2026
16a8c65
Clarify forwarding config and avoid duplicating Multi-Cluster Replica…
stephanos Jul 17, 2026
f8db375
Link dcRedirectionPolicy to config reference; clarify clusterInformat…
stephanos Jul 17, 2026
b9b66c8
Update temporal-nexus.mdx
stephanos Jul 17, 2026
f0dfd7e
De-duplicate httpAddress step against Enable Nexus
stephanos Jul 17, 2026
1276f5e
Tighten failover behavior bullets
stephanos Jul 17, 2026
87d8e8e
Shorten the httpAddress configuration step
stephanos Jul 17, 2026
88f2f08
Update temporal-nexus.mdx
stephanos Jul 17, 2026
bd91b56
Drop operator cluster upsert caveat from httpAddress step
stephanos Jul 17, 2026
af98ee2
Update temporal-nexus.mdx
stephanos Jul 17, 2026
383a7a4
Elaborate auto-forwarding setting and fix failover diagram
stephanos Jul 17, 2026
e90c423
Fix mermaid parse error and soften auto-forwarding wording
stephanos Jul 17, 2026
70e982c
Fix cut-off note in failover diagram
stephanos Jul 17, 2026
030e6e3
Update temporal-nexus.mdx
stephanos Jul 17, 2026
628cb01
Replace failover sequence diagram with cluster/namespace topology
stephanos Jul 17, 2026
65a3a91
Show before/after failover states in the diagram
stephanos Jul 17, 2026
0853333
Use a sequence diagram with Cluster boxes for failover
stephanos Jul 17, 2026
c76f7ea
Add boom emoji to the failover note in the diagram
stephanos Jul 17, 2026
92a7ad7
Use full 'Namespace', HTML bold for active-Cluster notes, rename fina…
stephanos Jul 17, 2026
63eed47
Revert HTML bold in diagram notes (not rendered under strict mermaid)
stephanos Jul 17, 2026
29d8dc0
Shorten failover behavior bullets
stephanos Jul 17, 2026
4ae5112
Make failover bullets value-first
stephanos Jul 17, 2026
0ee8078
Update temporal-nexus.mdx
stephanos Jul 17, 2026
ff8096b
Update temporal-nexus.mdx
stephanos Jul 17, 2026
49cade2
Restore async-replication caveat and fix proper-noun casing
stephanos Jul 17, 2026
75fe1a4
Reframe abrupt-loss note as a warning admonition
stephanos Jul 17, 2026
41f7c06
Soften abrupt-loss note (warning to note, neutral wording)
stephanos Jul 17, 2026
01a3064
Update temporal-nexus.mdx
stephanos Jul 17, 2026
9b62220
Fold callback-delivery detail into the failover lead-in
stephanos Jul 17, 2026
1dee3a4
Show a failed callback attempt and retry in the diagram
stephanos Jul 17, 2026
29c41c3
Clarify forwarding: Nexus vs client-API paths; drop selected-apis-for…
stephanos Jul 17, 2026
b2e663d
Update temporal-nexus.mdx
stephanos Jul 17, 2026
e42e4f9
Demote dcRedirectionPolicy to optional in forwarding step
stephanos Jul 17, 2026
3c2a9dc
Update temporal-nexus.mdx
stephanos Jul 17, 2026
7dd7098
Update temporal-nexus.mdx
stephanos Jul 17, 2026
62a080e
Update temporal-nexus.mdx
stephanos Jul 17, 2026
b40a311
Update temporal-nexus.mdx
stephanos Jul 17, 2026
3d71d3e
Update temporal-nexus.mdx
stephanos Jul 17, 2026
9d37e2f
Update temporal-nexus.mdx
stephanos Jul 17, 2026
7f04fe6
Update temporal-nexus.mdx
stephanos Jul 17, 2026
4f8ffe6
Use a flowchart with Cluster subgraphs for the failover diagram
stephanos Jul 17, 2026
92b3a52
Give the mermaid linter a DOM so it can parse sequence box
stephanos Jul 17, 2026
d2e20f4
Restore sequence box failover diagram; note selected-apis-forwarding
stephanos Jul 17, 2026
f7576ed
Update temporal-nexus.mdx
stephanos Jul 17, 2026
668317e
Update temporal-nexus.mdx
stephanos Jul 17, 2026
80a3e42
Use global-jsdom for the mermaid linter DOM setup
stephanos Jul 17, 2026
05e3d32
Update temporal-nexus.mdx
stephanos Jul 17, 2026
ff720fd
Clarify the advertise-httpAddress step
stephanos Jul 17, 2026
6ee1921
Reword step 2 so the reader is the actor, not the section
stephanos Jul 17, 2026
251345f
Update temporal-nexus.mdx
stephanos Jul 17, 2026
87a5226
Update temporal-nexus.mdx
stephanos Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 67 additions & 6 deletions docs/production-deployment/self-hosted-guide/temporal-nexus.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
id: nexus
title: Self-hosted Temporal Nexus
sidebar_label: Temporal Nexus
description: Use Nexus in your self-hosted Temporal Service.
description: Use Nexus in your self-hosted Temporal Service, including across Global (multi-region) Namespaces.
toc_max_heading_level: 4
keywords:
- self-hosted
tags:
- Self hosting
- enable-nexus
- global-namespace
---

:::info NEW TO NEXUS?
Expand All @@ -21,11 +22,6 @@ This page explains how to self-host Nexus. To learn about Nexus, see the [how Ne

Nexus can be configured by setting static configuration and dynamic configuration entries.


:::note
Nexus is supported in single-cluster setups only. See [Nexus Architecture](https://github.com/temporalio/temporal/blob/main/docs/architecture/nexus.md) for operational details.
:::

:::note
Replace `$PUBLIC_URL` with a URL value that's accessible to external callers or internally within the cluster.
Currently, external Nexus calls are considered experimental so it should be safe to use the address of an internal load balancer for the Frontend Service.
Expand Down Expand Up @@ -91,3 +87,68 @@ See [how Nexus works](/nexus) for an architectural overview, then follow an SDK
[.NET](/develop/dotnet/nexus)

:::

## Global Namespaces (multi-region failover)

Nexus works across a [Global (multi-region) Namespace](/global-namespace). An
asynchronous Nexus Operation started in one Cluster completes even if the Namespace
fails over, or its Cluster is lost, before the Operation finishes.

:::note Endpoint target types

This applies to [Worker-target Endpoints](/nexus/endpoints), where the Endpoint
routes to a target Namespace and Task Queue that a Worker polls. Endpoints can also
target an external URL (`--target-url`), which is experimental and not covered here.

:::

### Configuration

1. **Set up Multi-Cluster Replication.** See
[Multi-Cluster Replication](/self-hosted-guide/multi-cluster-replication) for
connecting Clusters and creating replicated Namespaces.

2. **Advertise a frontend HTTP address on every Cluster.** Set
`frontend.rpc.httpPort` and `clusterInformation.<cluster>.httpAddress` (shown in
[Enable Nexus](#enable-nexus) for one Cluster) on **each** Cluster, each with its
own address, so the other Clusters can reach it to deliver callbacks.

3. **Register Endpoints on every Cluster.** The
[Nexus Endpoint registry](/nexus/registry) isn't replicated across Clusters.
Create the same Endpoints (same target Namespace and Task Queue) on **each** Cluster.

4. **Cross-Cluster forwarding.** Nexus request and callback forwarding is on by
default via `system.enableNamespaceNotActiveAutoForwarding` (per-Namespace
dynamic config).

Optionally, set the server's

@stephanos stephanos Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if this should be optional or recommended?

[`dcRedirectionPolicy`](/references/configuration#dcredirectionpolicy) so client
requests forward to the active Cluster when a client connects to a standby: use
`all-apis-forwarding` for all client APIs, or `selected-apis-forwarding` for a
fixed subset that includes `StartNexusOperationExecution` (used to start a
[Standalone Nexus Operation](/standalone-nexus-operation)).

### What to expect on failover

For a Nexus Operation started before a Cluster failover completes on the new active
Cluster, the completion callback is delivered to the caller Namespace's current
active Cluster, re-resolved on each attempt:

```mermaid
sequenceDiagram
box Cluster A
participant caA as Caller Namespace
participant haA as Handler Namespace
end
box Cluster B
participant caB as Caller Namespace
participant haB as Handler Namespace
end
Note over caA,haA: Cluster A active
caA->>haA: start Nexus Operation
haA-->>caA: Operation started, token returned
Note over caA,haB: 💥 Fail over both namespaces from Cluster A to B
Note over caB,haB: Cluster B active
haB->>caB: deliver completion callback
Note over caB: Nexus Operation completes
```
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"dprint": "^0.55.1",
"eslint": "^9.8.0",
"eslint-plugin-react": "^7.23.2",
"global-jsdom": "^29.0.0",
"husky": "^9.1.7",
"hyperlink": "^5.0.4"
}
Expand Down
24 changes: 6 additions & 18 deletions scripts/lint-mermaid.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Set up a browser-like DOM before loading mermaid. mermaid.parse() uses DOM
// APIs for some diagram syntaxes (for example a sequence diagram `box`) and
// otherwise fails headless with "window is not defined".
import 'global-jsdom/register';

@stephanos stephanos Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was needed to make the mermaid chart above work; the box is crucial to convey the topology clearly.


import fs from 'node:fs/promises';
import path from 'node:path';
import DOMPurify from 'dompurify';
import mermaidModule from 'mermaid';

const mermaid = mermaidModule.default ?? mermaidModule;
import mermaid from 'mermaid';
const DOCS_ROOT = path.resolve('docs');
const MARKDOWN_EXTENSIONS = new Set(['.md', '.mdx']);

Expand Down Expand Up @@ -109,20 +111,6 @@ async function lintFile(filePath) {
}

async function main() {
// Mermaid's parser may call DOMPurify hooks for some diagram syntaxes.
// In Node (without a browser window), dompurify can resolve to a minimal
// implementation that lacks hook APIs; provide no-op hooks so syntax-only
// parsing still works in CI.
if (typeof DOMPurify.addHook !== 'function') {
DOMPurify.addHook = () => {};
}
if (typeof DOMPurify.removeHook !== 'function') {
DOMPurify.removeHook = () => {};
}
if (typeof DOMPurify.sanitize !== 'function') {
DOMPurify.sanitize = (value) => value;
}

mermaid.initialize({ startOnLoad: false });

const markdownFiles = await walk(DOCS_ROOT);
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8098,6 +8098,11 @@ global-dirs@^3.0.0:
dependencies:
ini "2.0.0"

global-jsdom@^29.0.0:
version "29.0.0"
resolved "https://registry.yarnpkg.com/global-jsdom/-/global-jsdom-29.0.0.tgz#c7c7f51d58f8069d94563afb5d7b8cd34546d64e"
integrity sha512-S9Wl+EHDfkO8DYleqMYzf14hKfwIysEN/FvoVRdPif3uUGUlmiHs/gj1PVKXhmJ20DwUVACtdxxhNYYvvn9K7A==

globals@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
Expand Down