What is Temporal Nexus?

Nexus lets different teams share Temporal workflows across team, namespace, region, and cloud boundaries — without exposing internal implementation details.

The core idea in one sentence:

Team A can call Team B's workflows like a typed API — with full durability, retries, and fault-tolerance built in — without needing access to Team B's namespace or knowing how their code works.

The Problem Nexus Solves

Without Nexus

Siloed Teams

Each team works in their own Temporal namespace. There's no clean way for the Payments team to trigger an action in the Fraud Detection team's workflow without tight coupling or shared credentials.

Teams either share namespaces (messy) or build fragile HTTP bridges (unreliable).

With Nexus

Modular & Safe

The Fraud Detection team publishes a Nexus Service with a clear contract. The Payments team calls it from their workflow like any other operation.

Nexus handles routing, retries, security, and observability automatically — across any boundary.

What It Looks Like

Team A — Payments
W
PaymentWorkflow
Caller Namespace
Calls fraud.v1/checkTransaction
Waits for result (sync or async)
Nexus Endpoint
Routes securely
Retries + Auth
Team B — Fraud Detection
S
Nexus Service: fraud.v1
Handler Namespace
W
FraudCheckWorkflow
Runs internally, result returned

Key Facts

Durability

Up to 60 Days

Async Nexus Operations can run for up to 60 days in Temporal Cloud. The caller workflow is suspended until the result arrives.

Reliability

At-Least-Once

Nexus Machinery retries failed operations automatically. Pair with workflow ID policies to get exactly-once semantics.

Security

Built-in Auth

mTLS encryption and namespace allowlists control who can call what. No API keys flying around in code.

Boundaries

Cross-Everything

Works across teams, namespaces, regions (AWS & GCP), and clouds — with the same developer experience everywhere.

The Four Building Blocks

Nexus has four key concepts. Understanding these unlocks everything else.

1

Nexus Endpoint

The address you publish and route through

Think of an Endpoint like a URL for your team's services. It's a named entry point registered in the Nexus Registry that routes requests to a specific namespace and task queue.

It's not a general HTTP proxy — it's specifically designed for Nexus, with built-in auth, retries, and observability.

Endpoint: fraud-detection-prod
Routes to: fraud-ns / fraud-task-queue
2

Nexus Service

The contract you publish for others to consume

A Service is a named collection of Nexus Operations — like an API interface. Multiple services can run in the same worker. Callers import the service definition to get type safety.

Example: fraud.v1 service exposes checkTransaction, flagUser, and getScore operations.

3

Nexus Operation

The individual action — sync or async

Synchronous operations complete in under 10 seconds. The result comes back in the same HTTP round-trip. Great for quick lookups, scoring, or validations.

Caller → [Nexus RPC] → Handler → result → Caller
Duration: milliseconds to <10 seconds

Asynchronous operations start a Workflow and return an operation token. The caller workflow is suspended. When the handler workflow completes, a callback delivers the result.

Caller → [start] → Handler starts Workflow → [operation token]
...time passes (up to 60 days)...
Handler Workflow completes → [callback] → Caller resumes
4

Nexus Registry

The directory of all Endpoints in your account

Scoped to your Temporal Cloud account or self-hosted cluster. Teams register Endpoints here. The Registry is the source of truth for endpoint discovery, access control, and audit logging.

fraud-detection-prod
kyc-verification-v2
notifications-global
+ register new

How a Nexus Call Works

Walk through the step-by-step lifecycle of a Nexus Operation. Choose sync or async.

Caller Workflow
payments-ns
Nexus Endpoint
Routing + Auth
Handler Worker
fraud-ns
[ready] Press "Run Demo" to start the animation

Built-in Reliability

Nexus protects callers from handler failures through automatic retries, circuit breaking, and cancellation propagation.

Circuit Breaker

If a handler returns 5 consecutive retryable errors, Nexus trips the circuit breaker for that caller↔endpoint pair. This prevents overloading a struggling handler with a flood of retries.

Closed
Normal operation
Open
Failing fast
Half-Open
Testing recovery
Consecutive Errors
0/5

Reliability Comparison

Feature Raw HTTP Call Nexus Operation
Automatic retries on transient failure Manual Built-in
Caller workflow survives worker restart No Yes (durable)
Circuit breaking Manual Automatic
Cancel propagates to handler No Yes
Cross-namespace auth DIY mTLS + Allowlists
Bi-directional observability links No Yes
Max operation duration Request timeout Up to 60 days

Cancellation Propagation

When the caller workflow is canceled, Nexus automatically propagates the cancel signal to any pending Nexus Operations. The handler workflow receives the cancel request and the caller gets a CanceledFailure result.

Cancel caller
→ Nexus Machinery →
Cancel pending ops
Cancel handler workflows

Note: Terminating a caller workflow abandons (does not cancel) pending operations.

Code Walkthrough

Here's what using Nexus actually looks like in TypeScript. Three steps: define, implement, call.

The service definition is the contract. Both teams share this — usually as a package.

// shared/fraud-service.ts (Team B publishes this)
import { defineNexusServiceContract, WorkflowHandle } from '@temporalio/nexus';

export interface CheckTransactionInput {
  transactionId: string;
  amount: number;
  userId: string;
}

export interface FraudCheckResult {
  approved: boolean;
  riskScore: number;
  reason?: string;
}

// This defines the "contract" both teams agree on
export const fraudService = defineNexusServiceContract({
  name: 'fraud.v1',
  operations: {
    // async: runs a full Workflow, can take hours
    checkTransaction: {
      input: WorkflowInput<CheckTransactionInput>,
      output: WorkflowHandle<FraudCheckResult>,
    },
    // sync: quick score lookup, <10 seconds
    getQuickScore: {
      input: SyncInput<{ userId: string }>,
      output: SyncOutput<{ score: number }>,
    }
  }
});

Team B implements the handler in their own worker — using their own workflows internally.

// fraud-team/worker.ts (Team B's implementation)
import { NexusWorker, NewWorkflowRunOperation, NewSyncOperation } from '@temporalio/nexus';
import { fraudService } from '../shared/fraud-service';

const fraudHandler = fraudService.implement({
  // Async: delegate to internal Workflow
  checkTransaction: NewWorkflowRunOperation({
    async start(input, ctx) {
      const client = ctx.getClient();
      // Team B starts their OWN workflow internally
      return await client.workflow.start(FraudCheckWorkflow, {
        args: [input],
        taskQueue: 'fraud-task-queue',
        workflowId: `fraud-${input.transactionId}`,
      });
    }
  }),

  // Sync: fast lookup, no Workflow needed
  getQuickScore: NewSyncOperation({
    async handler(input) {
      const score = await scoreCache.get(input.userId);
      return { score };
    }
  }),
});

// Run a Worker that polls the Endpoint's task queue
const worker = await NexusWorker.create({
  taskQueue: 'fraud-task-queue',
  nexusServices: [fraudHandler],
});

Team A calls the Nexus Service from their Workflow — it looks just like calling any other activity.

// payments-team/workflow.ts (Team A's caller)
import { proxyActivities, executeNexusOperation } from '@temporalio/workflow';
import { fraudService } from '../shared/fraud-service'; // shared package

export async function PaymentWorkflow(payment: Payment): Promise<Result> {
  // 1. Call the Nexus Operation — fully durable, typed
  const fraudResult = await executeNexusOperation({
    endpoint: 'fraud-detection-prod', // Nexus Endpoint name
    service: fraudService,
    operation: fraudService.operations.checkTransaction,
    input: {
      transactionId: payment.id,
      amount: payment.amount,
      userId: payment.userId,
    },
    // Total duration caller will wait (up to 60 days)
    scheduleToCloseTimeout: '24h',
  });

  // 2. Caller workflow was suspended during the check
  // Now it has the result — fully typed!
  if (!fraudResult.approved) {
    throw new Error(`Fraud detected: ${fraudResult.reason}`);
  }

  return processApprovedPayment(payment);
}

The caller never imports Team B's internal code. If Team B changes their implementation — swapping FraudCheckWorkflow for a new ML model — Team A's code doesn't change at all.

Test Your Understanding

Check what you've learned. Click an answer to see if you're right.