Azure Cosmos DB Pocket Book — Uplatz
50 deep-dive flashcards • Wide layout • Fewer scrolls • 20+ Interview Q&A • Readable code examples
1) What is Azure Cosmos DB?
Globally distributed, multi-model NoSQL database service with elastic scale, low latency, and turnkey replication. APIs: Core (SQL), MongoDB, Cassandra, Gremlin, Table, PostgreSQL (for Hyperscale).
# Provision via Azure Portal / CLI
az cosmosdb create -g rg -n acct
2) Key Concepts
Account → Database → Container (collection/table/graph) → Items. Partition key distributes data; RU/s define throughput. Consistency levels balance latency vs correctness.
pk: /tenantId # common choice
3) Multi-Model
Choose API that matches your app: Core(SQL) for JSON docs+SQL, Mongo API for Mongo drivers, Cassandra API for wide-column, Gremlin for graphs, Table for key/attr.
# Core(SQL) sample item
{ "id":"u1","tenantId":"t1","name":"Ada" }
4) Global Distribution
Add regions for read/write closer to users; enable multi-region writes for active-active. Automatic failover with priorities.
az cosmosdb update -n acct -g rg --locations regionName=eastus
5) Consistency Levels
Strong, Bounded Staleness, Session (default), Consistent Prefix, Eventual. Session gives read-your-writes for a client session.
consistency: "Session"
6) Throughput (RU/s)
RU = normalized cost for reads/writes/query. Provision per container or database, or use autoscale to scale 10%–100% of a max RU.
autoscaleMaxThroughput: 4000
7) Partitioning
Choose a high-cardinality, evenly distributed partition key. Avoid “hot” partitions; model for your access patterns.
/tenantId or /userId over /country
8) Latency Targets
P50 reads < 10ms, writes < 10ms (in-region). Achieve with good PK choice, small docs, and point reads over cross-partition scans.
GET by id+pk faster than query
9) SDKs
First-class SDKs for .NET, Java, Node, Python. Use latest client; enable retries, diagnostics, and connection pooling.
npm i @azure/cosmos
10) Q&A — “When to choose Cosmos DB?”
Answer: Global apps needing low latency, elastic scale, and schema-less JSON; when you need multi-model APIs and turnkey multi-region with SLAs.
11) Containers & Indexing
Every container has an index policy (range/hash). Default indexes all properties. Narrow with included/excluded paths to save RU on writes.
/includePaths: [ "/*" ]
12) SQL (Core) Query Basics
Familiar SELECT/FROM/WHERE with JSON semantics. CROSS JOIN for arrays, UDFs for custom logic, OFFSET/LIMIT for paging (or continuation tokens).
SELECT c.id, c.name FROM c WHERE c.tenantId = @t
13) Point Reads vs Queries
Point read (id + pk) is cheapest and fastest. Queries may fan out across partitions if filter can’t prune. Always parameterize.
container.item(id, pk).read()
14) Cross-Partition Queries
If filter doesn’t include PK or partition-prunable field, RU spikes. Add PK in query or denormalize a filter field at top-level.
SELECT * FROM c WHERE c.tenantId=@t AND c.type="order"
15) Composite Indexes
Needed for ORDER BY on multiple properties and filtering + sorting. Plan these for hot queries to cut RU.
compositeIndexes: [[{"path":"/type","order":"ascending"},{"path":"/ts","order":"descending"}]]
16) Unique Keys
Enforce uniqueness on a path combination within a logical partition. Set at container creation; immutable later.
uniqueKeyPolicy: [{ paths:["/email"] }]
17) TTL (Time-To-Live)
Auto-expire items or entire containers. Great for caches, sessions, ephemeral telemetry.
defaultTtl: 3600 # seconds
18) Change Feed
Ordered log of inserts/updates (and deletes if enabled). Use for event-driven pipelines, CQRS projections, or downstream sync.
ChangeFeedProcessorBuilder(...).Build()
19) Transactions
ACID within a single logical partition using stored procedures or transactional batch. Not cross-partition.
container.items.batch(pk).create(item).replace(item2)
20) Q&A — “How to page efficiently?”
Answer: Use continuation tokens (SDK returns) over OFFSET/LIMIT. Keep page size modest (e.g., 50–200) for predictable RU.
21) Provisioned vs Autoscale
Provisioned: fixed RU/s, predictable cost. Autoscale: scales between 10% and 100% of max; good for spiky traffic.
throughput: { autoscaleMaxThroughput: 20000 }
22) RU Budgeting
Measure RU per operation; design for point reads and PK-aligned queries. Pre-aggregate and store read models for dashboards.
diagnostics.RequestCharge
23) Hot Partition Mitigation
Choose better PK, add synthetic keys (e.g., /tenantId#bucket), randomize prefix, or shard logically into multiple containers.
pk: /tenantId#/day
24) Logical Modeling
Single-table design: store heterogeneous types in one container keyed by tenant/type for co-location and atomic partition operations.
{ "type":"order", "tenantId":"t1", "id":"o1" }
25) Write Patterns
Use bulk executor or SDK bulk mode for high-throughput writes. Batch per partition for efficiency.
container.items.bulk(ops)
26) Read Patterns
Prefer point reads; cache hot docs; use materialized views per query shape. Avoid large cross-partition scans.
GET (id, pk) → cache
27) Multi-Region Writes
Enable multi-master for active-active. Handle conflict resolution (LWW / custom policy).
conflictResolutionPolicy: { mode:"LastWriterWins", conflictResolutionPath:"/ts" }
28) Consistency Tuning
Default Session; raise to Strong for strict reads (higher RU/latency) or lower to Eventual for max performance where OK.
clientOptions: { consistencyLevel:"Session" }
29) Serverless & Free Tier
Serverless charges per request unit consumed; great for dev/test or low-traffic apps. Free tier grants limited RU/GB.
capex → opex by RU
30) Q&A — “How to reduce RU on queries?”
Answer: Filter by PK, add composite indexes, denormalize filter fields, project only needed columns, and page with continuation tokens.
31) SDK (Node.js) Basics
Initialize client, get container, point read, parameterized query. Capture diagnostics for RU/latency insights.
import { CosmosClient } from "@azure/cosmos";
const client = new CosmosClient({ endpoint, key });
const cont = client.database("app").container("users");
const { resource } = await cont.item(id, pk).read();
32) SDK (Python) Basics
Use azure-cosmos; set consistency, retry options, and connection mode. Use async client for high concurrency.
from azure.cosmos import CosmosClient
client = CosmosClient(url, key)
container = client.get_database_client("app").get_container_client("users")
33) Change Feed Processor
Scales across instances, checkpointing via leases in a separate container. Ideal for downstream processing, projections, and ETL.
builder.WithInstanceName("proc").WithLeaseContainer(leaseContainer)
34) Triggers, UDFs, SProcs
JavaScript logic in the engine. Use sparingly; they run within partition and can affect RU/latency. Prefer app-side where possible.
CREATE FUNCTION udf_norm(s) { return s.toLowerCase(); }
35) Security & Network
Use Azure AD RBAC, Managed Identity, Private Endpoints, and CMK encryption if needed. Disable public network when possible.
firewall: denyAll; privateLink: enabled
36) Backups & PITR
Periodic or continuous backup with point-in-time restore (PITR). Set retention based on RPO/RTO.
backupPolicy: { type:"Continuous", retention:30d }
37) Observability Hooks
Enable SDK diagnostics, App Insights tracing, custom metrics (RU, latency, throttles, hot partitions). Correlate with request IDs.
clientOptions: { userAgentSuffix:"app/1.2.3" }
38) Throttling & Retries
429 means RU exhausted; SDK backs off automatically. Log and consider raising throughput or optimizing queries.
if (err.code===429) await sleep(err.retryAfterInMs)
39) CI/CD & IaC
Use ARM/Bicep/Terraform to declare accounts, DBs, containers (PK, indexing, RU). Validate in pre-prod with synthetic traffic.
resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2023-04-15'
40) Q&A — “When to use triggers vs change feed?”
Answer: Triggers for small, synchronous per-item logic inside a partition; Change Feed for scalable, asynchronous pipelines and integrations.
41) Cost Controls
Choose right RU model, fix hot partitions, reduce doc size, tighten indexes, and use point reads. Turn on autoscale for bursts.
includePaths minimal; exclude large subtrees
42) Governance
Tag resources, lock production accounts, policy-enforce private endpoints, and monitor key rotations. Separate prod vs non-prod accounts.
tags: { env:"prod", owner:"data" }
43) Reliability & DR
Multi-region reads, optional multi-region writes, automatic failover, PITR backups. Test failover regularly.
automaticFailover: true
44) Performance Tuning
Measure RU, fix cross-partition queries, use composites for ORDER BY, cache, and pre-compute aggregates. Keep docs compact.
SELECT VALUE COUNT(1) ... → store count
45) Common Pitfalls
Bad PK, full scans, OFFSET/LIMIT pagination, over-indexing, giant documents, and assuming cross-partition ACID. Avoid with design upfront.
doc size < 2MB recommended
46) Migration Tips
From Mongo/Cassandra: choose matching API. For Core(SQL), write ETL to reshape docs, set PKs, and backfill composites.
bulk import → verify RU → switch traffic
47) SLOs & Alerts
Track p95 latency, throttles, RU headroom, replica health, failover drills, and change feed lag. Alert on rising RU/query charge.
alert: RU/s utilization > 80%
48) Production Checklist
- Right PK & composite indexes
- Private endpoints + AAD
- Autoscale or RU headroom
- Backups/PITR configured
- Change feed for pipelines
- Dashboards & alerts live
49) Sample IaC Snippet
Minimal Bicep for a Core(SQL) account, DB, and container with TTL and autoscale.
resource acct 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' = {
name: 'acct'
location: resourceGroup().location
kind: 'GlobalDocumentDB'
properties: { databaseAccountOfferType: 'Standard' }
}
resource db 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2023-04-15' = {
name: 'acct/app'
properties: { resource: { id: 'app' } }
}
resource cont 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2023-04-15' = {
name: 'acct/app/users'
properties: {
resource: {
id: 'users'
partitionKey: { paths: ['/tenantId'], kind:'Hash' }
defaultTtl: 3600
}
options: { autoscaleSettings:{ maxThroughput: 4000 } }
}
}
50) Interview Q&A — 20 Practical Questions (Expanded)
1) Why Cosmos DB? Global distribution, elastic scale, low latency, multi-model APIs, and turnkey replication with SLAs.
2) Partition key selection? High cardinality, even distribution, aligns with access patterns (e.g., /tenantId
).
3) Reduce RU on queries? Filter by PK, denormalize hot filters, add composite indexes, and project minimal fields.
4) Point read vs query? Point read (id+pk) is cheapest/fastest; prefer when possible.
5) Consistency trade-offs? Strong = highest correctness/latency; Session = good default; Eventual = fastest.
6) Multi-region writes? Enable for active-active; plan conflict resolution strategy (LWW/custom).
7) Change feed use cases? Event sourcing, projections, analytics sync, cache invalidation.
8) Cross-partition transactions? Not supported; design to keep multi-item ACID within one partition.
9) TTL usage? Auto-expire sessions/caches/telemetry with container or per-item TTL.
10) Over-indexing impact? Higher RU on writes; limit indexes to needed paths.
11) Pagination best practice? Continuation tokens instead of OFFSET/LIMIT.
12) Hot partition symptoms? Throttles on a single PK, uneven RU; fix via key redesign or bucketing.
13) Cost optimization? Autoscale, point reads, compact docs, selective indexing, cache.
14) Serverless vs provisioned? Serverless = pay-per-RU for low traffic; provisioned/autoscale for steady or spiky workloads.
15) Unique keys? Enforce per-partition uniqueness at create time.
16) Composite indexes? Required for multi-column ORDER BY and efficient sort+filter.
17) Security posture? AAD, private endpoints, CMK, disable public network, least privilege.
18) Diagnostics to watch? RequestCharge, ActivityId, Regions contacted, SDK retries, latency histograms.
19) Modeling strategy? Single-container design per bounded context; co-locate related types by PK.
20) Gremlin/Mongo/Cassandra APIs? Choose based on app drivers and data model; Core(SQL) for native JSON+SQL.