Azure Cosmos DB Overview
Azure Cosmos DB is a globally distributed NoSQL database that trades some relational database features for horizontal scale, multi-region writes, and single-digit millisecond latency anywhere in the world. If you’re building an app that needs to serve users on multiple continents without noticeable lag, Cosmos DB is one of the few services that can handle that out of the box.
What makes Cosmos DB different
Traditional databases are designed around a single location. You put them in a datacenter, and everything connects to that datacenter. When users are far away, they wait. When traffic spikes, you scale up a bigger machine (vertical scaling).
Cosmos DB inverts this model:
- Multi-region by design — add regions in the Portal or CLI and data is replicated there automatically, usually within minutes
- Horizontal scale — throughput and storage scale out across physical partitions, not up to a bigger machine
- Multiple APIs — the same underlying engine supports SQL (NoSQL), MongoDB, Cassandra, Gremlin (graph), and Table APIs
- Tunable consistency — you choose the trade-off between consistency and performance for your workload
The trade-off: Cosmos DB does not support multi-table JOIN queries, stored procedures with complex transactions spanning many records, or the rich analytics capabilities of a data warehouse. It’s optimized for transactional workloads with known access patterns.
Choosing your API
When you create a Cosmos DB account, you choose an API. The API determines how your application talks to Cosmos DB.
| API | Wire protocol | Best for |
|---|---|---|
| NoSQL (SQL API) | Cosmos-native HTTPS/REST | New applications; SQL-like syntax for JSON documents |
| MongoDB | MongoDB wire protocol | Existing MongoDB apps — minimal code changes needed |
| Cassandra | CQL (Cassandra Query Language) | Existing Cassandra apps; wide-column data model |
| Gremlin | TinkerPop Gremlin | Graph data — relationships, social networks, recommendation engines |
| Table | Azure Table Storage API | Migrating from Azure Table Storage; key-value with richer queries |
For new applications, the NoSQL API (also called the SQL API or Core API) is the right default. It has the best SDK support, the most documentation, and access to all Cosmos DB features. The MongoDB API is a close second if your team already knows MongoDB and you want to minimize learning curve.
Consistency levels
When data is replicated across multiple regions, there’s an inherent tension: if you write data in East US and immediately read it in Europe, might you see the old value before the new one has propagated? Cosmos DB gives you five levels to control this trade-off:
| Level | Reads see | Latency | Best for |
|---|---|---|---|
| Strong | Always the latest write | Highest (waits for global confirmation) | Financial transactions, inventory systems |
| Bounded Staleness | At most X versions or T time behind | High | Analytics on near-real-time data |
| Session (default) | Your own writes, others may lag | Low | User-specific data (profile, cart, preferences) |
| Consistent Prefix | In-order, but may lag | Low | Order matters, eventual sync is acceptable |
| Eventual | May see older data, out of order | Lowest | Social media likes, non-critical counts |
Session consistency — the default — is the right choice for most web applications. Within a user’s session, reads always reflect that user’s own writes. Other users’ recent writes might not be visible immediately, which is usually acceptable.
Creating a Cosmos DB account with Azure CLI
# Create a Cosmos DB account with the NoSQL API
az cosmosdb create \
--resource-group my-storage-rg \
--name my-cosmos-account \
--kind GlobalDocumentDB \
--default-consistency-level Session \
--locations regionName=eastus failoverPriority=0 isZoneRedundant=True \
--locations regionName=westus failoverPriority=1 isZoneRedundant=False
# Add a second read region later
az cosmosdb update \
--resource-group my-storage-rg \
--name my-cosmos-account \
--locations regionName=eastus failoverPriority=0 isZoneRedundant=True \
--locations regionName=westus failoverPriority=1 isZoneRedundant=False \
--locations regionName=northeurope failoverPriority=2 isZoneRedundant=False
# Create a database
az cosmosdb sql database create \
--resource-group my-storage-rg \
--account-name my-cosmos-account \
--name myapp-db
# Create a container with 400 RU/s provisioned throughput
az cosmosdb sql container create \
--resource-group my-storage-rg \
--account-name my-cosmos-account \
--database-name myapp-db \
--name products \
--partition-key-path "/categoryId" \
--throughput 400
# View the account details
az cosmosdb show \
--resource-group my-storage-rg \
--name my-cosmos-account \
--output jsonThroughput models: provisioned vs serverless
Cosmos DB has two ways to pay for compute:
- Provisioned throughput — you specify a fixed number of RU/s (minimum 400 per container). You pay whether you use it or not. Best for predictable production traffic. You can also use autoscale (400-4000 RU/s, scaling automatically based on load).
- Serverless — you pay per RU consumed, no minimum. Ideal for development, testing, and bursty low-traffic workloads. Cannot be used with multi-region writes.
# Create a serverless account
az cosmosdb create \
--resource-group my-storage-rg \
--name my-cosmos-serverless \
--kind GlobalDocumentDB \
--capabilities EnableServerless
# Create a container with autoscale throughput (400-4000 RU/s)
az cosmosdb sql container create \
--resource-group my-storage-rg \
--account-name my-cosmos-account \
--database-name myapp-db \
--name orders \
--partition-key-path "/userId" \
--max-throughput 4000Common mistakes
- Choosing Cosmos DB for complex relational queries. Cosmos DB excels at single-document reads and writes with known partition keys. It is not designed for multi-table JOINs, complex GROUP BY aggregations, or ad-hoc analytical queries across millions of records. If those are your primary patterns, use Azure SQL Database or Synapse Analytics instead.
- Not understanding RU costs before launch. A point read of a 1 KB document costs 1 RU. A cross-partition query scanning 1,000 documents costs hundreds of RUs. Running a poorly designed query in production can hit your provisioned throughput ceiling and throttle your application. Test query RU costs in development using the SDK’s response headers before going to production.
- Setting strong consistency on a globally distributed account. Strong consistency requires every write to be confirmed by all regions before returning success. For a 3-region account spanning continents, this adds hundreds of milliseconds of latency to every write. Use session consistency unless you have a genuine requirement for linearizability.
- Creating a provisioned-throughput account for a development database. Even 400 RU/s provisioned throughput has a minimum monthly cost. Use a serverless Cosmos DB account for development and staging environments. Switch to provisioned when you’re ready for production and have measured your throughput needs.
Summary
- Cosmos DB is a globally distributed NoSQL database optimized for low-latency reads and writes across multiple regions simultaneously.
- Choose your API when creating the account — the NoSQL API is the right default for new applications; MongoDB API suits teams migrating existing MongoDB workloads.
- Session consistency is the default and appropriate for most applications; only consider Strong consistency when you genuinely need global linearizability.
- Use serverless throughput for development and low-traffic apps; use provisioned or autoscale throughput for predictable production workloads.
Frequently asked questions
What is Cosmos DB best suited for?
Cosmos DB is best for globally distributed applications that need low latency anywhere in the world, applications with variable or unpredictable query patterns that don't fit neatly into a relational schema, and workloads needing automatic and instant scaling. It is not ideal for complex analytical queries, large-scale ad-hoc reporting, or workloads with complex relational integrity requirements.
What does "globally distributed" mean for Cosmos DB?
You can add Azure regions to your Cosmos DB account and Azure will automatically replicate all your data to every region you add. Reads and writes can be served from the nearest region, giving users low latency regardless of where they are. Adding a region takes minutes and requires no application code changes.
How does Cosmos DB pricing work?
Cosmos DB charges for Request Units (RUs) — a normalized measure of CPU, memory, and I/O consumed per operation — and for storage (GB/month). You provision throughput in RU/s either at the container level (manual or autoscale) or use the serverless model where you pay per RU consumed rather than provisioned. Provisioned throughput is more cost-effective for sustained workloads; serverless suits bursty or low-traffic workloads.