Cosmos DB Partitioning and Throughput Design

Watch the video to deepen your understanding.
SubscribeComplete the full lesson to earn 25 points
Work through each section, then tap βMark as Completeβ on the last one.
β¦ Skip the page breaks and see fewer ads β read each lesson on a single page with Pro
Lesson: Cosmos DB Partitioning and Throughput Design
Introduction: The Architecture of Scale
In the world of distributed databases, "scale" is not just about adding more hardware; it is about how data is organized to allow for horizontal growth. Azure Cosmos DB is a globally distributed, multi-model database service designed to provide single-digit millisecond latency at any scale.
The secret to this performance lies in Partitioning. Unlike relational databases where you might struggle with vertical scaling (buying a bigger server), Cosmos DB uses partitioning to distribute your data across multiple physical partitions. Understanding how to design your partition key is the single most important decision you will make when building on Cosmos DB, as it directly dictates both your performance and your cost (Throughput).
The Mechanics of Partitioning
What is a Partition Key?
A partition key is a property (or set of properties) within your document that Cosmos DB uses to determine which logical partition a document belongs to.
- Logical Partition: A grouping of items that share the same partition key value.
- Physical Partition: The internal infrastructure managed by Azure that stores your logical partitions.
When you perform a read or write operation, the database uses the partition key to route the request directly to the specific physical node holding that data. If your partition key is well-designed, your database can handle millions of requests per second by spreading the load evenly across many physical nodes.
Throughput (Request Units - RUs)
Cosmos DB measures the cost of operations in Request Units (RUs). RUs represent a currency that abstracts CPU, IOPS, and memory.
- Provisioned Throughput: You reserve a specific number of RUs per second for your container.
- The Distribution Problem: If you provision 1,000 RUs/s for a container, those 1,000 RUs are distributed equally across all physical partitions. If one partition holds 90% of your data (a "Hot Partition"), you will hit a 429 "Too Many Requests" error on that partition, even if the rest of your database is idle.
Practical Examples: Choosing a Partition Key
Scenario 1: The "High Cardinality" Approach (Recommended)
Imagine an E-commerce system storing Orders.
- Poor Choice:
State(e.g., "CA", "NY"). There are only 50 states. If 30% of your customers are in California, that partition will be significantly busier than others. - Great Choice:
OrderId. Every order is unique. This ensures that every order goes to a different logical partition, distributing the load perfectly across the entire cluster.
Scenario 2: The "Multi-Tenant" Approach
If you are building a SaaS application, you likely want to isolate data by TenantId.
- Best Practice: Use
TenantIdas your partition key. This allows you to perform queries scoped to a single tenant efficiently, which is the most common pattern in SaaS applications.
Code Snippet: Defining a Container with a Partition Key
When using the Azure Cosmos DB .NET SDK, you define the partition key during container creation:
// Define the partition key path
string partitionKeyPath = "/tenantId";
// Create the container
ContainerResponse response = await database.CreateContainerIfNotExistsAsync(
id: "OrdersContainer",
partitionKeyPath: partitionKeyPath,
throughput: 400 // Provisioned RUs
);
Best Practices
- High Cardinality is King: Choose a partition key with a wide range of values. The more unique values, the better the distribution.
- Avoid Hot Partitions: Monitor your metrics in the Azure Portal. If you see one partition consistently using more RUs than others, your partition key is skewed.
- Query Scoping: Always include the partition key in your query filters whenever possible. A "Cross-Partition Query" (where you don't provide the partition key) must be sent to every physical partition, which is significantly more expensive and slower.
- Synthetic Keys: If you don't have a natural high-cardinality property, create a synthetic one. For example, concatenate
UserId+Timestampto create a unique key ifUserIdalone results in partitions that are too large.
Common Pitfalls
- The "Big Data" Trap: Do not pick a partition key that results in a logical partition growing beyond 20 GB. If a single logical partition exceeds this, you will be unable to add more data to it.
- Over-provisioning: Don't just provision 100,000 RUs because "it's fast." Calculate your expected read/write patterns and use the Cosmos DB Capacity Planner to estimate costs.
- Updating the Partition Key: You cannot change the partition key once a container is created. Choosing the wrong key requires migrating all your data to a new container. Choose carefully at the start.
π‘ Pro Tip: The "Right-Sized" Partition
A good rule of thumb is that your partition key should allow for a high volume of operations while keeping the logical partition size under 20GB. Aim for a distribution where your RU load is spread as evenly as possible across the container's physical partitions.
Key Takeaways
- Partitioning is foundational: It is the mechanism that allows Cosmos DB to scale horizontally.
- Choose Cardinality: A high-cardinality partition key (like
OrderIdorDeviceId) is almost always superior to low-cardinality keys (likeStatusorCountry). - Optimize for Queries: While distribution is vital, ensure your partition key aligns with your most frequent query patterns to avoid expensive cross-partition scans.
- Monitor for Skew: Use the Azure Portal to watch for "Hot Partitions" and adjust your strategy if one partition begins to dominate your RU consumption.
- Immutability: Since partition keys cannot be changed post-creation, spend extra time during the design phase modeling your data access patterns.
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- β Fewer advertisements
- β 2Γ daily points limit
- β Distraction-free lessons