DP-900: Azure Cosmos DB Deep Dive (Partitions, RUs, Consistency, APIs)

Cosmos DB resource structure and use cases, good partition keys and hot partitions, what drives RU consumption, provisioned vs autoscale vs serverless, multi-region writes and the five consistency levels, and how to pick among the five APIs for DP-900.

Domain 3 of the official DP-900 skills outline includes "Identify use cases for Azure Cosmos DB" and "Describe Azure Cosmos DB APIs." Real exam questions go one step further and often ask how to choose a partition key, what request units (RUs) depend on, whether serverless or autoscale fits a workload, and how the five consistency levels differ.

This post is a supplementary entry to Non-relational Data Fundamentals in our DP-900 study series. It takes the RUs, partition keys, consistency levels, and API list introduced there and expands them to the level you need for exam questions, in this order: resource structure, partition design, throughput modes, global distribution and consistency, and how to choose an API.

---

 

What Kind of Database Is Cosmos DB?

Picture a convenience store chain with branches all over the world. The product list set by headquarters is replicated to every branch, so customers buy from the nearest one. Azure Cosmos DB is a fully managed NoSQL database (PaaS) built the same way: data is replicated to the Azure regions you choose, and users read and write against the nearest replica.

Cosmos DB is schema-agnostic. Items in the same container can have different numbers of properties and different structures, and by default every property is indexed automatically, so you do not have to define a schema or indexes in advance. Data is organized in a four-level structure.

| Level | Role | |------|------| | Account | The top-level Azure resource; sets the API, regions, and default consistency | | Database | A logical namespace that groups related containers | | Container | The basic unit of storage and scaling; partition key, throughput, indexing policy, and TTL are set here | | Item | An individual piece of data, called a document, row, node, or edge depending on the API |

Cosmos DB fits apps that need a flexible schema, global users, and consistently low latency. Typical examples are IoT and telemetry ingestion, player profiles and leaderboards in games, product catalogs and shopping carts in online stores, and personalization in web and mobile apps. On the other hand, if you need complex joins across many tables, Azure SQL Database is a better fit, and for large-scale analytics, Microsoft Fabric is.

Exam tip: "Single-digit-millisecond responses for users worldwide, JSON data whose schema changes often" → Cosmos DB. "An order system with many multi-table joins" → Azure SQL Database, not Cosmos DB.

---

 

Partition Keys: Where Scaling Starts

Data in a container is divided into logical partitions according to the partition key value. Items with the same partition key value form one logical partition, and Cosmos DB spreads logical partitions across internal physical partitions to grow storage and throughput.

A single logical partition can store up to 20 GB. A physical partition handles up to 10,000 RU per second, so a single logical partition cannot exceed that limit either. Provisioned throughput is divided evenly across physical partitions. If requests pile up on a few partitions, those become hot partitions, and requests can be rate-limited even though throughput is left unused elsewhere. Once you choose a partition key, you cannot change it in place. To change it, you create a new container and move the data.

| Good partition key | Poor partition key | |------|------| | Many distinct values (user ID, device ID, order ID) | Only a handful of values (status, type, country) | | Storage and requests spread evenly across values | Data and requests concentrate on certain values | | Appears in the filters of frequent queries | Every query has to scan all partitions |

If the data for one key value might exceed 20 GB, hierarchical partition keys let you stack up to three levels of keys (for example, tenant ID → user ID) to spread the data more evenly.

Exam tip: "The best property to use as a partition key" → one with many distinct values that are evenly distributed. "Requests are rejected even though throughput is left over, because they concentrate on a few partitions" → hot partition.

---

 

Request Units (RUs) and Throughput Modes

What Affects RU Consumption

A request unit (RU) is Cosmos DB's performance currency, rolling CPU, IOPS, and memory into one number. A point read of a single item of about 1 KB by its ID and partition key costs 1 RU, and every operation, including writes, queries, and deletes, is measured in RUs.

| Factor | Effect on RUs | |------|------| | Item size | Larger items cost more RUs to read and write | | Indexing | Every property is indexed by default; excluding some lowers write RUs | | Property count | More properties cost more RUs to write | | Consistency level | Strong and bounded staleness use about twice the RUs for reads | | Query complexity | More results, predicates, and functions cost more |

Throughput Modes

| Mode | How it works | Best fit | |------|------|------| | Provisioned throughput (manual) | Reserve RU/s in advance, either dedicated to a container or shared at the database level (up to 25 containers) | Steady, predictable traffic | | Autoscale | Set a maximum RU/s and it adjusts instantly between 10% and 100% of that value | Traffic with peaks, where you can set an upper limit | | Serverless | Nothing to provision; you pay for the RUs you consume; single-region accounts only | Intermittent, unpredictable, low traffic, development and testing |

For example, if you set the autoscale maximum to 20,000 RU/s, throughput moves between 2,000 and 20,000 RU/s. Serverless accounts cannot be distributed across regions, so if you need global distribution you must use provisioned throughput.

Exam tip: "A development app used only now and then, paying only for what you use" → serverless. "Traffic that is quiet most of the time but surges during events, with a maximum RU/s set" → autoscale. "Replicate to multiple regions" → not possible with serverless.

---

 

Global Distribution and the Five Consistency Levels

Multi-Region Writes

You can add Azure regions to an account at any time; data is replicated automatically and users read from the nearest regional replica. With multi-region writes enabled, writes are handled in the nearest region too. Accounts with multi-region writes have a 99.999% availability SLA, and both reads and writes are guaranteed to complete in under 10 milliseconds at the 99th percentile.

Consistency Levels

When replicas live in several regions, you have to decide when a value just written becomes visible in other regions. Cosmos DB offers this trade-off in five levels.

!The five consistency levels of Azure Cosmos DB

| Level | What it guarantees | Analogy | |------|------|------| | Strong | Every read reflects the most recent write | A live broadcast | | Bounded staleness | Reads lag behind by at most a set time or number of versions | A broadcast with at most a five-minute delay | | Session | Within one client session, you read your own writes immediately | The comment you post shows up on your screen right away | | Consistent prefix | Writes never appear out of order, but may not be the latest | A rerun that arrives episode by episode in order | | Eventual | All replicas converge over time; highest availability | A postcard that arrives eventually |

The default consistency is set per account, and individual requests can relax it to a weaker level when needed. Session is the most widely used level for both single-region and globally distributed apps.

Exam tip: "A user must see the profile they just edited right away" → Session. "Reads must always return the latest value" → Strong. "Highest availability and lowest latency, slightly stale values are fine" → Eventual. "Delay is acceptable, but the order must never change" → Consistent prefix.

---

 

Choosing an API

You choose the API when you create the account, and it determines the data format, query language, and client libraries your application uses. Internal storage is the same; the API acts as an abstraction layer on top.

| API | Data model | Query language | Choose it when | |------|------|------|------| | NoSQL | JSON documents | SQL-like syntax | The default for new apps; the native API (formerly called the SQL API) | | MongoDB | BSON documents | MongoDB Query Language (MQL) | You want to keep using MongoDB drivers and experience | | Table | Key-value | OData-style key lookups | Moving an Azure Table Storage app that needs more performance and global distribution | | Apache Cassandra | Column family | CQL | Moving an existing Cassandra workload to a managed service | | Apache Gremlin | Graph (vertices and edges) | Gremlin | Relationships are central, as in social networks, recommendations, fraud detection, or org charts |

Keep a few recent changes in mind as well. Azure Cosmos DB for PostgreSQL is on a retirement path and is not recommended for new projects; the alternatives are elastic clusters in Azure Database for PostgreSQL for PostgreSQL workloads and Cosmos DB for NoSQL for NoSQL workloads. To migrate an existing MongoDB app with the full set of MQL features, Microsoft recommends a separate service, Azure DocumentDB. Cosmos DB for NoSQL supports Fabric mirroring, which replicates operational data into Microsoft Fabric without ETL so you can analyze it without consuming RUs.

Exam tip: "Traverse the nodes and relationships of a graph" → Gremlin. "Cassandra Query Language (CQL)" → Apache Cassandra. "The native Cosmos DB API, JSON plus SQL-like queries" → NoSQL.

---

 

Practice with Scenarios

Decide on your answer first, then check the columns on the right.

| Situation | Answer | Why | |------|------|------| | The order container uses "order status" as its partition key, and only a few partitions are busy | Hot partition; redesign with a high-cardinality key | A key with only a few values | | You want to change the partition key of a container in production | Create a new container and move the data | A partition key c

Back to blog list