Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Access Durable Object jurisdiction via `ctx.id.jurisdiction`
description: Read the jurisdiction of a Durable Object from within the object itself.
products:
- durable-objects
- workers
date: 2026-03-26
---

`ctx.id.jurisdiction` inside a Durable Object now reports the [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction) the object was created in — for example `"eu"` when accessed through `env.MY_DURABLE_OBJECT.jurisdiction("eu")` — so you can make region-aware decisions without passing the jurisdiction through method arguments or persisting it in storage. For the full list of ID-construction paths that preserve `jurisdiction`, refer to the [Durable Object ID documentation](/durable-objects/api/id/#jurisdiction).

```js
export class RegionalRoom extends DurableObject {
async fetch(request) {
// "eu" when accessed through env.MY_DURABLE_OBJECT.jurisdiction("eu")
const region = this.ctx.id.jurisdiction;
return new Response(`Hello from ${region ?? "the default region"}!`);
}
}

// Worker
export default {
async fetch(request, env) {
const stub = env.MY_DURABLE_OBJECT.jurisdiction("eu").getByName("general");
return stub.fetch(request);
},
};
```

`ctx.id.jurisdiction` is `undefined` for Durable Objects that were not created in a jurisdiction-restricted namespace. Alarms scheduled before 2026-03-15 also do not have `jurisdiction` stored; to backfill the value, reschedule the alarm from a `fetch()` or RPC handler.
111 changes: 109 additions & 2 deletions src/content/docs/durable-objects/api/id.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,15 @@ assert not id1.equals(id2), "Different unique ids should never be equal."

`name` is an optional property of a `DurableObjectId`, which returns the name that was used to create the `DurableObjectId` via [`DurableObjectNamespace::idFromName`](/durable-objects/api/namespace/#idfromname). This value is undefined if the `DurableObjectId` was constructed using [`DurableObjectNamespace::newUniqueId`](/durable-objects/api/namespace/#newuniqueid).

The `name` property is available on `ctx.id` inside the Durable Object when the caller uses `idFromName()` or `getByName()`. If the caller accesses the Durable Object using `idFromString()`, `ctx.id.name` will be `undefined`, even if the ID was originally created with `idFromName()`. Names longer than 1,024 bytes are not passed through and will be `undefined` on `ctx.id`.
The `name` property is also available on `ctx.id` inside the Durable Object when the caller uses `idFromName()` or `getByName()`. `ctx.id.name` will be `undefined` in the following cases:

- The caller accesses the Durable Object using `idFromString()`, even if the ID was originally created with `idFromName()`.
- Names longer than 1,024 bytes are not passed through to `ctx.id`.
- The Durable Object was created with `newUniqueId()`.

:::note[Alarms]
`ctx.id.name` is especially useful inside [alarm handlers](/durable-objects/api/alarms/), where there is no calling client to pass the name as an argument. When the alarm fires, `ctx.id.name` holds the same name the object was originally accessed with.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combine with note below for single one for alarms behavior


:::note
Alarms created before 2026-03-15 do not have `name` stored. When such an alarm fires, `ctx.id.name` will be `undefined`, and any new alarm scheduled from that handler will also lack a `name`. To fix this, reschedule the alarm from a `fetch()` or RPC handler where `name` is available.
:::

Expand All @@ -102,6 +108,20 @@ console.assert(

</TabItem>

<TabItem label="TypeScript" icon="seti:typescript">

```ts
const uniqueId: DurableObjectId = env.MY_DURABLE_OBJECT.newUniqueId();
const fromNameId: DurableObjectId = env.MY_DURABLE_OBJECT.idFromName("foo");
console.assert(uniqueId.name === undefined, "unique ids have no name");
console.assert(
fromNameId.name === "foo",
"name matches parameter to idFromName",
);
```

</TabItem>

<TabItem label="Python" icon="seti:python">

```python
Expand All @@ -115,6 +135,93 @@ assert from_name_id.name == "foo", "name matches parameter to idFromName"

</Tabs>

The same `name` is available inside the Durable Object via `ctx.id.name`:

<Tabs>

<TabItem label="JavaScript" icon="seti:javascript">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Typescript tab too


```js
import { DurableObject } from "cloudflare:workers";

export class ChatRoom extends DurableObject {
async getRoomName() {
return this.ctx.id.name; // "foo" when accessed via getByName("foo")
}
}
```

</TabItem>

<TabItem label="TypeScript" icon="seti:typescript">

```ts
import { DurableObject } from "cloudflare:workers";

export class ChatRoom extends DurableObject<Env> {
async getRoomName(): Promise<string | undefined> {
return this.ctx.id.name; // "foo" when accessed via getByName("foo")
}
}
```

</TabItem>

<TabItem label="Python" icon="seti:python">

```python
from workers import DurableObject

class ChatRoom(DurableObject):
async def get_room_name(self):
return self.ctx.id.name # "foo" when accessed via get_by_name("foo")
```

</TabItem>

</Tabs>

### `jurisdiction`

`jurisdiction` is an optional property of a `DurableObjectId`, which returns the [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction) the ID is restricted to, such as `"eu"` or `"fedramp"`. The same value is available inside the Durable Object via `ctx.id.jurisdiction`, including in [alarm handlers](/durable-objects/api/alarms/) and objects accessed via `idFromString()`, so you can make region-aware decisions without passing the jurisdiction as an argument or persisting it in storage.

`jurisdiction` is preserved across every ID-construction path, including:

- IDs created from a jurisdiction-restricted subnamespace, for example `env.MY_DURABLE_OBJECT.jurisdiction("eu").idFromName("foo")` or `.newUniqueId()`.
- IDs created via `env.MY_DURABLE_OBJECT.newUniqueId({ jurisdiction: "eu" })`.
- IDs restored from a string via `idFromString()` — the jurisdiction is encoded in the string itself, so it works on any namespace binding.

`ctx.id.jurisdiction` is `undefined` in two cases:

- The Durable Object was not created in a jurisdiction-restricted namespace.
- The Durable Object's alarm was scheduled before 2026-03-15. To backfill the value, reschedule the alarm from a `fetch()` or RPC handler.

<Tabs>

<TabItem label="JavaScript" icon="seti:javascript">

```js
const plainId = env.MY_DURABLE_OBJECT.idFromName("foo");
const euId = env.MY_DURABLE_OBJECT.jurisdiction("eu").idFromName("foo");
console.assert(plainId.jurisdiction === undefined, "no jurisdiction set");
console.assert(euId.jurisdiction === "eu", "jurisdiction matches namespace");
```

</TabItem>

<TabItem label="Python" icon="seti:python">

```python
plain_id = env.MY_DURABLE_OBJECT.idFromName("foo")
eu_id = env.MY_DURABLE_OBJECT.jurisdiction("eu").idFromName("foo")
assert plain_id.jurisdiction is None, "no jurisdiction set"
assert eu_id.jurisdiction == "eu", "jurisdiction matches namespace"
```

</TabItem>

</Tabs>

## Related resources

- [Durable Objects: Easy, Fast, Correct – Choose Three](https://blog.cloudflare.com/durable-objects-easy-fast-correct-choose-three/).
20 changes: 14 additions & 6 deletions src/content/docs/durable-objects/reference/data-location.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ Note that it is also possible to specify a jurisdiction by creating an individua

### Supported locations

| Parameter | Location |
| --------- | ---------------------------- |
| eu | The European Union |
| Parameter | Location |
| --------- | ------------------------------ |
| eu | The European Union |
| fedramp | FedRAMP-compliant data centers |

### Read the jurisdiction from inside a Durable Object

The jurisdiction of a Durable Object is available inside the object via [`ctx.id.jurisdiction`](/durable-objects/api/id/#jurisdiction). The value is preserved across `toString()` and `idFromString()` round-trips and is also available inside [alarm handlers](/durable-objects/api/alarms/) for alarms scheduled on 2026-03-15 or later, which makes it suitable for region-aware logic inside the Durable Object.

## Provide a location hint

Durable Objects, as with any stateful API, will often add response latency as requests must be forwarded to the data center where the Durable Object, or state, is located.
Expand Down Expand Up @@ -102,10 +106,14 @@ Hints are a best effort and not a guarantee. Unlike with jurisdictions, Durable
| afr | Africa <sup>2</sup> |
| me | Middle East <sup>2</sup> |

<sup>1</sup> Dynamic relocation of existing Durable Objects is planned for the future.
<sup>1</sup> Dynamic relocation of existing Durable Objects is planned for the
future.

<sup>2</sup> Durable Objects currently do not spawn in this location. Instead, the Durable Object will spawn in a nearby location which does support Durable Objects. For example, Durable Objects hinted to South America spawn in Eastern North America instead.
<sup>2</sup> Durable Objects currently do not spawn in this location. Instead,
the Durable Object will spawn in a nearby location which does support Durable
Objects. For example, Durable Objects hinted to South America spawn in Eastern
North America instead.

## Additional resources

- You can find our more about where Durable Objects are located using the website: [Where Durable Objects Live](https://where.durableobjects.live/).
- You can find our more about where Durable Objects are located using the website: [Where Durable Objects Live](https://where.durableobjects.live/).