# Serverless Workers on GCP Cloud Run - TypeScript SDK

> For the complete documentation index, see [llms.txt](https://docs.temporal.io/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.

> Run a Temporal Worker on a GCP Cloud Run worker pool using the TypeScript SDK.

> **Pre-release**
> Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways.
> Create a [support ticket](/cloud/support#support-ticket) or contact your account team for access, and
> [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview.

On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker.
Register Workflows and Activities the same way you would with any other TypeScript Worker, and Temporal Cloud scales the pool up and down as work arrives and drains.

A Cloud Run Worker needs no Cloud Run-specific package.
The one addition to a standard Worker is [Worker Versioning](/worker-versioning), which is required for Serverless Workers.

For the end-to-end deployment guide covering the Worker Pool, IAM, and compute configuration, see [Deploy a Serverless Worker on GCP Cloud Run](/production-deployment/worker-deployments/serverless-workers/cloud-run).

## Create a versioned Worker 

Build the Worker as you would any long-running TypeScript Worker, then pass `workerDeploymentOptions` to `Worker.create()` to declare the Worker Deployment Version and turn versioning on.

The following Worker reads its connection settings and Task Queue from the environment, so the same image can run against any Namespace:

<!--SNIPSTART typescript-cloud-run-worker-->
[features/snippets/worker/worker.ts](https://github.com/temporalio/features/blob/worker-docs-snippets/features/snippets/worker/worker.ts)
```ts
const connection = await NativeConnection.connect({
  address: process.env.TEMPORAL_ADDRESS,
  apiKey: process.env.TEMPORAL_API_KEY,
  tls: true,
});

const worker = await Worker.create({
  connection,
  namespace: process.env.TEMPORAL_NAMESPACE!,
  taskQueue: process.env.TEMPORAL_TASK_QUEUE!,
  workflowsPath: require.resolve('./workflows'),
  workerDeploymentOptions: {
    version: { deploymentName: 'my-app', buildId: 'build-1' },
    useWorkerVersioning: true,
    defaultVersioningBehavior: 'PINNED',
  },
});

await worker.run();
```
<!--SNIPEND-->

`deploymentName` and `buildId` together identify the Worker Deployment Version. Both values must match the version you create with `temporal worker deployment create-version` in the deployment guide, or the Worker polls under a version the WCI does not manage.

Every Workflow needs a [versioning behavior](/worker-versioning#versioning-behaviors), either `PINNED` or `AUTO_UPGRADE`.
Setting `defaultVersioningBehavior` as shown above covers every Workflow on the Worker.
To set the behavior per Workflow instead, pass the Workflow function to `setWorkflowOptions()` from `@temporalio/workflow`:

```ts
import { setWorkflowOptions } from '@temporalio/workflow';

setWorkflowOptions({ versioningBehavior: 'PINNED' }, myWorkflow);
export async function myWorkflow(): Promise<string> {
  // ...
}
```

For general Worker setup and options that are not specific to Cloud Run, see [Run a Worker](/develop/typescript/workers/run-worker-process).

## Configure the Temporal connection 

Read the Namespace, address, and Task Queue from environment variables you set on the Worker Pool, and mount the Temporal Cloud API key or TLS material from Secret Manager rather than passing it in plaintext.

To load the connection settings from a TOML config file and profiles instead of reading each variable by hand, use `loadClientConnectConfig()` from `@temporalio/envconfig` and pass its `connectionOptions` and `namespace` to `NativeConnection.connect()` and `Worker.create()`.
For the supported variables and the config file format, see [Environment configuration](/develop/environment-configuration).

## Package the Worker image 

The Worker reads TLS roots from the operating system's certificate store, and the slim Node.js images ship without one.
On `node:22-slim`, connecting with TLS fails at startup:

```
TransportError: tonic::transport::Error(Transport, NativeCertsNotFound)
```

Install the certificates in the runtime stage of your Dockerfile:

```dockerfile
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates \
    && rm -rf /var/lib/apt/lists/*
```

Use a glibc-based image such as `node:22-slim` rather than an Alpine image. Alpine replaces glibc with musl, which the
Rust core does not support. See [Do not use Alpine](/develop/typescript/workers/run-worker-process#do-not-use-alpine).

Node.js also sizes its heap from the host's memory rather than the container limit, so set
`NODE_OPTIONS=--max-old-space-size=<MB>` on the Worker Pool to about 80% of the instance's memory limit. A Cloud Run
Worker Pool defaults to 512 MiB per instance, so raise `--memory` if your Worker needs more. See
[Run a Worker on Docker](/develop/typescript/workers/run-worker-process#run-a-worker-on-docker).

## Keep Activities safe across scale-in 

The WCI decides when to remove an instance from Task Queue activity, not from what an individual instance is doing.
An instance running a long Activity can be stopped mid-execution.

Use [Activity Heartbeats](/develop/typescript/activities/timeouts#activity-heartbeats) so a retry resumes from the last recorded progress instead of starting over:

```ts
import { heartbeat } from '@temporalio/activity';

export async function myActivity(items: string[]): Promise<string> {
  for (let i = 0; i < items.length; i++) {
    heartbeat(i);
    // ... process items[i]
  }
  return 'done';
}
```

For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/serverless-workers/cloud-run#lifecycle).

## Add observability 

A Cloud Run Worker emits the same traces and metrics as a Worker anywhere else.
For how to configure metrics export and OpenTelemetry tracing interceptors, see [Observability - TypeScript SDK](/develop/typescript/platform/observability) and the [SDK metrics reference](/references/sdk-metrics).
