// This skill should be used when the user asks about "R2", "D1", "KV", "Durable Objects", "Queues", "Vectorize", "Hyperdrive", "Workers Analytics", "Email Routing", "Browser Rendering", or discusses Cloudflare platform services, storage options, database choices, when to use which service, or integration patterns between Workers and platform products.
| name | Cloudflare Platform Products |
| description | This skill should be used when the user asks about "R2", "D1", "KV", "Durable Objects", "Queues", "Vectorize", "Hyperdrive", "Workers Analytics", "Email Routing", "Browser Rendering", or discusses Cloudflare platform services, storage options, database choices, when to use which service, or integration patterns between Workers and platform products. |
| version | 0.1.0 |
This skill provides guidance on Cloudflare's platform products and services that integrate with Workers. It covers storage options (KV, R2, D1), coordination services (Durable Objects, Queues), data services (Vectorize, Hyperdrive), and specialized services (Analytics Engine, Browser Rendering). Use this skill when choosing between platform products, designing system architecture, or integrating multiple Cloudflare services.
Cloudflare offers a comprehensive suite of platform products designed to work seamlessly with Workers:
| Product | Category | Use Case | Key Features |
|---|---|---|---|
| KV | Storage | Key-value cache, static content | Eventually consistent, global, 25MB values |
| D1 | Database | Relational data, SQL queries | SQLite, transactions, migrations |
| R2 | Storage | Large files, object storage | S3-compatible, unlimited size, no egress fees |
| Durable Objects | Coordination | Stateful services, real-time | Strong consistency, WebSockets, single-threaded |
| Queues | Messaging | Async processing, event-driven | At-least-once delivery, batching |
| Vectorize | Data | Semantic search, embeddings | Vector similarity, RAG support |
| Hyperdrive | Database | Postgres connection pooling | Reduced latency, connection management |
| Analytics Engine | Analytics | Custom metrics, time-series | High-cardinality data, SQL queries |
| Workers AI | AI/ML | Inference, embeddings | Text generation, vision, audio |
See references/platform-products-matrix.md for detailed comparison and selection guide.
Best for: Static content, configuration, caching, read-heavy workloads
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Cache API responses
await env.CACHE.put(`api:users:${id}`, JSON.stringify(user), {
expirationTtl: 3600
});
// Store configuration
await env.CONFIG.put('feature_flags', JSON.stringify(flags));
// Session storage
await env.SESSIONS.put(sessionId, userData, {
expirationTtl: 86400 // 24 hours
});
Best for: Relational data, complex queries, transactional workloads
Characteristics:
When to use:
When NOT to use:
Example use cases:
// User management
await env.DB.prepare(
'SELECT * FROM users WHERE email = ? AND active = 1'
).bind(email).first();
// Transactions (via batch)
await env.DB.batch([
env.DB.prepare('INSERT INTO orders (user_id, total) VALUES (?, ?)').bind(userId, total),
env.DB.prepare('UPDATE users SET last_order = ? WHERE id = ?').bind(Date.now(), userId)
]);
// Complex queries
await env.DB.prepare(`
SELECT orders.*, users.email
FROM orders
JOIN users ON orders.user_id = users.id
WHERE orders.status = ?
`).bind('pending').all();
Best for: Large files, user uploads, backups, media storage
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Store user upload
await env.UPLOADS.put(`users/${userId}/avatar.jpg`, imageData, {
httpMetadata: {
contentType: 'image/jpeg'
},
customMetadata: {
uploadedBy: userId,
uploadedAt: Date.now().toString()
}
});
// Stream large file
const object = await env.MEDIA.get('videos/large-video.mp4');
return new Response(object.body);
// Store backup
await env.BACKUPS.put(`db-backup-${Date.now()}.sql`, backupData);
See references/storage-options-guide.md for detailed storage selection criteria.
Best for: Coordination, real-time collaboration, WebSockets, rate limiting
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Rate limiting
export class RateLimiter {
constructor(state, env) {
this.state = state;
}
async fetch(request) {
const count = await this.state.storage.get('count') || 0;
const limit = 100;
if (count >= limit) {
return new Response('Rate limit exceeded', { status: 429 });
}
await this.state.storage.put('count', count + 1);
return new Response('OK');
}
}
// Chat room coordination
export class ChatRoom {
constructor(state, env) {
this.state = state;
this.sessions = [];
}
async fetch(request) {
const pair = new WebSocketPair();
this.sessions.push(pair[1]);
pair[1].accept();
pair[1].addEventListener('message', event => {
// Broadcast to all sessions
this.sessions.forEach(session => {
session.send(event.data);
});
});
return new Response(null, { status: 101, webSocket: pair[0] });
}
}
Best for: Asynchronous processing, background jobs, event-driven workflows
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Producer: Queue email sending
await env.EMAIL_QUEUE.send({
to: user.email,
subject: 'Welcome',
body: 'Welcome to our service!'
});
// Consumer: Process emails in batches
export default {
async queue(batch, env) {
for (const message of batch.messages) {
const { to, subject, body } = message.body;
try {
await sendEmail(to, subject, body, env);
message.ack();
} catch (error) {
console.error('Email failed:', error);
message.retry();
}
}
}
};
Best for: Semantic search, RAG, recommendations, similarity matching
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Generate and store embeddings
const embeddings = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: [document.text]
});
await env.VECTOR_INDEX.insert([{
id: document.id,
values: embeddings.data[0],
metadata: { text: document.text, title: document.title }
}]);
// Semantic search
const queryEmbedding = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: [userQuestion]
});
const results = await env.VECTOR_INDEX.query(queryEmbedding.data[0], {
topK: 5
});
// Use results for RAG
const context = results.matches.map(m => m.metadata.text).join('\n');
Best for: Postgres connection pooling, reducing database latency
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Connect to Postgres via Hyperdrive
const client = env.HYPERDRIVE.connect();
const result = await client.query(
'SELECT * FROM users WHERE id = $1',
[userId]
);
// Connection automatically pooled and managed
Best for: Custom metrics, high-cardinality analytics, time-series data
Characteristics:
When to use:
When NOT to use:
Example use cases:
// Write analytics events
await env.ANALYTICS.writeDataPoint({
blobs: ['api_call', request.url, request.method],
doubles: [responseTime, statusCode],
indexes: [userId]
});
// Query via GraphQL API or Dashboard
Best for: Web scraping, PDF generation, screenshots, browser automation
Characteristics:
When to use:
Example use cases:
// Take screenshot
const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();
await page.goto('https://example.com');
const screenshot = await page.screenshot();
await browser.close();
return new Response(screenshot, {
headers: { 'Content-Type': 'image/png' }
});
Best for: Custom email handling, email forwarding, email processing
Characteristics:
When to use:
Need to store data → What kind?
Need to process requests → What pattern?
Common multi-product patterns:
RAG Application:
E-commerce Platform:
Content Platform:
Real-time Collaboration:
See examples/multi-product-architecture.js for complete integration examples.
See references/pricing-optimization.md for detailed cost optimization strategies.
// Before: External Postgres via Hyperdrive
const result = await env.HYPERDRIVE.query('SELECT * FROM users WHERE id = ?', [id]);
// After: D1 (if dataset fits in 25 MB)
const result = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(id).first();
// R2 is S3-compatible, minimal code changes needed
// Before: aws-sdk with S3
// After: R2 binding (native integration)
await env.MY_BUCKET.put('key', data);
const object = await env.MY_BUCKET.get('key');
// Simple cache: KV
await env.CACHE.put('key', 'value', { expirationTtl: 3600 });
// Stateful/counters: Durable Objects
const id = env.COUNTER.idFromName('global');
const counter = env.COUNTER.get(id);
await counter.fetch(request);
For detailed information, consult:
references/platform-products-matrix.md - Complete product comparison and selection criteriareferences/storage-options-guide.md - Deep dive on KV vs D1 vs R2 decisionsreferences/pricing-optimization.md - Cost optimization strategiesWorking examples in examples/:
multi-product-architecture.js - Integrating multiple platform productsFor the latest platform documentation:
Use the cloudflare-docs-specialist agent to search documentation and fetch the latest platform information.