2.1.2. Request Units, Indexing Policies, and Consistency Levels
💡 First Principle: Every RU-optimization lever works by reducing work the engine must do: indexing policy reduces what writes must update, consistency level reduces how many replicas a read must confirm, and throughput mode matches capacity to demand. There's no magic — just less work, fewer RUs.
Throughput comes in three purchasing models: provisioned manual (fixed RU/s — cheap for steady load), autoscale (scales between 10% and 100% of a max — for spiky AI workloads), and serverless (pay per operation — for dev or infrequent traffic). When demand exceeds provisioned RU/s, requests fail with HTTP 429 (Too Many Requests) and a retry-after hint; the SDK retries automatically, but sustained 429s mean you've under-provisioned or over-spent per operation.
By default, Cosmos DB indexes every path in every item. Convenient — any query works out of the box — but every indexed path adds RU cost to every write. The indexing policy lets you flip the economics with includedPaths and excludedPaths:
{
"indexingMode": "consistent",
"includedPaths": [{ "path": "/userId/?" }, { "path": "/timestamp/?" }],
"excludedPaths": [{ "path": "/*" }, { "path": "/embedding/*" }]
}
This "exclude everything, include what you query" pattern can cut write RU dramatically — and excluding the embedding array is essential, because vectors are indexed separately (Section 2.1.3). Composite indexes handle multi-property ORDER BY queries that single-property indexes can't serve.
Consistency levels control the read-side work. The table below is exam-critical — know the guarantees, the relative cost, and the canonical use case for each level.
| Level | Guarantee | Read RU cost | Typical use |
|---|---|---|---|
| Strong | Always latest committed write, globally | 2x | Financial/inventory truth |
| Bounded staleness | Lag bounded by K versions or T time | 2x | Global apps needing near-strong reads |
| Session (default) | Read-your-own-writes within a session token | 1x | User-facing apps (chat history) |
| Consistent prefix | Reads never see out-of-order writes | 1x | Event/state streams |
| Eventual | Replicas converge eventually; no ordering | 1x | Counters, likes, telemetry |
Session is the default for good reason: each user sees their own writes immediately, at half the read cost of strong. Building on the currency model from 2.1 — strong consistency makes every read confirm with a replica quorum, and that extra work is exactly why it bills double.
⚠️ Exam Trap: "Choose the strongest consistency to be safe" costs you double RUs and added latency on every read. When a scenario says users must see their own messages immediately — that's Session, not Strong. Strong is only right when all users must see all writes immediately, worldwide.
Reflection Question: A write-heavy logging container queries only two properties. What indexing policy change cuts costs, and why does it affect writes rather than reads?