Cosmos DB fundamentals

Microsoft Azure · Practical · 14 min

Cosmos DB powers low-latency, elastic workloads, but only if you model partitions and RUs correctly.

Azure Cosmos DB is a managed, globally distributed NoSQL database with single-digit millisecond reads. It offers several APIs; NoSQL (JSON documents queried with a SQL-like language) is the native one, with MongoDB, Cassandra, Gremlin and Table APIs for compatibility.

Resource model: account (endpoint, regions, consistency) > database > container (holds items, has a partition key and indexing policy) > item (a JSON document with an id).

Every container has a partition key, a property such as /customerId. Items with the same value form a logical partition (limit 20 GB); Cosmos spreads logical partitions over physical partitions to scale. The id is unique only within its partition, so a point read needs both id and partition key and is the cheapest operation.

Cost is measured in request units (RU): a 1 KB point read is 1 RU; writes and queries cost more. You pay for provisioned throughput (manual or autoscale RU/s) or use serverless for intermittent traffic. Requests above your RU/s get HTTP 429 and must be retried (the SDKs do it for you).

All properties are indexed by default; tune the indexing policy to exclude paths you never filter on, which lowers write RU. Data-plane access with Entra ID uses Cosmos DB's own data-plane roles, assigned with az cosmosdb sql role assignment create.

Example

# pip install azure-cosmos azure-identity
from azure.cosmos import CosmosClient, PartitionKey
from azure.identity import DefaultAzureCredential

client = CosmosClient("https://cosmos-orders.documents.azure.com:443/", DefaultAzureCredential())
db = client.get_database_client("shop")
orders = db.get_container_client("orders")       # partition key: /customerId

orders.upsert_item({"id": "o-1001", "customerId": "c-42", "total": 59.90, "status": "paid"})

item = orders.read_item(item="o-1001", partition_key="c-42")   # point read, ~1 RU
print(item["total"])  # 59.9

rows = orders.query_items(
    "SELECT c.id, c.total FROM c WHERE c.customerId = @cid AND c.status = 'paid'",
    parameters=[{"name": "@cid", "value": "c-42"}], partition_key="c-42")
print([r["id"] for r in rows])   # ['o-1001']

Remember

  • Account > database > container > item
  • Partition key choice drives scale; a logical partition is capped at 20 GB
  • Point reads (id + partition key) are the cheapest operation
  • Throughput is RU/s; 429 means throttled, retry

Watch out for

  • Querying without the partition key, which fans out to every physical partition and burns RUs.

Check yourself

  1. What uniquely identifies an item in a Cosmos DB NoSQL container?
  2. Your app receives HTTP 429 from Cosmos DB. What does it mean?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: learn.microsoft.com/en-us/azure/cosmos-db/introduction