Context actions are methods available on the Restate Context object (ctx) that provide Restate’s core capabilities. These actions enable durable execution, state management, service communication, and timing control.

Durable steps

Use run to safely wrap any non-deterministic operation, like HTTP calls or database responses, and have Restate persist its result.
// External API call
const apiResult = await ctx.run("fetch-data", async () => {
  const response = await fetch("https://api.example.com/data");
  return response.json();
});

// Database operation
const dbResult = await ctx.run("update-user", () => {
  return updateUserDatabase(userId, { name: "John" });
});

// Idempotency key generation
const id = ctx.rand.uuidv4();
Without run(), these operations would produce different results during replay, breaking deterministic recovery.

State management

Available in Virtual Object and Workflow handlers for persistent key-value storage.

Get

Retrieve stored state by key.
// Get with type and default value
const profile = await ctx.get<UserProfile>("profile");
const count = (await ctx.get<number>("count")) ?? 0;
const cart = (await ctx.get<ShoppingCart>("cart")) ?? [];

Set

Store state that persists across function invocations.
// Store simple values
ctx.set("lastLogin", request.date);
ctx.set("count", count + 1);

// Store complex objects
ctx.set("profile", {
  name: "John Doe",
  email: "[email protected]",
});

Clear

State is retained indefinitely for Virtual Objects, or for the configured retention period for Workflows. To clear state:
// Clear specific keys
ctx.clear("shoppingCart");
ctx.clear("sessionToken");

// Clear all user data
ctx.clearAll();

Service communication

Request-response calls

Make request-response calls to other services. Your function waits for the result.
// Call another service
const validation = await ctx
  .serviceClient(ValidationService)
  .validateOrder(order);

// Call Virtual Object function
const profile = await ctx.objectClient(UserAccount, userId).getProfile();

// Submit Workflow
const result = await ctx
  .workflowClient(OrderWorkflow, orderId)
  .run(order);

Sending messages

Make one-way calls that don’t return results. Your function continues immediately.
// Fire-and-forget notification
ctx
  .serviceSendClient(NotificationService)
  .sendEmail({ userId, message: "Welcome!" });

// Background analytics
ctx
  .serviceSendClient(AnalyticsService)
  .recordEvent({ kind: "user_signup", userId });

// Cleanup task
ctx.objectSendClient(ShoppingCartObject, userId).emtpyExpiredCart();

Delayed messages

Schedule handlers to run in the future.
// Schedule reminder for tomorrow
ctx.serviceSendClient(ReminderService).sendReminder(
  { userId, message },
  sendOpts({
    delay: { days: 1 },
  })
);

Durable timers and timeouts

Pause function execution for a specific duration.
// Sleep for specific duration
await ctx.sleep({ minutes: 5 }); // 5 minutes

// Wait for action or timeout
const result = await ctx
  .workflowClient(OrderWorkflow, orderId)
  .run(order)
  .orTimeout({ minutes: 5 });
Handlers consume no resources while sleeping and resume at exactly the right time, even across restarts (see suspensions).

Workflow events

Use durable promises to wait for external events or human input in your workflows. Create promises that external systems can resolve to send data to your workflow.
// Wait for external event
const paymentResult = await ctx.promise<PaymentResult>(
  "payment-completed"
);

// Wait for human approval
const approved = await ctx.promise<boolean>("manager-approval");

// Wait for multiple events
const [payment, inventory] = await RestatePromise.all([
  ctx.promise<PaymentResult>("payment").get(),
  ctx.promise<InventoryResult>("inventory").get(),
]);
Resolve promises from signal handlers.
// In a signal function
confirmPayment: async (
  ctx: WorkflowSharedContext,
  result: PaymentResult
) => {
  await ctx.promise("payment-completed").resolve(result);
},

// In a signal function
approveRequest: async (ctx: WorkflowSharedContext, approved: boolean) => {
  await ctx.promise("manager-approval").resolve(approved);
},
To implement a similar pattern in Basic Services or Virtual Objects, have a look at awakeables (TS/Java/Kotlin/Go/Python).