Skip to content

Commit f4b1f70

Browse files
Merge pull request #4865 from MicrosoftDocs/main
Auto Publish – main to live - 2026-04-17 22:05 UTC
2 parents 5f46cb1 + af793ae commit f4b1f70

10 files changed

Lines changed: 314 additions & 130 deletions

articles/cosmos-db/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@
240240
href: hierarchical-partition-keys.md?context=/azure/cosmos-db/context/context
241241
- name: Hierarchical partition keys FAQ
242242
href: hierarchical-partition-keys-faq.yml?context=/azure/cosmos-db/context/context
243+
- name: Unlimited scale with hierarchical partition keys
244+
href: hierarchical-partition-keys-unlimited-scale.md?context=/azure/cosmos-db/context/context
243245
- name: Change partition key
244246
href: change-partition-key.md
245247
- name: Synthetic partition keys
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
---
2+
title: Unlimited logical partition storage with hierarchical partition keys
3+
description: Learn how to use hierarchical partition keys with a unique last level to scale beyond the 20-GB logical partition limit in Azure Cosmos DB.
4+
author: lnajaroen
5+
ms.author: lnajaroen
6+
ms.service: azure-cosmos-db
7+
ms.topic: concept-article
8+
ms.date: 03/24/2026
9+
ai-usage: ai-assisted
10+
appliesto:
11+
- ✅ NoSQL
12+
---
13+
14+
# Unlimited logical partition storage with hierarchical partition keys in Azure Cosmos DB
15+
16+
This document explains how hierarchical partition keys (HPK) can help you model high-cardinality data. To avoid hitting the 20 GB logical partition size limit, use a multi-level partition key path that ends with a unique identifier, such as /id.
17+
18+
In Azure Cosmos DB, items are grouped into logical partitions based on the value of the partition key. A single logical partition has a maximum storage size of 20 GB. For more information, see [logical partitions overview](partitioning.md). If your data model causes too many items to share the same partition key value (for example, all events for a single customer, tenant, device, or account), that logical partition can grow until it reaches the 20-GB limit, at which point writes targeting that partition fail.
19+
20+
You can avoid this limit by using [hierarchical partition keys](hierarchical-partition-keys.md) (HPK) with a unique identifier as the final level. A unique identifier guarantees that the previous levels can exceed 20GB. For example, if the partition key hierarchy is TenantId, UserId, and id (guid), then you can have infinite data for each combination of TenantId, UserId. This strategy works with any HPK container — no extra account-level settings are required.
21+
22+
## Best practice: use a unique last level
23+
24+
Choose one to three business-grouping levels (such as tenant, customer, or workload) and use a unique final level of `/id`. Azure Cosmos DB uses the combined hierarchy to distribute items.
25+
26+
For example, a multitenant application might use the following hierarchical partition key path:
27+
28+
- `/tenantId`
29+
- `/userId`
30+
- `/id`
31+
32+
With hierarchical partition keys, the logical partition key is defined as the full concatenation of all levels. In this example, each logical partition key is the combination of `tenantId` + `userId` + `id`. Because `id` is unique for every item, each logical partition contains at most one item and never approaches the 20-GB limit. This means the first and second levels (`tenantId` and `userId`) can individually exceed 20 GB of data, because their data is spread across many logical partitions defined by the full three-level key.
33+
34+
You can apply this strategy today by creating a new container with an HPK path that ends with `/id`. For more information about creating containers with hierarchical partition keys, see [Create a container by using hierarchical partition keys](hierarchical-partition-keys.md#create-a-container-by-using-hierarchical-partition-keys).
35+
36+
> [!IMPORTANT]
37+
> Adding a unique last level changes how you target point operations and transactional operations. Review the [prerequisites and limitations](#prerequisites-and-limitations) before you adopt this pattern.
38+
39+
## Prerequisites and limitations
40+
41+
Before you adopt an HPK strategy that ends with a unique value of `/id`, make sure the pattern aligns with the transactional semantics your application requires.
42+
43+
### Transactional operations
44+
45+
Operations that require a single, shared partition key value across multiple items aren't compatible with a unique-last-level pattern. The following features are **not supported** when you use this pattern:
46+
47+
- **Transactional batch (atomic batch):** Requires multiple items to share the same partition key value.
48+
- **Stored procedures and triggers:** Rely on grouping multiple items under one partition key value.
49+
50+
If you need these features, consider an HPK design where the last level isn't unique, or use an alternative data model. Validate that your design still avoids exceeding the 20-GB logical partition limit for your workload.
51+
52+
### Application requirements
53+
54+
To use hierarchical partition keys, you must use a supported version of the Azure Cosmos DB SDK. See [supported SDK versions](hierarchical-partition-keys.md#get-started).
55+
56+
## Optional: enforce the pattern at the account level
57+
58+
The ability to exceed 20 GB on the first and second levels is built into hierarchical partition keys — it works automatically when you end your key path with a unique value like `/id`. No account-level property is required to get this benefit.
59+
60+
However, if you want to **enforce** that all new containers created in an account follow this pattern, you can enable the `EnforceHierarchicalPartitionKeyIdLastLevel` property on your account. This property doesn't unlock new functionality — it prevents teams or applications from accidentally creating containers that don't use `/id` as the last level.
61+
62+
> [!NOTE]
63+
> The minimum Resource Provider API version required is `2026-03-15`. For the full REST API specification, see [Database Accounts - Create Or Update](/rest/api/cosmos-db-resource-provider/database-accounts/create-or-update).
64+
65+
### Behavior after enablement
66+
67+
| Behavior | Description |
68+
| --- | --- |
69+
| **New containers must use HPK + /id as last level** | Any new container created in the account must both use hierarchical partition keys and end with `/id` as the last level. If you want to partition only by `/id`, you can achieve this by setting `/id` as the first and only level in your hierarchical partition key. |
70+
| **Existing containers unchanged** | Enabling this property doesn't retroactively modify existing containers or their partition key configuration. To adopt this pattern for existing containers, create a new container with the desired HPK definition and [migrate your data](container-copy.md). |
71+
| **No defaulting of `/id`** | Azure Cosmos DB doesn't add `/id` as the last level automatically. You must specify the full HPK path at container creation time with `/id` as the last level. |
72+
| **Support for additional levels** | There is support for four levels of keys. However, a fourth level is recommended only for rare scenarios where three levels are needed in addition to `/id`. For the majority of workloads, two or three level of keys are sufficient to achieve good data distribution and optimize query performance. |
73+
74+
## Enable and configure enforcement
75+
76+
If you choose to enable the account-level enforcement, use one of the following methods to set the `EnforceHierarchicalPartitionKeyIdLastLevel` property on your account.
77+
78+
### [Bicep](#tab/bicep)
79+
80+
```bicep
81+
resource cosmosAccount 'Microsoft.DocumentDB/databaseAccounts@2026-03-15' = {
82+
name: '<account-name>'
83+
location: '<location>'
84+
properties: {
85+
databaseAccountOfferType: 'Standard'
86+
enableHierarchicalPartitionKeyIdLastLevel: true
87+
}
88+
}
89+
```
90+
91+
After you enable the property, create a container with a hierarchical partition key path that ends with `/id`:
92+
93+
```bicep
94+
partitionKey: {
95+
paths: [
96+
'/tenantId'
97+
'/userId'
98+
'/id'
99+
]
100+
kind: 'MultiHash'
101+
version: 2
102+
}
103+
```
104+
105+
### [ARM template](#tab/arm-json)
106+
107+
```json
108+
{
109+
"type": "Microsoft.DocumentDB/databaseAccounts",
110+
"apiVersion": "2026-03-15",
111+
"name": "<account-name>",
112+
"location": "<location>",
113+
"properties": {
114+
"databaseAccountOfferType": "Standard",
115+
"enableHierarchicalPartitionKeyIdLastLevel": true
116+
}
117+
}
118+
```
119+
120+
After you enable the property, create a container with a hierarchical partition key path that ends with `/id`:
121+
122+
```json
123+
"partitionKey": {
124+
"paths": [
125+
"/tenantId",
126+
"/userId",
127+
"/id"
128+
],
129+
"kind": "MultiHash",
130+
"version": 2
131+
}
132+
```
133+
134+
### [Azure CLI](#tab/azure-cli)
135+
136+
```azurecli
137+
az cosmosdb update \
138+
--resource-group <resource-group-name> \
139+
--name <account-name> \
140+
--enable-hierarchical-partition-key-id-last-level true
141+
```
142+
143+
### [PowerShell](#tab/powershell)
144+
145+
```powershell
146+
Update-AzCosmosDBAccount `
147+
-ResourceGroupName "<resource-group-name>" `
148+
-Name "<account-name>" `
149+
-EnableHierarchicalPartitionKeyIdLastLevel $true
150+
```
151+
152+
### [Management .NET SDK](#tab/net-v3)
153+
154+
Use the `Azure.ResourceManager.CosmosDB` management SDK to enable the property on your account.
155+
156+
```csharp
157+
using Azure.ResourceManager;
158+
using Azure.ResourceManager.CosmosDB;
159+
using Azure.ResourceManager.CosmosDB.Models;
160+
161+
ArmClient client = new ArmClient(new DefaultAzureCredential());
162+
163+
ResourceIdentifier accountId = CosmosDBAccountResource.CreateResourceIdentifier(
164+
"<subscription-id>", "<resource-group-name>", "<account-name>");
165+
166+
CosmosDBAccountResource account = client.GetCosmosDBAccountResource(accountId);
167+
168+
CosmosDBAccountPatch patch = new CosmosDBAccountPatch();
169+
patch.EnableHierarchicalPartitionKeyIdLastLevel = true;
170+
171+
await account.UpdateAsync(WaitUntil.Completed, patch);
172+
```
173+
174+
### [Management Java SDK](#tab/java-v4)
175+
176+
Use the `azure-resourcemanager-cosmos` management SDK to enable the property on your account.
177+
178+
```java
179+
import com.azure.resourcemanager.cosmos.CosmosManager;
180+
import com.azure.resourcemanager.cosmos.models.CosmosDBAccount;
181+
182+
CosmosManager cosmosManager = CosmosManager.authenticate(credential, profile);
183+
184+
CosmosDBAccount account = cosmosManager.databaseAccounts()
185+
.getByResourceGroup("<resource-group-name>", "<account-name>");
186+
187+
account.update()
188+
.withEnableHierarchicalPartitionKeyIdLastLevel(true)
189+
.apply();
190+
```
191+
192+
### [Management Python SDK](#tab/python)
193+
194+
Use the `azure-mgmt-cosmosdb` management SDK to enable the property on your account.
195+
196+
```python
197+
from azure.identity import DefaultAzureCredential
198+
from azure.mgmt.cosmosdb import CosmosDBManagementClient
199+
200+
credential = DefaultAzureCredential()
201+
client = CosmosDBManagementClient(credential, "<subscription-id>")
202+
203+
account = client.database_accounts.get("<resource-group-name>", "<account-name>")
204+
205+
update_params = {
206+
"location": account.location,
207+
"properties": {
208+
"enable_hierarchical_partition_key_id_last_level": True
209+
}
210+
}
211+
212+
client.database_accounts.begin_create_or_update(
213+
"<resource-group-name>", "<account-name>", update_params
214+
).result()
215+
```
216+
217+
---
218+
219+
After you enable the property, create a new container by specifying a hierarchical partition key path that ends with `/id` (for example: `/tenantId`, `/userId`, `/id`). For more information about creating containers with hierarchical partition keys, see [Create a container by using hierarchical partition keys](hierarchical-partition-keys.md#create-a-container-by-using-hierarchical-partition-keys).
220+
221+
To disable this feature set 'enableHierarchicalPartitionKeyIdLastLevel' property back to false.
222+
223+
## Frequently asked questions
224+
225+
### Why am I getting errors related to the 20-GB limit?
226+
227+
This typically means a single logical partition (a single partition key value) has accumulated more than 20 GB of data. Switching to HPK and ensuring the final level is unique (for example, `/id`) helps prevent unbounded growth under one value. To proactively monitor for logical partitions approaching this limit, see [Create alerts to monitor logical partition key storage size](how-to-alert-on-logical-partition-key-storage-size.md).
228+
229+
### Why does my request fail with "The last level of the hierarchical partition key must be '/id'"?
230+
231+
With `EnforceHierarchicalPartitionKeyIdLastLevel` enabled, your items must include every partition key property in the hierarchy. For example, if your HPK is `/tenantId`, `/userId`, `/id`, then each item must have `tenantId`, `userId`, and `id` properties. The request must supply the matching full partition key value for point reads, updates, and deletes. If this is not needed please disable.
232+
233+
### Why can't I create a container with a non-hierarchical partition key? Request failing with "Non-hierarchical partition key collection creation is blocked"
234+
235+
After you enable `EnforceHierarchicalPartitionKeyIdLastLevel`, you must use hierarchical partition keys for all newly created containers. This restriction doesn't affect existing containers. If this is not needed please disable.
236+
237+
### Can I change an existing container to use hierarchical partition keys?
238+
239+
No. Partition key configuration is immutable. To adopt HPK (or to add a unique last level like `/id`), create a new container with the desired HPK definition and [migrate your data by using container copy jobs](container-copy.md).
240+
241+
### Can I still use transactional batch, stored procedures, or triggers?
242+
243+
If your usage depends on grouping multiple items under a single shared partition key value, a unique-last-level HPK (ending in `/id`) isn't compatible. If you need these features, consider an HPK design where the last level isn't unique (or use an alternative data model), and validate that it still avoids exceeding the 20-GB logical partition limit for your workload.
244+
245+
## Next steps
246+
247+
- [Hierarchical partition keys in Azure Cosmos DB](hierarchical-partition-keys.md)
248+
- [Frequently asked questions on hierarchical partition keys in Azure Cosmos DB](hierarchical-partition-keys-faq.yml)
249+
- [Partitioning and horizontal scaling in Azure Cosmos DB](partitioning.md)

articles/cosmos-db/hierarchical-partition-keys.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ When you choose each level of your hierarchical partition key, it's important to
3030

3131
- **Have a high cardinality**. The first, second, and third (if applicable) keys of the hierarchical partition should all have a wide range of possible values.
3232

33-
- Having low cardinality at the first level of the hierarchical partition key limits all of your write operations at the time of ingestion to just one physical partition until it reaches 50 GB and splits into two physical partitions. For example, suppose your first-level key is on `TenantId` and you only have five unique tenants. Each of these tenants' operations are scoped to just one physical partition, limiting your throughput consumption to just what is on that one physical partition. This is because hierarchical partitions optimize for all documents with the same first-level key to be collocated on the same physical partition to avoid full-fanout queries.
33+
- Having low cardinality at the first level of the hierarchical partition key limits all of your write operations at the time of ingestion to just one physical partition until it reaches 50 GB and splits into two physical partitions. For example, suppose your first-level key is on `TenantId` and you only have five unique tenants. Each of these tenants' operations is scoped to just one physical partition, limiting your throughput consumption to just what is on that one physical partition. This is because hierarchical partitions optimize for all documents with the same first-level key to be collocated on the same physical partition to avoid full-fanout queries.
3434
- While this might be okay for workloads where we do a one-time ingest of all our tenants' data and the following operations are primarily read-heavy afterwards, this can be unideal for workloads where your business requirements involve ingestion of data within a specific time. For example, if you have strict business requirements to avoid latencies, the maximum throughput your workload can theoretically achieve to ingest data is number of physical partitions * 10k. If your top-level key has low cardinality, your number of physical partitions is likely 1, unless there's sufficient data for the level-1 key for it to be spread across multiple partitions after splits, which can take between 4-6 hours to complete.
3535

3636
- **Spread RU consumption and data storage evenly across all logical partitions**. This spread ensures even RU consumption and storage distribution across your physical partitions.
@@ -79,10 +79,10 @@ Find the latest preview version of each supported SDK:
7979

8080
| SDK | Supported versions | Package manager link |
8181
| --- | --- | --- |
82-
| .NET SDK v3 | >= 3.33.0 | <https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.33.0/> |
83-
| Java SDK v4 | >= 4.42.0 | <https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/cosmos/azure-cosmos/CHANGELOG.md#4420-2023-03-17/> |
82+
| .NET SDK v3 | >= 3.33.0 | <https://www.nuget.org/packages/Microsoft.Azure.Cosmos> |
83+
| Java SDK v4 | >= 4.42.0 | <https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/cosmos/azure-cosmos> |
8484
| JavaScript SDK v4 | 4.0.0 | <https://www.npmjs.com/package/@azure/cosmos/> |
85-
| Python SDK | >= 4.6.0 | <https://pypi.org/project/azure-cosmos/4.6.0/> |
85+
| Python SDK | >= 4.6.0 | <https://pypi.org/project/azure-cosmos> |
8686

8787
## Create a container by using hierarchical partition keys
8888

0 commit comments

Comments
 (0)