Installs into .claude/skills of the current project.
Are you the author of Cosmosdb?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-cosmosdb)
---
name: cosmosdb
description: "Azure Cosmos DB expert. Deep expertise in multi-model APIs (NoSQL, MongoDB, Cassandra, Gremlin, Table), partitioning, consistency levels, RU optimization, global distribution, and operational tuning. WHEN: \"Cosmos DB\", \"CosmosDB\", \"Cosmos\", \"Request Units\", \"RU/s\", \"partition key Cosmos\", \"consistency level\", \"global distribution\", \"multi-region writes\", \"Cosmos DB NoSQL\", \"Cosmos DB MongoDB\", \"change feed\", \"Cosmos DB serverless\"."
license: MIT
---
# Azure Cosmos DB
This skill covers Azure Cosmos DB, Microsoft's globally distributed, multi-model database service. It covers all supported APIs (NoSQL, MongoDB, Cassandra, Gremlin, Table), partitioning internals, consistency models, Request Unit economics, global distribution, change feed, and operational tuning. Cosmos DB is a fully managed service with no user-facing version numbers -- all accounts run the latest platform release.
## How to Approach Tasks
When you receive a request:
1. **Classify** the request:
- **Architecture/internals** -- Load `references/architecture.md`
- **Performance diagnostics** -- Load `references/diagnostics.md`
- **Configuration/operations** -- Load `references/best-practices.md`
- **Comparison with other databases** -- see the `overview` skill
2. **Determine the API** -- Ask if unclear. Behavior differs significantly across APIs (NoSQL vs MongoDB vs Cassandra vs Gremlin vs Table). The NoSQL (Core SQL) API is the most feature-complete and most commonly used.
3. **Analyze** -- Apply Cosmos DB-specific reasoning. Reference the partition model, RU economics, consistency level trade-offs, and global distribution implications as relevant.
4. **Recommend** -- Provide actionable guidance with specific Azure CLI commands, SDK code, indexing policies, or configuration changes.
5. **Verify** -- Suggest validation steps (Azure Monitor metrics, diagnostic logs, SDK diagnostics, partition key statistics).
## Core Expertise
### Multi-Model APIs
Cosmos DB exposes multiple wire-protocol-compatible APIs. Each API stores data in the same underlying atom-record-sequence (ARS) engine but presents a different data model:
| API | Data Model | Wire Protocol | Best For |
|---|---|---|---|
| **NoSQL (Core SQL)** | JSON documents | REST / SQL-like query | New applications, full Cosmos DB feature access, flexible schema |
| **MongoDB** | BSON documents | MongoDB wire protocol (v4.2/5.0/6.0/7.0) | Lift-and-shift from MongoDB, existing MongoDB drivers |
| **Cassandra** | Wide-column | CQL wire protocol | Lift-and-shift from Apache Cassandra |
| **Gremlin** | Graph (vertices/edges) | Apache TinkerPop Gremlin | Relationship-heavy data, graph traversals |
| **Table** | Key-value (schemaless) | Azure Table Storage protocol | Simple key-value, migration from Azure Table Storage |
**Key decision:** Use the NoSQL API for new projects unless you have an existing codebase on MongoDB/Cassandra/Gremlin. The NoSQL API exposes every Cosmos DB feature first and has the richest SDK support.
### Partitioning
Partitioning is the most critical design decision in Cosmos DB. It determines data distribution, query performance, and throughput scalability.
**Logical partition:** All items sharing the same partition key value. Maximum size: 20 GB. All queries scoped to a single logical partition are efficient single-partition queries.
**Physical partition:** The underlying storage and compute unit. Each physical partition supports up to ~10,000 RU/s and 50 GB of storage. Physical partitions are managed transparently by the platform.
**Partition key selection rules:**
- Choose a property with high cardinality (many distinct values)
- Choose a property that distributes reads AND writes evenly
- Choose a property frequently used in WHERE clauses
- Avoid keys that create "hot partitions" (e.g., a date field where all current writes go to today)
- Common good keys: `tenantId`, `userId`, `deviceId`, `categoryId`
- Common bad keys: `status` (low cardinality), `createdDate` (write-hot), `region` (low cardinality)
**Hierarchical partition keys** allow up to three levels of partition key (e.g., `/tenantId/userId/sessionId`). This is useful when a single key does not provide sufficient cardinality or when you need sub-partitioning within a logical partition.
**Cross-partition queries** fan out to all physical partitions. They are slower and consume more RUs. Design your data model so that the most frequent queries target a single partition.
### Consistency Levels
Cosmos DB offers five consistency levels, from strongest to weakest:
| Level | Guarantee | Read Latency | Write Latency | RU Cost (reads) | Use Case |
|---|---|---|---|---|---|
| **Strong** | Linearizability. Reads return the most recent committed write. | Higher (quorum read from multiple regions) | Higher | 2x | Financial transactions, inventory counts |
| **Bounded Staleness** | Reads lag behind writes by at most K versions or T seconds. | Moderate | Moderate | 2x | Leaderboards, near-real-time analytics |
| **Session** | Within a session: read-your-writes, monotonic reads, monotonic writes. Across sessions: consistent prefix. | Low | Low | 1x | Default. Best for most applications. User-facing apps. |
| **Consistent Prefix** | Reads never see out-of-order writes. No staleness bound. | Low | Low | 1x | Social feeds, event sourcing where order matters |
| **Eventual** | No ordering guarantee. Reads may see any committed write. | Lowest | Lowest | 1x | Counters, likes, non-critical aggregations |
**Key trade-offs:**
- Strong and Bounded Staleness cost 2x RUs for reads (quorum reads)
- Strong consistency is not available with multi-region writes
- Session consistency is the default and recommended for most workloads
- The consistency level is set at the account level but can be relaxed per-request (never strengthened)
### Request Units (RUs)
Every Cosmos DB operation consumes Request Units. An RU is a blended measure of CPU, IOPS, and memory:
- A point read (GET by id + partition key) of a 1 KB item costs 1 RU
- A point write of a 1 KB item costs ~5.3 RUs
- Query cost depends on: result set size, number of partitions touched, query complexity, index utilization
- Cross-partition queries cost more than single-partition queries
- Larger documents cost more RUs (roughly proportional to size)
**RU optimization strategies:**
1. Use point reads (`ReadItem` by id + partition key) instead of queries whenever possible -- 1 RU vs potentially hundreds
2. Use the right consistency level -- Strong/Bounded Staleness doubles read RU cost
3. Optimize indexing policy -- exclude unused paths, use composite indexes for ORDER BY
4. Minimize cross-partition queries through good partition key design
5. Project only needed fields in queries (SELECT c.name, c.email instead of SELECT *)
6. Use pagination with continuation tokens for large result sets
7. Avoid high fan-out queries (queries with no partition key filter)
### Capacity Modes
| Mode | How It Works | Best For | Limits |
|---|---|---|---|
| **Provisioned throughput** | Pre-allocate fixed RU/s per container or database. Billed hourly. | Predictable, sustained workloads | Min 400 RU/s per container |
| **Autoscale** | Automatically scales between 10% and 100% of configured max RU/s. | Variable workloads with predictable peaks | Min max-RU/s: 1,000 |
| **Serverless** | Pay per RU consumed. No pre-provisioning. | Dev/test, sporadic traffic, low-throughput apps | Max 5,000 RU/s burst, 1 TB storage, single region only |
**Provisioned throughput** can be set at the database level (shared across containers) or at the container level (dedicated). Database-level throughput distributes RU/s across containers with a minimum of 100 RU/s per container.
### Change Feed
Change feed provides a persistent, ordered log of all inserts and updates (and, with all-versions-and-deletes mode, deletes) to a container:
- **Latest version mode (default):** Captures the latest version of each changed item. Does not capture deletes or intermediate versions.
- **All versions and deletes mode:** Captures all changes including deletes. Requires continuous backup. Retention limited to the continuous backup retention period.
**Processing models:**
- **Change feed processor (push model):** SDK-based processor that distributes change feed partitions across consumer instances. Handles lease management, load balancing, checkpointing. Recommended for most scenarios.
- **Pull model:** Manual control over reading changes with `FeedIterator`. Use when you need fine-grained control.
- **Azure Functions trigger:** Serverless processing using the change feed processor under the hood.
### Indexing
By default, Cosmos DB automatically indexes every property in every document. You can customize the indexing policy:
**Index types:**
- **Range index** -- Default for all paths. Supports equality, range, ORDER BY, and system functions.
- **Spatial index** -- For geospatial queries (ST_DISTANCE, ST_WITHIN, ST_INTERSECTS).
- **Composite index** -- Required for ORDER BY on multiple properties, and optimizes multi-property filters.
- **Vector index** -- For vector similarity search (flat, quantizedFlat, diskANN).
**Indexing policy tuning:**
```json
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{ "path": "/frequently_queried_field/?" },
{ "path": "/another_field/?" }
],
"excludedPaths": [
{ "path": "/large_blob_field/?" },
{ "path": "/rarely_queried/*" },
{ "path": "/_etag/?" }
],
"compositeIndexes": [
[
{ "path": "/category", "order": "ascending" },
{ "path": "/timestamp", "order": "descending" }
]
]
}
```
**Key rule:** Excluding paths that are never queried saves RUs on writes and reduces index storage.
### Global Distribution
Cosmos DB replicates data across Azure regions with single-digit-millisecond latency at the 99th percentile:
- Add or remove regions at any time with no downtime
- **Single-region writes:** One write region, zero or more read regions. Automatic failover if write region goes down.
- **Multi-region writes:** All regions accept writes. Lower write latency (writes go to nearest region). Requires conflict resolution policy.
**Conflict resolution (multi-region writes):**
- **Last Writer Wins (LWW):** Default. Uses a configurable conflict resolution path (default: `_ts`). Highest value wins.
- **Custom (stored procedure):** A stored procedure that merges conflicting writes. Called on conflicts only.
### Transactions and Batch Operations
- **Transactional batch:** Atomic operations on items within the same logical partition. Up to 100 operations or 2 MB total. All-or-nothing semantics. Supported in NoSQL API.
- **Cross-partition transactions are NOT supported.** Design your data model so that items that need transactional consistency share a partition key.
- **Stored procedures:** JavaScript functions that execute atomically within a single logical partition. Can read and write multiple items transactionally. Bounded execution time.
- **Pre-triggers and post-triggers:** Execute before/after a create, replace, or delete operation.
- **User-defined functions (UDFs):** JavaScript functions callable from SQL queries for custom computation.
### Security
- **Azure RBAC (data plane):** Fine-grained role-based access control for Cosmos DB operations using AAD/Entra ID identities. Built-in roles: Cosmos DB Built-in Data Reader, Cosmos DB Built-in Data Contributor, plus custom role definitions.
- **Master keys:** Primary and secondary read-write keys plus read-only keys. Rotate regularly.
- **Resource tokens:** Scoped, time-limited tokens for per-user or per-partition access.
- **Microsoft Entra ID (AAD) authentication:** Recommended over master keys for production.
- **Customer-managed keys (CMK):** Encrypt data at rest with keys stored in Azure Key Vault.
- **Always Encrypted:** Client-side encryption for sensitive fields.
- **Private endpoints:** Access Cosmos DB over Azure Private Link, keeping traffic on the Microsoft backbone.
- **IP firewall and VNet service endpoints:** Restrict access by IP range or virtual network.
### Backup and Restore
- **Continuous backup (PITR):** Point-in-time restore to any second within the retention window. Two tiers:
- **7-day retention** (continuous7days): Default for new accounts
- **30-day retention** (continuous30days): Extended retention
- **Periodic backup:** Legacy mode. Full backup snapshots at configured intervals (1-24 hours). Retention of 2+ copies. Restore requires support ticket.
- **Restore:** Creates a new account from the backup. You cannot restore into an existing account.
### Cost Optimization Strategies
1. **Right-size throughput:** Use autoscale for variable workloads, provisioned for steady workloads, serverless for dev/test
2. **Reserved capacity:** 1-year or 3-year reservations for 20-65% discount on provisioned throughput
3. **Optimize partition key:** Avoid hot partitions that force over-provisioning
4. **Tune indexing policy:** Exclude paths not used in queries to reduce write RU cost and index storage
5. **Use point reads over queries:** 1 RU vs potentially hundreds
6. **Minimize document size:** Shorter property names, remove unused fields
7. **TTL (Time to Live):** Automatically expire old data at no extra RU cost (delete operations consume no RUs when driven by TTL)
8. **Use integrated cache:** For read-heavy workloads with dedicated gateway, reduces RU consumption for repeated reads
9. **Analyze with Azure Monitor:** Identify containers with low utilization or high 429 rates
## NoSQL (Core SQL) Query Language
The Cosmos DB NoSQL API uses a SQL-like query language over JSON documents. It is NOT standard SQL -- it operates on hierarchical JSON, not relational tables.
**Key differences from SQL:**
- No `JOIN` between containers -- `JOIN` is intra-document (self-join over arrays within a single document)
- No `GROUP BY` with `HAVING` (use subqueries or client-side aggregation for complex groupings)
- `SELECT *` returns the entire JSON document, not columns
- Functions: `CONTAINS()`, `STARTSWITH()`, `ENDSWITH()`, `ARRAY_CONTAINS()`, `IS_DEFINED()`, `IS_NULL()`
- Aggregates: `COUNT`, `SUM`, `AVG`, `MIN`, `MAX` (single partition is efficient; cross-partition aggregates fan out)
- Geospatial: `ST_DISTANCE()`, `ST_WITHIN()`, `ST_INTERSECTS()` with spatial indexes
- Pagination via continuation tokens (not `OFFSET/LIMIT` for large datasets)
**Common query patterns:**
```sql
-- Single-partition query (efficient)
SELECT c.id, c.name, c.email
FROM c
WHERE c.tenantId = 'tenant-1' AND c.status = 'active'
-- Intra-document JOIN (iterate over embedded arrays)
SELECT c.id, item.name, item.price
FROM c
JOIN item IN c.lineItems
WHERE c.tenantId = 'tenant-1' AND item.price > 100
-- Aggregate with GROUP BY
SELECT c.category, COUNT(1) AS cnt, SUM(c.amount) AS total
FROM c
WHERE c.tenantId = 'tenant-1'
GROUP BY c.category
-- Geospatial query
SELECT c.name, ST_DISTANCE(c.location, {"type":"Point","coordinates":[-73.99,40.73]}) AS dist
FROM c
WHERE ST_DISTANCE(c.location, {"type":"Point","coordinates":[-73.99,40.73]}) < 5000
```
## Vector Search
Cosmos DB supports vector similarity search in the NoSQL API for AI/ML workloads:
- Store vector embeddings alongside regular document properties
- Index types: `flat` (brute-force, exact), `quantizedFlat` (compressed, approximate), `diskANN` (graph-based, approximate, best for large-scale)
- Similarity metrics: cosine, dot product, Euclidean
- Use the `VectorDistance()` function in queries
**Container vector policy example:**
```json
{
"vectorEmbeddings": [
{
"path": "/embedding",
"dataType": "float32",
"distanceFunction": "cosine",
"dimensions": 1536
}
]
}
```
**Vector index in indexing policy:**
```json
{
"vectorIndexes": [
{ "path": "/embedding", "type": "diskANN" }
]
}
```
**Vector search query:**
```sql
SELECT TOP 10 c.id, c.title, VectorDistance(c.embedding, [0.1, 0.2, ...]) AS score
FROM c
ORDER BY VectorDistance(c.embedding, [0.1, 0.2, ...])
```
## Analytical Store (Azure Synapse Link)
Cosmos DB offers an auto-synced column store for analytics:
- Transactional data is automatically synced to the analytical store (no ETL)
- Analytical store is column-oriented, optimized for aggregation queries
- Queryable from Azure Synapse Analytics (Spark, SQL serverless)
- No impact on transactional workload RU consumption
- Separate TTL for analytical store (can retain longer than transactional TTL)
Enable analytical store on a container:
```bash
az cosmosdb sql container create \
--account-name mycosmosaccount \
--resource-group myrg \
--database-name mydatabase \
--name mycontainer \
--partition-key-path "/tenantId" \
--analytical-storage-ttl -1
```
## Data Modeling Guidelines
### When to Embed vs Reference
**Embed (denormalize):**
- Data is read together (e.g., order + line items)
- Bounded one-to-few relationships (e.g., user + addresses)
- Data changes together (single transactional batch)
- Document stays under the 2 MB item size limit
**Reference (normalize across documents):**
- Unbounded one-to-many (e.g., user + all orders over years)
- Data is shared across many parents (e.g., product referenced by many orders)
- Data is updated independently and frequently
- Would exceed 2 MB item limit if embedded
**Hybrid pattern:** Embed frequently-read summary data; store full details as separate items. Use change feed to keep denormalized copies in sync.
### Multi-Entity Container Pattern
Store multiple entity types in the same container with a `type` discriminator:
```json
{"id": "user-123", "pk": "tenant-1", "type": "user", "name": "Jane", ...}
{"id": "order-456", "pk": "tenant-1", "type": "order", "userId": "user-123", ...}
{"id": "invoice-789", "pk": "tenant-1", "type": "invoice", "orderId": "order-456", ...}
```
Benefits: Single-partition transactions across entity types, efficient point reads, shared throughput. Use the `type` field in WHERE clauses to filter.
## SDK Connection Modes
| Mode | Protocol | Best For | Notes |
|---|---|---|---|
| **Direct** | TCP (proprietary) | Production. Lowest latency, highest throughput. | Default in .NET v3+ and Java v4+. Connects directly to partition replicas. |
| **Gateway** | HTTPS via gateway service | Restricted networks (firewall allows only HTTPS/443) | Adds a hop. Higher latency. Required for some environments. |
**Always use Direct mode in production** unless network restrictions prevent it. Direct mode uses a pool of TCP connections to partition replicas, eliminating the gateway hop.
## Common Troubleshooting Patterns
### 429 (Request Rate Too Large) Errors
The most common Cosmos DB issue. Caused by exceeding provisioned RU/s:
1. Check `NormalizedRUConsumption` metric in Azure Monitor -- if consistently at 100%, throughput is saturated
2. Check per-partition RU consumption -- a hot partition can cause 429s even when total RU/s is under limit
3. Solutions: increase RU/s, switch to autoscale, optimize queries, improve partition key distribution, implement SDK retry with exponential backoff
### High Latency
1. Check physical distance between client and Cosmos DB region -- use multi-region with preferred region closest to client
2. Check `NormalizedRUConsumption` -- throttling causes queuing and latency spikes
3. Check query execution metrics (`x-ms-request-charge`, `x-ms-documentdb-query-metrics`) -- high RU queries indicate missing composite indexes or cross-partition fan-out
4. Check SDK connection mode -- use Direct mode (not Gateway) for lowest latency in .NET/Java
5. Check for large documents or large result sets causing serialization overhead
### Cross-Partition Query Performance
1. Check if the query includes a partition key filter -- without it, query fans out to all partitions
2. Add a composite index for ORDER BY queries spanning multiple fields
3. Consider data model redesign to co-locate frequently joined data
4. Use `FeedOptions.PartitionKey` in SDK to force single-partition execution when possible
5. Monitor `x-ms-documentdb-query-metrics` for per-partition RU breakdown
### Partition Splits and Data Skew
1. Monitor physical partition count via `PhysicalPartitionCount` metric
2. Check partition key statistics in the portal or via REST API
3. If one partition is much larger or hotter than others, consider hierarchical partition keys or a different partition key
4. After a split, throughput is automatically redistributed -- monitor for transient 429s during splits