Cosmosdb Best Practices
ClineOfficialCreated by cosmosdb-agent-kitDistributed by Cline
- Skill
- Guidelines
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured set of 73+ guidelines for working with Azure Cosmos DB. It covers essential topics including data modeling, partition key design, query optimization, SDK usage, indexing, throughput scaling, global distribution, monitoring, design patterns, and vector search. The content is organized into modular rule files to assist developers in writing, reviewing, and refactoring code that interacts with the database.
What it does
- Provides specific rules for designing efficient data models and choosing partition keys.
- Offers guidance on optimizing queries and implementing SDK patterns.
- Details strategies for indexing, throughput management, and global distribution.
- Includes best practices for implementing vector search and RAG patterns.
- Supplies diagnostic and monitoring recommendations for database operations.
- Organizes content into categorized rule files for targeted retrieval.
When to use it
- When designing data models or selecting partition keys for Cosmos DB.
- When writing or refactoring application code that uses the Cosmos DB SDK.
- When optimizing query performance or indexing strategies.
- When configuring global distribution, throughput, or scaling settings.
- When implementing vector search or advanced design patterns.
Advantages
- Modular structure allows for loading only relevant rules for specific tasks.
- Covers a wide range of operational and architectural concerns.
- Provides clear examples of incorrect and correct implementation patterns.
- Prioritizes rules by impact to guide development decisions.
Usage examples
- “How should I choose a partition key for my Cosmos DB container?”
- The agent will retrieve rules from the partition- prefix to explain high-cardinality, write distribution, and query alignment.
- “What are the best practices for using the Cosmos DB SDK?”
- The agent will load rules from the sdk- prefix to provide guidance on singleton client usage, async APIs, and retry logic.
- “How do I optimize my data model for read-heavy workloads?”
- The agent will reference model- prefixed rules to explain denormalization and embedding strategies.
- “What should I consider when implementing vector search in Cosmos DB?”
- The agent will access vector- prefixed rules to explain embedding policies, index types, and similarity search functions.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/cline/cosmosdb-best-practices/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip cosmosdb-best-practices.zip -d .agents/skills
Documentation by cosmosdb-agent-kit
Azure Cosmos DB Best Practices
Comprehensive performance optimization guide for Azure Cosmos DB applications, containing 73+ rules across 10 categories, prioritized by impact to guide automated refactoring and code generation.
73 individual rule files are in the rules/ directory, one file per rule, synced from the AzureCosmosDB/cosmosdb-agent-kit. Load only the relevant rule file(s) when answering a question — do NOT load all files at once.
When to Apply
Reference these guidelines when:
Designing data models for Cosmos DB
Choosing partition keys
Writing or optimizing queries
Implementing SDK patterns
Reviewing code for performance issues
Configuring throughput and scaling
Building globally distributed applications
Implementing vector search and RAG patterns
Rule Index
Rules are grouped by category prefix. For a given question, load files matching
the relevant prefix (e.g., model-*.md for data modeling, sdk-*.md for SDK usage).
See rules/_sections.md for category descriptions.
1. Data Modeling — CRITICAL (prefix: model-)
model-embed-related.md — Embed related data retrieved together
model-reference-large.md — Reference data when items grow large
model-avoid-2mb-limit.md — Keep items well under 2MB limit
model-id-constraints.md — Follow ID value length and character constraints
model-nesting-depth.md — Stay within 128-level nesting depth limit
model-numeric-precision.md — Understand IEEE 754 numeric precision limits
model-denormalize-reads.md — Denormalize for read-heavy workloads
model-schema-versioning.md — Version your document schemas
model-type-discriminator.md — Use type discriminators for polymorphic data
model-json-serialization.md — Handle JSON serialization correctly
model-relationship-references.md — Use ID references with transient hydration
2. Partition Key Design — CRITICAL (prefix: partition-)
partition-high-cardinality.md — Choose high-cardinality partition keys
partition-avoid-hotspots.md — Distribute writes evenly
partition-hierarchical.md — Use hierarchical partition keys for flexibility
partition-query-patterns.md — Align partition key with query patterns
partition-synthetic-keys.md — Create synthetic keys when needed
partition-key-length.md — Respect partition key value length limits
partition-20gb-limit.md — Plan for 20GB logical partition limit
3. Query Optimization — HIGH (prefix: query-)
query-avoid-cross-partition.md — Minimize cross-partition queries
query-use-projections.md — Project only needed fields
query-pagination.md — Use continuation tokens for pagination
query-avoid-scans.md — Avoid full container scans
query-parameterize.md — Use parameterized queries
query-order-filters.md — Order filters by selectivity
4. SDK Best Practices — HIGH (prefix: sdk-)
sdk-singleton-client.md — Reuse CosmosClient as singleton
sdk-async-api.md — Use async APIs for throughput
sdk-retry-429.md — Handle 429s with retry-after
sdk-connection-mode.md — Use Direct mode for production
sdk-preferred-regions.md — Configure preferred regions
sdk-excluded-regions.md — Exclude regions experiencing issues
sdk-availability-strategy.md — Configure availability strategy for resilience
sdk-circuit-breaker.md — Use circuit breaker for fault tolerance
sdk-diagnostics.md — Log diagnostics for troubleshooting
sdk-serialization-enums.md — Serialize enums as strings not integers
sdk-emulator-ssl.md — Configure SSL and connection mode for Cosmos DB Emulator
sdk-etag-concurrency.md — Use ETags for optimistic concurrency
sdk-java-content-response.md — Enable content response on write operations (Java)
sdk-java-cosmos-config.md — Configure Cosmos DB in Spring Boot with dependent beans
sdk-java-spring-boot-versions.md — Match Java version to Spring Boot requirements
sdk-local-dev-config.md — Configure local development to avoid cloud conflicts
sdk-newtonsoft-dependency.md — Explicitly reference Newtonsoft.Json package (.NET)
sdk-spring-data-annotations.md — Annotate entities for Spring Data Cosmos
sdk-spring-data-repository.md — Use CosmosRepository correctly
5. Indexing Strategies — MEDIUM-HIGH (prefix: index-)
index-exclude-unused.md — Exclude paths never queried
index-composite.md — Use composite indexes for ORDER BY
index-spatial.md — Add spatial indexes for geo queries
index-range-vs-hash.md — Choose appropriate index types
index-lazy-consistent.md — Understand indexing modes
6. Throughput & Scaling — MEDIUM (prefix: throughput-)
throughput-autoscale.md — Use autoscale for variable workloads
throughput-right-size.md — Right-size provisioned throughput
throughput-serverless.md — Consider serverless for dev/test
throughput-burst.md — Understand burst capacity
throughput-container-vs-database.md — Choose allocation level wisely
7. Global Distribution — MEDIUM (prefix: global-)
global-multi-region.md — Configure multi-region writes
global-consistency.md — Choose appropriate consistency level
global-conflict-resolution.md — Implement conflict resolution
global-failover.md — Configure automatic failover
global-read-regions.md — Add read regions near users
global-zone-redundancy.md — Enable zone redundancy for HA
8. Monitoring & Diagnostics — LOW-MEDIUM (prefix: monitoring-)
monitoring-ru-consumption.md — Track RU consumption
monitoring-latency.md — Monitor P99 latency
monitoring-throttling.md — Alert on throttling
monitoring-azure-monitor.md — Integrate Azure Monitor
monitoring-diagnostic-logs.md — Enable diagnostic logging
9. Design Patterns — HIGH (prefix: pattern-)
pattern-change-feed-materialized-views.md — Use Change Feed for materialized views
pattern-efficient-ranking.md — Use count-based or cached approaches for ranking
pattern-service-layer-relationships.md — Use a service layer to hydrate document references
10. Vector Search — HIGH (prefix: vector-)
vector-enable-feature.md — Enable vector search feature on account
vector-embedding-policy.md — Define vector embedding policy on container
vector-index-type.md — Configure vector indexes (QuantizedFlat or DiskANN)
vector-distance-query.md — Use VectorDistance() for similarity search
vector-normalize-embeddings.md — Normalize embeddings for cosine similarity
vector-repository-pattern.md — Implement repository pattern for vector search
How to Use
Each rule is a separate file under rules/. When answering a Cosmos DB question, read only the relevant rule file(s) based on the prefix matching the topic:
Data modeling question → read
rules/model-*.mdfilesPartition key question → read
rules/partition-*.mdfilesSDK/client question → read
rules/sdk-*.mdfilesetc.
Each rule file contains:
Brief explanation of why it matters
Incorrect code example with explanation
Correct code example with explanation
Additional context and references
Source: AzureCosmosDB/cosmosdb-agent-kit
Files
- ATTRIBUTION.mdAdded by AutoGineer876 B
- SKILL.md10.1 KiB
- rules/_sections.md2.1 KiB
- rules/_template.md802 B
- rules/global-conflict-resolution.md4.0 KiB
- rules/global-consistency.md3.7 KiB
- rules/global-failover.md3.7 KiB
- rules/global-multi-region.md3.2 KiB
- rules/global-read-regions.md3.9 KiB
- rules/global-zone-redundancy.md3.5 KiB
- rules/index-composite.md6.0 KiB
- rules/index-exclude-unused.md3.1 KiB
- rules/index-lazy-consistent.md3.1 KiB
- rules/index-range-vs-hash.md3.4 KiB
- rules/index-spatial.md3.1 KiB
- rules/model-avoid-2mb-limit.md2.0 KiB
- rules/model-denormalize-reads.md3.4 KiB
- rules/model-embed-related.md2.5 KiB
- rules/model-id-constraints.md2.9 KiB
- rules/model-json-serialization.md4.0 KiB
- rules/model-nesting-depth.md3.3 KiB
- rules/model-numeric-precision.md3.2 KiB
- rules/model-reference-large.md2.3 KiB
- rules/model-relationship-references.md3.6 KiB
- rules/model-schema-versioning.md2.4 KiB
- rules/model-type-discriminator.md3.5 KiB
- rules/monitoring-azure-monitor.md4.4 KiB
- rules/monitoring-diagnostic-logs.md5.1 KiB
- rules/monitoring-latency.md4.2 KiB
- rules/monitoring-ru-consumption.md4.2 KiB
- rules/monitoring-throttling.md4.4 KiB
- rules/partition-20gb-limit.md2.8 KiB
- rules/partition-avoid-hotspots.md3.4 KiB
- rules/partition-hierarchical.md2.7 KiB
- rules/partition-high-cardinality.md2.2 KiB
- rules/partition-key-length.md2.8 KiB
- rules/partition-query-patterns.md2.7 KiB
- rules/partition-synthetic-keys.md3.8 KiB
- rules/pattern-change-feed-materialized-views.md7.2 KiB
- rules/pattern-efficient-ranking.md5.8 KiB
- rules/pattern-service-layer-relationships.md4.8 KiB
- rules/query-avoid-cross-partition.md2.5 KiB
- rules/query-avoid-scans.md2.5 KiB
- rules/query-order-filters.md2.6 KiB
- rules/query-pagination.md6.2 KiB
- rules/query-parameterize.md2.9 KiB
- rules/query-use-projections.md2.7 KiB
- rules/sdk-async-api.md3.2 KiB
- rules/sdk-availability-strategy.md5.3 KiB
- rules/sdk-circuit-breaker.md8.4 KiB
- rules/sdk-connection-mode.md2.9 KiB
- rules/sdk-diagnostics.md3.6 KiB
- rules/sdk-emulator-ssl.md7.8 KiB
- rules/sdk-etag-concurrency.md8.1 KiB
- rules/sdk-excluded-regions.md4.9 KiB
- rules/sdk-java-content-response.md3.9 KiB
- rules/sdk-java-cosmos-config.md5.9 KiB
- rules/sdk-java-spring-boot-versions.md4.8 KiB
- rules/sdk-local-dev-config.md5.4 KiB
- rules/sdk-newtonsoft-dependency.md3.9 KiB
- rules/sdk-preferred-regions.md3.2 KiB
- rules/sdk-retry-429.md3.7 KiB
- rules/sdk-serialization-enums.md2.8 KiB
- rules/sdk-singleton-client.md3.7 KiB
- rules/sdk-spring-data-annotations.md3.4 KiB
- rules/sdk-spring-data-repository.md3.4 KiB
- rules/throughput-autoscale.md2.6 KiB
- rules/throughput-burst.md2.7 KiB
- rules/throughput-container-vs-database.md3.2 KiB
- rules/throughput-right-size.md3.1 KiB
- rules/throughput-serverless.md2.7 KiB
- rules/vector-distance-query.md4.8 KiB
- rules/vector-embedding-policy.md3.8 KiB
- rules/vector-enable-feature.md3.0 KiB
- rules/vector-index-type.md4.7 KiB
- rules/vector-normalize-embeddings.md8.6 KiB
- rules/vector-repository-pattern.md12.9 KiB
rules/vector-repository-pattern.md
title: Implement Repository Pattern for Vector Search impact: HIGH impactDescription: Provides clean abstraction for vector operations and data access tags: vector, repository, pattern, architecture, vector-search
Implement Repository Pattern for Vector Search
Impact: HIGH (Clean abstraction for vector operations)
When implementing vector search, use a repository pattern to encapsulate Cosmos DB operations. This separates data access logic from business logic and makes vector search operations testable and maintainable.
Key Methods to Implement:
insert_document/upsert_document - Store documents with embeddings
vector_search - Perform similarity search with VectorDistance()
get_document - Point read by ID and partition key
delete_document - Remove documents
Incorrect (direct container access in application code):
# Python - BAD: Direct container access scattered throughout app
@app.post("/api/search")
async def search(request: SearchRequest):
# Vector search logic mixed with API logic
query = f"""
SELECT TOP {request.limit} c.title,
VectorDistance(c.embedding, @embedding) AS score
FROM c ORDER BY VectorDistance(c.embedding, @embedding)
"""
results = container.query_items(query, parameters=[...])
# No abstraction, hard to test, tightly coupled// .NET - BAD: No separation of concerns
public class DocumentService {
public async Task<List<Doc>> Search(float[] embedding) {
// Direct container access, no abstraction
var query = new QueryDefinition(...);
var iterator = _container.GetItemQueryIterator<Doc>(query);
// Mixing infrastructure concerns with business logic
}
}Correct (repository pattern with clean abstraction):
# Python - GOOD: Repository pattern
class DocumentRepository:
"""Repository for documents with vector search capabilities"""
def __init__(self, container: ContainerProxy):
self.container = container
async def insert_document(self, document: DocumentChunk) -> DocumentChunk:
"""Insert document with vector embedding."""
try:
doc_dict = document.dict()
created_item = self.container.upsert_item(body=doc_dict)
return DocumentChunk(**created_item)
except CosmosHttpResponseError as e:
logger.error(f"Failed to insert document: {e.message}")
raise
async def vector_search(
self,
query_embedding: List[float],
limit: int = 5,
similarity_threshold: float = 0.0,
category_filter: Optional[str] = None
) -> List[DocumentChunk]:
"""Perform vector similarity search with VectorDistance()."""
try:
# Build parameterized query
query = """
SELECT TOP @limit
c.id, c.title, c.content, c.category, c.metadata,
VectorDistance(c.embedding, @queryVector) AS similarityScore
FROM c
WHERE VectorDistance(c.embedding, @queryVector) > @threshold
"""
# Add optional filters
if category_filter:
query += " AND c.category = @category"
query += " ORDER BY VectorDistance(c.embedding, @queryVector)"
# Build parameters
parameters = [
{"name": "@queryVector", "value": query_embedding},
{"name": "@limit", "value": limit},
{"name": "@threshold", "value": similarity_threshold}
]
if category_filter:
parameters.append({"name": "@category", "value": category_filter})
# Execute query
items = list(self.container.query_items(
query=query,
parameters=parameters,
enable_cross_partition_query=True,
populate_query_metrics=True
))
# Convert to domain models
results = []
for item in items:
score = item.pop('similarityScore', 0.0)
if 'metadata' not in item:
item['metadata'] = {}
item['metadata']['similarityScore'] = score
item['embedding'] = [] # Exclude from response for performance
results.append(DocumentChunk(**item))
return results
except CosmosHttpResponseError as e:
logger.error(f"Vector search failed: {e.message}")
raise
async def get_document(self, document_id: str, category: str) -> Optional[DocumentChunk]:
"""Point read with partition key."""
try:
item = self.container.read_item(
item=document_id,
partition_key=category
)
return DocumentChunk(**item)
except CosmosHttpResponseError as e:
if e.status_code == 404:
return None
raise
# Usage in application
@app.post("/api/search")
async def search(request: SearchRequest):
results = await document_repo.vector_search(
query_embedding=request.embedding,
limit=request.top_k,
category_filter=request.category
)
return {"results": results}// .NET - GOOD: Repository pattern
public interface IDocumentRepository
{
Task<DocumentChunk> InsertDocumentAsync(DocumentChunk document);
Task<List<DocumentChunk>> VectorSearchAsync(
float[] queryEmbedding,
int limit = 5,
double similarityThreshold = 0.0,
string? categoryFilter = null);
Task<DocumentChunk?> GetDocumentAsync(string id, string category);
}
public class DocumentRepository : IDocumentRepository
{
private readonly Container _container;
private readonly ILogger<DocumentRepository> _logger;
public DocumentRepository(Container container, ILogger<DocumentRepository> logger)
{
_container = container;
_logger = logger;
}
public async Task<DocumentChunk> InsertDocumentAsync(DocumentChunk document)
{
try
{
var response = await _container.UpsertItemAsync(
item: document,
partitionKey: new PartitionKey(document.Category)
);
_logger.LogInformation("Inserted document {Id}", document.Id);
return response.Resource;
}
catch (CosmosException ex)
{
_logger.LogError(ex, "Failed to insert document {Id}", document.Id);
throw;
}
}
public async Task<List<DocumentChunk>> VectorSearchAsync(
float[] queryEmbedding,
int limit = 5,
double similarityThreshold = 0.0,
string? categoryFilter = null)
{
try
{
// Build query
var queryText = @"
SELECT TOP @limit
c.id, c.title, c.content, c.category, c.metadata,
VectorDistance(c.embedding, @queryVector) AS similarityScore
FROM c
WHERE VectorDistance(c.embedding, @queryVector) > @threshold";
if (!string.IsNullOrEmpty(categoryFilter))
{
queryText += " AND c.category = @category";
}
queryText += " ORDER BY VectorDistance(c.embedding, @queryVector)";
// Build query definition
var queryDef = new QueryDefinition(queryText)
.WithParameter("@queryVector", queryEmbedding)
.WithParameter("@limit", limit)
.WithParameter("@threshold", similarityThreshold);
if (!string.IsNullOrEmpty(categoryFilter))
{
queryDef = queryDef.WithParameter("@category", categoryFilter);
}
// Execute query
var results = new List<DocumentChunk>();
using var iterator = _container.GetItemQueryIterator<DocumentChunk>(queryDef);
while (iterator.HasMoreResults)
{
var response = await iterator.ReadNextAsync();
results.AddRange(response);
// Log RU consumption
_logger.LogDebug("Vector search consumed {RU} RUs",
response.RequestCharge);
}
return results;
}
catch (CosmosException ex)
{
_logger.LogError(ex, "Vector search failed");
throw;
}
}
public async Task<DocumentChunk?> GetDocumentAsync(string id, string category)
{
try
{
var response = await _container.ReadItemAsync<DocumentChunk>(
id: id,
partitionKey: new PartitionKey(category)
);
return response.Resource;
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return null;
}
}
}
// Usage in service/controller
public class SearchService
{
private readonly IDocumentRepository _repository;
public SearchService(IDocumentRepository repository)
{
_repository = repository;
}
public async Task<List<DocumentChunk>> SearchAsync(SearchRequest request)
{
return await _repository.VectorSearchAsync(
queryEmbedding: request.Embedding,
limit: request.TopK,
categoryFilter: request.Category
);
}
}// JavaScript/TypeScript - GOOD: Repository pattern
class DocumentRepository {
constructor(private container: Container) {}
async insertDocument(document: DocumentChunk): Promise<DocumentChunk> {
try {
const { resource } = await this.container.items.upsert(document);
console.log(`Inserted document ${resource.id}`);
return resource;
} catch (error) {
console.error('Failed to insert document:', error);
throw error;
}
}
async vectorSearch(
queryEmbedding: number[],
options: {
limit?: number;
similarityThreshold?: number;
categoryFilter?: string;
} = {}
): Promise<DocumentChunk[]> {
const { limit = 5, similarityThreshold = 0.0, categoryFilter } = options;
try {
let query = `
SELECT TOP @limit
c.id, c.title, c.content, c.category, c.metadata,
VectorDistance(c.embedding, @queryVector) AS similarityScore
FROM c
WHERE VectorDistance(c.embedding, @queryVector) > @threshold
`;
const parameters = [
{ name: '@queryVector', value: queryEmbedding },
{ name: '@limit', value: limit },
{ name: '@threshold', value: similarityThreshold }
];
if (categoryFilter) {
query += ' AND c.category = @category';
parameters.push({ name: '@category', value: categoryFilter });
}
query += ' ORDER BY VectorDistance(c.embedding, @queryVector)';
const { resources } = await this.container.items
.query({
query,
parameters
})
.fetchAll();
return resources.map(item => ({
...item,
embedding: [] // Exclude for performance
}));
} catch (error) {
console.error('Vector search failed:', error);
throw error;
}
}
async getDocument(id: string, category: string): Promise<DocumentChunk | null> {
try {
const { resource } = await this.container.item(id, category).read();
return resource;
} catch (error: any) {
if (error.code === 404) {
return null;
}
throw error;
}
}
}
// Usage
const documentRepo = new DocumentRepository(container);
const results = await documentRepo.vectorSearch(embedding, {
limit: 10,
categoryFilter: 'ai'
});Benefits:
✅ Testable - Mock repository in unit tests
✅ Maintainable - Vector search logic in one place
✅ Reusable - Use repository across multiple services
✅ Clean separation - Infrastructure vs business logic
✅ Easier to optimize - Centralized query performance tuning
Best Practices:
Use
upsert_itemfor idempotent insertsAlways parameterize queries (never concatenate embeddings)
Include
ORDER BY VectorDistance()for ranked resultsExclude embeddings from SELECT when not needed (performance)
Log RU consumption for monitoring
Handle 404 errors gracefully (return null, not exception)
Use domain models (not raw dictionaries/dynamic)
Related Rules:
vector-distance-query.md - VectorDistance() usage
query-parameterize.md - Always use parameters
query-use-projections.md - Exclude unnecessary fields
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- cosmosdb-agent-kit
- Publisher
- Cline (Official)
- Distributed by
- Cline
- Source
- cline/skills · skills/cosmosdb-best-practices · commit 2637846
- Licence
- MIT License (redistribution allowed)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by cosmosdb-agent-kit or Cline.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download cosmosdb-best-practices.zip