Standalone Nexus Operations vs Workflow-driven
Standalone Nexus Operations let you run Nexus Operation Executions independently, without being orchestrated by a Workflow. Instead of calling a Nexus Operation from within a Workflow Definition using @temporalio/workflow's createNexusServiceClient(), you execute a Standalone Nexus Operation directly from a Nexus service client created on the Temporal Client using client.nexus.createServiceClient(). Standalone Nexus Operations use the same Nexus Service contract, Operation handlers, and Worker setup as Workflow-driven Operations — only the execution path differs.
Standalone Nexus Operations requires TypeScript SDK v1.20.2 or above
Standalone Nexus Operations require TypeScript SDK v1.20.2 or above. All APIs are experimental and may be subject to backwards-incompatible changes.
Count Nexus operations example
const query = `Endpoint = "${ENDPOINT_NAME}"`;
const count = await client.nexus.count(query);
console.log(`Total Nexus operations: ${count.count}`);
Count standalone Nexus operations with client.nexus.count()
Use client.nexus.count() to count Standalone Nexus Operation Executions that match a List Filter query. Note that client.nexus.count() is called on the base Client, not on the NexusServiceClient.
List Nexus operations example
const query = `Endpoint = "${ENDPOINT_NAME}"`;
for await (const op of client.nexus.list({ query })) {
console.log(
`OperationId: ${op.operationId},`,
`Operation: ${op.operation},`,
`Status: ${op.status}`,
);
}
List standalone Nexus operations with client.nexus.list()
Use client.nexus.list() to list Standalone Nexus Operation Executions that match a List Filter query. The result is an async iterator that yields operation metadata entries. Note that client.nexus.list() is called on the base Client, not on the NexusServiceClient. The query parameter accepts List Filter syntax, for example "Endpoint = 'my-endpoint' AND Status = 'Running'".
Start operation and get result example
// Start an operation and get a NexusOperationHandle
const handle = await nexusClient.startOperation(
myNexusService.operations.hello,
{ name: 'World' },
{
id: `hello-${nanoid()}`,
scheduleToCloseTimeout: '10s',
},
);
// Await the result
const helloResult = await handle.result();
console.log(helloResult.greeting);
Execute standalone Nexus operation example
const nexusClient = client.nexus.createServiceClient({
endpoint: ENDPOINT_NAME,
service: myNexusService,
});
// Await the result of the operation immediately.
const echoResult = await nexusClient.executeOperation(
myNexusService.operations.echo,
{ message: 'hello' },
{
id: `echo-${nanoid()}`,
scheduleToCloseTimeout: '10s',
},
);
startOperation returns NexusOperationHandle
startOperation() returns a NexusOperationHandle. Use NexusOperationHandle.result() to wait until the Operation completes and retrieve its result. This works for both synchronous and asynchronous Operations. If the Operation completed successfully, the result is returned. If the Operation failed, the failure is thrown as an error.
executeOperation waits for completion
executeOperation() waits for the Operation to complete and returns the result. It requires an id parameter and an optional scheduleToCloseTimeout parameter which defaults to the maximum allowed by the Temporal server.
Nexus interceptor registration example
Example of registering Nexus interceptors in Worker creation:
```ts
import { NexusOperationLogInterceptor } from './nexus-interceptors';
const worker = await Worker.create({
// ...
nexusServices: [/* your Nexus services */],
interceptors: {
nexus: [
(_ctx) => ({
inbound: new NexusOperationLogInterceptor(),
}),
],
},
});
```
Nexus operation interceptor example - log operations
Example implementation of NexusInboundCallsInterceptor to log Nexus operation start:
```ts
import type {
NexusInboundCallsInterceptor,
NexusStartOperationInput,
NexusStartOperationOutput,
Next,
} from '@temporalio/worker';
export class NexusOperationLogInterceptor implements NexusInboundCallsInterceptor {
async startOperation(
input: NexusStartOperationInput,
next: Next<NexusInboundCallsInterceptor, 'startOperation'>
): Promise<NexusStartOperationOutput> {
console.log('Starting Nexus operation', {
service: input.ctx.service,
operation: input.ctx.operation,
});
const output = await next(input);
console.log('Nexus operation started', {
service: input.ctx.service,
operation: input.ctx.operation,
async: output.result.isAsync,
});
return output;
}
}
```
NexusOutboundCallsInterceptor
NexusOutboundCallsInterceptor intercepts outbound calls from Nexus Operations, such as enriching log attributes and metric tags. This allows modification of outbound Nexus calls.
NexusInboundCallsInterceptor
NexusInboundCallsInterceptor intercepts inbound Nexus Operation calls like startOperation and cancelOperation. This interceptor type monitors and modifies Nexus operations on the inbound side.
Nexus interceptor registration
Nexus interceptors are registered on Worker creation via WorkerOptions.interceptors. Pass an array of factory functions to interceptors.nexus. Each factory receives an OperationContext and returns an object with optional inbound and outbound interceptors.
Nexus operations have same latency SLOs and availability SLAs as Worker requests
Nexus operations such as RespondWorkflowTaskCompleted, PollNexusTaskQueue, RespondNexusTaskCompleted, and RespondNexusTaskFailed have the same latency SLOs and availability SLAs as other Worker requests in both caller and handler Namespaces in Temporal Cloud.
Nexus traffic routes through global mTLS-secured Envoy mesh
Nexus traffic for cross-Namespace connectivity routes through a global mTLS-secured Envoy mesh. Same-region Namespaces have low latency, while cross-region latency varies by provider.
Nexus caller Namespace limits per Endpoint
The limit is 1,000 caller Namespaces per Endpoint by default.
Nexus Operation duration maximum
The maximum ScheduleToClose duration for a Nexus Operation is 60 days.
Per-Workflow callback limits
The limit is 2000 callbacks per Workflow. This governs how many Nexus callers can attach to a handler Workflow.
Nexus rate limits
Nexus requests count toward the Namespace RPS limit.
Nexus Endpoint limits per Account
The limit is 100 Endpoints per Account by default.
Per-Workflow Nexus Operation limits
The limit is 30 in-flight Operations per Workflow.
Nexus-specific exception classes in TypeScript
TypeScript has three Nexus-specific exception classes: (1) `nexus-rpc`'s `OperationError` — throw this to indicate operation failure that should not be retried; (2) `nexus-rpc`'s `HandlerError` — throw with a specific HandlerErrorType, marked as retryable or non-retryable. Non-retryable types are BAD_REQUEST, UNAUTHENTICATED, UNAUTHORIZED, NOT_FOUND, NOT_IMPLEMENTED. Retryable types are RESOURCE_EXHAUSTED, INTERNAL, UNAVAILABLE, UPSTREAM_TIMEOUT. (3) `@temporalio/nexus`'s `NexusOperationFailure` — thrown inside a Workflow when a Nexus operation fails; use the `cause` attribute to access the cause chain.
Run Temporal development server with Nexus enabled
Start the Temporal development server with Nexus support by running the command `temporal server start-dev`. This automatically starts the Temporal development server with the Web UI and creates the default Namespace. The Web UI is accessible at http://localhost:8233 and the server is available for client connections on localhost:7233.
Create caller and handler Namespaces for Nexus
Create separate Namespaces for caller and handler using the commands: `temporal operator namespace create --namespace my-target-namespace` and `temporal operator namespace create --namespace my-caller-namespace`. The target namespace contains the Nexus Operation handler, and the caller namespace contains the Workflow that calls that handler. Using different namespaces demonstrates cross-Namespace Nexus calls.
Create a Nexus Endpoint to route requests
Create a Nexus Endpoint using: `temporal operator nexus endpoint create --name my-nexus-endpoint-name --target-namespace my-target-namespace --target-task-queue my-handler-task-queue`. The endpoint routes Nexus Operation requests from the caller to the handler by specifying the target namespace and task queue.
Query Standalone Nexus Operations via CLI
Query Standalone Nexus Operation Executions using the Temporal CLI.
To list operations:
./temporal nexus operation list --namespace my-caller-namespace --query 'Endpoint = "my-nexus-endpoint"'
To count operations:
./temporal nexus operation count --namespace my-caller-namespace --query 'Endpoint = "my-nexus-endpoint"'
Both commands filter by the specified namespace (my-caller-namespace) and endpoint (my-nexus-endpoint).