Skip to content

Commit fae9690

Browse files
Merge branch 'main' into patch-3
2 parents e8c2bd3 + 43d19fe commit fae9690

58 files changed

Lines changed: 2782 additions & 2107 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ temp/
2525
AGENTS.md
2626
CLAUDE.md
2727
.claude/*
28+
.omc
2829

2930
npm-debug.log*
3031
yarn-debug.log*

docs/cli/activity.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This file is generated from https://github.com/temporalio/cli/blob/main/internal
2727

2828
This page provides a reference for the `temporal` CLI `activity` command. The flags applicable to each subcommand are presented in a table within the heading for the subcommand. Refer to [Global Flags](#global-flags) for flags that you can use with every subcommand.
2929

30-
To use the CLI with Standalone Activities, see the CLI commands in the [Go](/docs/develop/go/standalone-activities.mdx) and [Python](/docs/develop/python/standalone-activities.mdx) Standalone Activity guides.
30+
To use the CLI with Standalone Activities, see the CLI commands in the [Go](/docs/develop/go/standalone-activities.mdx), [Python](/docs/develop/python/standalone-activities.mdx), and [.NET](/docs/develop/dotnet/standalone-activities.mdx) Standalone Activity guides.
3131

3232
## complete
3333

docs/cloud/billing-api.mdx

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
id: billing-api
3+
title: Cloud Billing API
4+
sidebar_label: Cloud Billing API
5+
description: The Temporal Cloud Billing API provides namespace-level cost attribution through on-demand billing reports.
6+
slug: /cloud/billing-api
7+
toc_max_heading_level: 4
8+
keywords:
9+
- explanation
10+
tags:
11+
- API
12+
- Billing
13+
- Temporal Cloud
14+
---
15+
16+
The Temporal Cloud Billing API provides Namespace-level cost attribution through on-demand billing reports.
17+
Reports are delivered in CSV format and can be accessed via API or downloaded directly for use in FinOps tooling and cost management platforms.
18+
19+
This API is part of the [Cloud Operations API](/ops).
20+
21+
:::tip Support, stability, and dependency info
22+
23+
The Temporal Cloud Billing API is in [Pre-release](/evaluate/development-production-features/release-stages#pre-release).
24+
25+
:::
26+
27+
The Billing API allows you to:
28+
29+
- Generate billing reports for specified invoice months
30+
- Retrieve report status and metadata
31+
- Download CSV reports that can be fed into internal analytics tooling or cloud cost management platforms
32+
33+
The Billing Report contains:
34+
35+
- Accurate Namespace-level cost attribution
36+
- Hourly granularity
37+
- A [FOCUS](https://focus.finops.org/)-friendly data format
38+
39+
For complete request and response schemas, refer to the Schema below.
40+
41+
Billing report generation is **asynchronous**. You initiate report creation, then poll for completion.
42+
43+
## Report data limitations
44+
45+
For pre-release, reports can be generated with hourly granularity only, for the current billing month, and the previous billing month.
46+
47+
## Allowed date ranges
48+
49+
Date ranges must use billing-month boundaries (MM/YYYY).
50+
Requests may include the current billing month.
51+
The data in finalized reports includes usage up to `current_time` \- 24 hours (rounded up to nearest hour).
52+
53+
## Rate limits and concurrency
54+
55+
Rate limits apply to API usage.
56+
57+
### Per-account concurrency
58+
59+
Within a single account:
60+
61+
- Only one billing report per account is generated at a time
62+
- Additional requests are accepted but queued
63+
64+
### Report Generation Latency
65+
66+
Report generation time varies and is not guaranteed. Factors that affect it include the size of the requested date range and overall platform load.
67+
68+
## Best practices
69+
70+
Provide an idempotency key (`async_operation_id`) when retrying requests.
71+
72+
Poll `GetBillingReport` using exponential backoff.
73+
74+
Download reports immediately after generation (URLs expire).
75+
76+
Avoid frequent generation of large overlapping ranges in the current billing period.
77+
78+
## Billing report schema
79+
80+
Billing reports are delivered in CSV format.
81+
82+
Each row represents a charge record.
83+
84+
| Column Name | Description | Example |
85+
| ----- | ----- | ----- |
86+
| BillingAccountID | Temporal Cloud account ID | a2dd6 |
87+
| BillingAccountName | Temporal Cloud account name | temporal |
88+
| BillingCurrency | The currency an account is billed in | USD (cents) |
89+
| BillingPeriodEnd | The exclusive end bound of a billing period | 2024-02-01T00:00:00Z |
90+
| BillingPeriodStart | The inclusive start bound of a billing period | 2024-01-01T00:00:00Z |
91+
| ChargeCategory | The highest level classification of a charge based on how it is billed | Usage |
92+
| ChargeDescription | A self contained summary of the charge’s purpose | Actions \- Tier 1 |
93+
| ChargeFrequency | Indicates how often a charge will occur | Usage-Based |
94+
| ChargePeriodEnd | Time period end from when this charge took place, correlates to data granularity | 2025-10-01T01:00:00.000Z |
95+
| ChargePeriodStart | Time period start from when this charge took place, correlates to data granularity | 2025-10-01T00:00:00.000Z |
96+
| ContractedCost | Cost calculated by multiplying ContractedUnitPrice and PricingQuantity | 100.00 |
97+
| ContractedUnitPrice | The agreed-upon unit price for a single pricing unit of the associated SKU. Inclusive of negotiated discounts | 10.00 |
98+
| InvoiceID | The ID of the invoice for this billing period | in\_XXXXXXXXXXXXXXXXXXXX |
99+
| InvoiceIssuer | The entity responsible for issuing payable invoices | stripe |
100+
| PricingQuantity | The volume of a given SKU used or purchased | 10.00 |
101+
| PricingUnit | The measurement unit used for PricingQuantity | 1 Million Actions |
102+
| Provider | The provider of purchased resources or services | Temporal Technologies |
103+
| Publisher | The publisher of purchased resources or services | Temporal Technologies |
104+
| ResourceID | Namespace name \+ Temporal Cloud account ID | production.a2dd6 |
105+
| ResourceName | Namespace name \+ Temporal Cloud account ID | production.a2dd6 |
106+
| ResourceType | The type of resource the charge applies to | Namespace |
107+
| ServiceCategory | The highest level classification of a service based on the core function of the service | Temporal Cloud |
108+
| ServiceName | An offering that can be purchased from a provider | Temporal Cloud |
109+
| ServiceSubcategory | A secondary classification of the service category for a service based on its core function | Actions |
110+
| SKUID | A unique identifier that represents a specific SKU | essentials-actions |
111+
| SKUMeter | The functionality being metered or measured by a particular SKU in a charge | Actions |
112+
| Tags | Provider and customer defined tags associated with resources | `{"$tmprl_project":["project-id"],"namespace-tag-key":["namespace-tag-value"]}` |
113+
114+
## Generate a report
115+
116+
To generate a report, follow these steps:
117+
118+
1. Create a billing report using `CreateBillingReport`. The response includes a `billing_report_id` and `async_operation_id`.
119+
1. Poll `GetBillingReport` using the `billing_report_id`
120+
1. When the report state becomes `BILLING_REPORT_STATE_GENERATED`, retrieve the download URL
121+
1. Download the report before the URL expires
122+
123+
### Key identifiers
124+
125+
| Identifier | Purpose |
126+
| ----- | ----- |
127+
| `billing_report_id` | Identifies the billing report and is used to retrieve metadata and download URLs |
128+
| `async_operation_id` | Identifies the background operation responsible for generating the report |
129+
130+
The async operation follows the standard Cloud Operations async model (see [Async Operations](/ops#per-identity-rate-limits)).

docs/cloud/get-started/billing-and-cost.mdx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,28 @@ tags:
2424
import * as Components from '@site/src/components';
2525

2626
Temporal strives to provide full transparency over billing and costs.
27-
Account Owners and Finance Admins can view their [detailed billing information](https://cloud.temporal.io/billing) at any time.
2827
Use this information to assess your spending patterns, inspect your credit ledger, check your invoice histories, update payment details,
2928
and manage your current plan as needed.
30-
You can see namespace-level cost estimates on the [usage dashboard](https://cloud.temporal.io/usage).
3129

3230
For more information on current Temporal Cloud pricing for Actions, storage, and services/support, please visit our [Pricing](/cloud/pricing) page.
3331

34-
The [billing](https://cloud.temporal.io/billing) page includes the following information.
35-
If you're not on a standard plan, your billing page may show a subset of this list:
32+
Temporal Provides multiple ways to view your usage and billing data:
3633

37-
- [Current balance](#current-balance): Your balance to date for this billing cycle
38-
- [Recent bill](#recent-bill): The amount of your most recent bill
39-
- [Invoice history](#invoice): Access to all past invoices
40-
- [Credit ledger](#credit-table): A record of all credit related transactions including details on credit grants, purchases, usage, and remaining credits, if applicable
41-
- [Plan](#plans): Your current plan, consumption pricing, and entitlements, with the ability to manage upgrades and downgrades, payment method, and account deletion
34+
- [Billing Center](https://cloud.temporal.io/billing) allows you to see summary invoices and credits, manage plans, and delete your accounts.
35+
- Coming soon: Billing dashboard enhancements to visualize billing by Namespace over time
36+
- Viewable by Account Owners and Finance Admin
37+
- [Usage Dashboards](https://cloud.temporal.io/usage) allow you to monitor Namespace level usage over time.
38+
- Coming soon: Additional granularity based on Action Types, grouping by Tags, and grouping by Projects
39+
- Viewable by Account Owners, Finance Admin, Global Admin on an account level. Namespace level usage is visible on the Namespace pages to those with access.
40+
- [Billing API](/cloud/billing-api) allow you to access billing information on a Namespace basis down to an hourly granularity, enriched with Tags and Projects.
41+
The Billing API provides a FOCUS-guided data format that can be ingested into your cloud cost management platform or analytics tooling, or downloaded as a CSV.
42+
- Viewable by Account Owners, Finance Admin
4243

43-
The [Usage](https://cloud.temporal.io/usage) page shows the cost breakdown by Namespace.
44-
If your organization separates projects by Namespace -- for architectural reasons, for development/production differentiation, for different products, etc -- you can view individual costs for each Namespace.
44+
:::tip Support, stability, and dependency info
45+
46+
The Temporal Cloud Billing API is in [Pre-release](/evaluate/development-production-features/release-stages#pre-release).
47+
48+
:::
4549

4650
## Current balance {#current-balance}
4751

docs/cloud/high-availability/failovers.mdx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ For more control over the failover process, you can [disable automated failovers
5555

5656
:::tip
5757

58-
You can test the failover of Namespace with High Availability features by manually triggering a failover using the UI or the 'tcld' CLI utility.
58+
You can test the failover of a Namespace with High Availability features by manually triggering a failover using the Web UI, the tcld CLI, or the Cloud Ops API.
59+
The Terraform provider does not support triggering failovers.
5960
In most scenarios, we recommend you let Temporal handle failovers for you.
6061

6162
After failover, be aware of the following points:
@@ -193,6 +194,14 @@ A forced failover when there is a significant replication lag has a higher likel
193194
### Trigger the failover {#manual-failovers}
194195

195196
You can trigger a failover manually using the Temporal Cloud Web UI, the tcld CLI, or the Cloud Ops API, depending on your preference and setup.
197+
198+
:::info Terraform not supported
199+
200+
The [Temporal Cloud Terraform provider](https://registry.terraform.io/providers/temporalio/temporalcloud/latest) does not support triggering failovers.
201+
You must use the Web UI, tcld CLI, or Cloud Ops API.
202+
203+
:::
204+
196205
The following instructions outline the steps for each method:
197206

198207
<Tabs>

docs/cloud/worker-health.mdx

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,79 @@ Workers, the Server can obtain an accurate count of Workers, understand Worker p
382382

383383
Use the Temporal CLI to view information about all Workers connected to Temporal Server. Use `temporal worker describe` to see details of a specific Worker. Use `temporal worker list` to get a complete list of all connected Workers.
384384

385-
If you wish to disable Worker heartbeating (features above will not work with this feature disabled) or set heartbeating to be more frequent than every 60 seconds (allowed range is 1s to 60s), set the configuration relevant to your SDK.
385+
If you wish to disable Worker heartbeating or set heartbeating to be more frequent than every 60 seconds (allowed range is 1s to 60s), set the configuration relevant to your SDK. The server needs Worker heartbeating to understand Worker status accurately. Disabling the Worker heartbeat will cause features that provide the list of active Workers and information about those Workers to show missing or inaccurate information.
386386
<SdkTabs hideUnsupportedLanguages>
387+
<SdkTabs.Go>
388+
389+
_Available since Go SDK v1.41.0_
390+
391+
Set the `WorkerHeartbeatInterval` field on [`client.Options`](https://pkg.go.dev/go.temporal.io/sdk/client#Options) to adjust the heartbeat interval.
392+
Set it to a negative value to disable heartbeating.
393+
394+
#### Enable host resource reporting
395+
396+
By default, the Go SDK reports `0` for CPU and memory usage in Worker heartbeats.
397+
To enable host resource reporting, provide a `SysInfoProvider` when creating your Worker.
398+
You must use a resource based tuner to enable host resource reporting.
399+
400+
The SDK includes a [gopsutil](https://github.com/shirou/gopsutil)-based implementation via the [sysinfo](https://pkg.go.dev/go.temporal.io/sdk/contrib/sysinfo) library that supports cgroup metrics in containerized Linux environments:
401+
402+
```go
403+
import (
404+
"log"
405+
406+
"go.temporal.io/sdk/client"
407+
"go.temporal.io/sdk/contrib/envconfig"
408+
"go.temporal.io/sdk/contrib/sysinfo"
409+
"go.temporal.io/sdk/worker"
410+
)
411+
412+
c, err := client.Dial(envconfig.MustLoadDefaultClientOptions())
413+
if err != nil {
414+
log.Fatalln("Unable to create client", err)
415+
}
416+
defer c.Close()
417+
tuner, err := worker.NewResourceBasedTuner(worker.ResourceBasedTunerOptions{
418+
TargetMem: 0.8,
419+
TargetCpu: 0.9,
420+
InfoSupplier: sysinfo.SysInfoProvider(),
421+
})
422+
w := worker.New(c, "my-task-queue", worker.Options{
423+
Tuner: tuner,
424+
})
425+
```
426+
427+
You can also implement the `worker.SysInfoProvider` interface to provide your own resource metrics.
428+
429+
</SdkTabs.Go>
387430
<SdkTabs.Python>
431+
432+
_Available since Python SDK v1.20.0_
433+
388434
Use `TelemetryConfig()` to adjust heartbeat settings. See the [Python SDK documentation](https://python.temporal.io/temporalio.bridge.runtime.RuntimeOptions.html#worker_heartbeat_interval_millis) for more details.
435+
389436
</SdkTabs.Python>
437+
<SdkTabs.TypeScript>
438+
439+
_Available since TypeScript SDK v1.14.0_
440+
441+
Set the `workerHeartbeatInterval` property on [`RuntimeOptions`](https://typescript.temporal.io/api/interfaces/worker.RuntimeOptions) to adjust the heartbeat interval.
442+
Set it to `0` to disable heartbeating.
443+
444+
</SdkTabs.TypeScript>
445+
<SdkTabs.DotNet>
446+
447+
_Available since .NET SDK v1.10.0_
448+
449+
Set the `WorkerHeartbeatInterval` property on [`TemporalRuntimeOptions`](https://dotnet.temporal.io/api/Temporalio.Runtime.TemporalRuntimeOptions.html) to adjust the heartbeat interval.
450+
Set it to `null` to disable heartbeating.
451+
452+
</SdkTabs.DotNet>
390453
<SdkTabs.Ruby>
454+
455+
_Available since Ruby SDK v1.1.0_
456+
391457
Add configurations to `Runtime()` to adjust heartbeat settings. See the [Ruby SDK documentation](https://ruby.temporal.io/Temporalio/Runtime.html) for more details.
458+
392459
</SdkTabs.Ruby>
393460
</SdkTabs>

docs/develop/dotnet/core-application.mdx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,60 @@ This means there are several things Workflows cannot do such as:
8484
Some calls in .NET do unsuspecting non-deterministic things and are easy to accidentally use.
8585
This is especially true with `Task`s.
8686
Temporal requires that the deterministic `TaskScheduler.Current` is used, but many .NET async calls will use `TaskScheduler.Default` implicitly (and some analyzers even encourage this).
87+
88+
The following sections cover replay-safe APIs, followed by .NET-specific `Task` gotchas.
89+
90+
#### Logging
91+
92+
Use [`Workflow.Logger`](https://dotnet.temporal.io/api/Temporalio.Workflows.Workflow.html#Temporalio_Workflows_Workflow_Logger), which is an instance of .NET's `ILogger`. The SDK logger automatically suppresses log messages during replay to avoid duplicates:
93+
94+
```csharp
95+
Workflow.Logger.LogInformation("Starting workflow for {Name}", name);
96+
```
97+
98+
For logger configuration, see [Observability: Logging](/develop/dotnet/observability#logging).
99+
100+
#### Random numbers and UUIDs
101+
102+
Use [`Workflow.Random`](https://dotnet.temporal.io/api/Temporalio.Workflows.Workflow.html#Temporalio_Workflows_Workflow_Random) to get a deterministic `Random` instance. For UUIDs, use [`Workflow.NewGuid()`](https://dotnet.temporal.io/api/Temporalio.Workflows.Workflow.html#Temporalio_Workflows_Workflow_NewGuid). Never use `System.Random` or `Guid.NewGuid()` directly:
103+
104+
```csharp
105+
// Good - deterministic across replays
106+
var value = Workflow.Random.Next(1, 100);
107+
var uniqueId = Workflow.NewGuid();
108+
109+
// Bad - different result on every replay
110+
var value = new Random().Next(1, 100);
111+
```
112+
113+
#### Current time
114+
115+
Use [`Workflow.UtcNow`](https://dotnet.temporal.io/api/Temporalio.Workflows.Workflow.html#Temporalio_Workflows_Workflow_UtcNow) instead of `DateTime.UtcNow`. The SDK returns the time of the last Workflow Task, which is consistent across replays:
116+
117+
```csharp
118+
var currentTime = Workflow.UtcNow;
119+
```
120+
121+
#### Detecting replay (advanced)
122+
123+
Use [`Workflow.Unsafe.IsReplaying`](https://dotnet.temporal.io/api/Temporalio.Workflows.Workflow.Unsafe.html#Temporalio_Workflows_Workflow_Unsafe_IsReplaying) to guard code that should only run on the first execution, such as emitting metrics or sending external notifications from an Interceptor.
124+
:::caution
125+
126+
Never use this to affect Workflow business logic — branching on replay status breaks determinism.
127+
128+
:::
129+
130+
```csharp
131+
if (!Workflow.Unsafe.IsReplaying)
132+
{
133+
EmitMetric("workflow_started", 1);
134+
}
135+
```
136+
137+
If your goal is to always take action when something new is happening, check that `Workflow.Unsafe.IsReplayingHistoryEvents` is false instead. This will be false during read-only operations like queries and update validators. This is what the SDK's built-in logger and metric meter use internally.
138+
139+
#### .NET Task gotchas
140+
87141
Here are some known gotchas to avoid with .NET tasks inside of Workflows:
88142

89143
- Do not use `Task.Run` - this uses the default scheduler and puts work on the thread pool.

docs/develop/dotnet/index.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ Connect to a Temporal Service and start a Workflow Execution.
6969
- [Get Workflow results](/develop/dotnet/temporal-client#get-workflow-results): Retrieve and process the results of your
7070
Workflows efficiently.
7171

72+
## [Standalone Activities](/develop/dotnet/standalone-activities)
73+
74+
Execute Activities independently without a Workflow using the Temporal Client.
75+
76+
- [How to execute a Standalone Activity](/develop/dotnet/standalone-activities#execute-activity)
77+
- [How to start a Standalone Activity without waiting](/develop/dotnet/standalone-activities#start-activity)
78+
- [How to get a handle to an existing Standalone Activity](/develop/dotnet/standalone-activities#get-activity-handle)
79+
7280
## [Testing](/develop/dotnet/testing-suite)
7381

7482
Set up the testing suite and test Workflows and Activities.

docs/develop/dotnet/message-passing.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ Follow these guidelines when writing your message handlers:
3737

3838
- Message handlers are defined as methods on the Workflow class, using one of the three attributes: [`WorkflowQueryAttribute`](https://dotnet.temporal.io/api/Temporalio.Workflows.WorkflowQueryAttribute.html), [`WorkflowSignalAttribute`](https://dotnet.temporal.io/api/Temporalio.Workflows.WorkflowSignalAttribute.html), and [`WorkflowUpdateAttribute`](https://dotnet.temporal.io/api/Temporalio.Workflows.WorkflowUpdateAttribute.html).
3939
- The parameters and return values of handlers and the main Workflow function must be [serializable](/dataconversion).
40-
- Prefer data classes to multiple input parameters.
41-
Data class parameters allow you to add fields without changing the calling signature.
40+
- Prefer data classes to multiple input parameters. Data class parameters allow you to add fields without changing the calling signature. Keep in mind that serialization and deserialization can fail with the default data converter if the new field does not have a default value.
4241

4342
### Query handlers {#queries}
4443

0 commit comments

Comments
 (0)