# Complete Bindings Guide Bindings are how Workers connect to Cloudflare resources and external services. They provide zero-latency access to storage, databases, queues, and other services. ## Storage Bindings ### KV (Key-Value Storage) Global, low-latency, eventually consistent key-value storage. **Best for:** - Configuration data - User sessions - Cache - Small objects (<25 MB) **Configuration:** ```toml [[kv_namespaces]] binding = "MY_KV" id = "your-namespace-id" preview_id = "preview-namespace-id" # For local dev ``` **API:** ```typescript // Write await env.MY_KV.put("key", "value"); await env.MY_KV.put("key", "value", { expirationTtl: 3600, // Expire in 1 hour metadata: { user: "123" } }); // Read const value = await env.MY_KV.get("key"); const json = await env.MY_KV.get("key", "json"); const buffer = await env.MY_KV.get("key", "arrayBuffer"); // With metadata const { value, metadata } = await env.MY_KV.getWithMetadata("key"); // Delete await env.MY_KV.delete("key"); // List keys const keys = await env.MY_KV.list({ prefix: "user:" }); ``` **Limits:** - Key size: 512 bytes - Value size: 25 MB - Write rate: 1 write/second per key (eventually consistent) - Read rate: unlimited ### D1 (SQL Database) Serverless SQLite database built on SQLite. **Best for:** - Structured data - Relational data - Complex queries - ACID transactions **Configuration:** ```toml [[d1_databases]] binding = "DB" database_name = "my-database" database_id = "your-database-id" ``` **API:** ```typescript // Query with bind parameters const result = await env.DB.prepare( "SELECT * FROM users WHERE id = ?" ).bind(userId).all(); // Insert await env.DB.prepare( "INSERT INTO users (name, email) VALUES (?, ?)" ).bind(name, email).run(); // Update await env.DB.prepare( "UPDATE users SET last_login = ? WHERE id = ?" ).bind(new Date().toISOString(), userId).run(); // Transaction const results = await env.DB.batch([ env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("Alice"), env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("Bob"), ]); // First row only const user = await env.DB.prepare( "SELECT * FROM users WHERE id = ?" ).bind(userId).first(); ``` **Features:** - Read replication (low latency reads globally) - Time Travel (restore to any point in last 30 days) - Backups - Migrations via Wrangler **Limits:** - Database size: 10 GB (Paid), 500 MB (Free) - Rows read: 25M/day (Paid), 5M/day (Free) - Rows written: 50M/day (Paid), 100K/day (Free) ### R2 (Object Storage) S3-compatible object storage with zero egress fees. **Best for:** - Large files - Media storage - Static assets - Backups **Configuration:** ```toml [[r2_buckets]] binding = "MY_BUCKET" bucket_name = "my-bucket" jurisdiction = "eu" # Optional: eu or fedramp ``` **API:** ```typescript // Put object await env.MY_BUCKET.put("file.txt", "contents", { httpMetadata: { contentType: "text/plain", cacheControl: "max-age=3600", }, customMetadata: { user: "123", }, }); // Put from stream await env.MY_BUCKET.put("large-file.bin", request.body); // Get object const object = await env.MY_BUCKET.get("file.txt"); if (object) { const text = await object.text(); const buffer = await object.arrayBuffer(); const stream = object.body; // ReadableStream // Metadata console.log(object.httpMetadata); console.log(object.customMetadata); } // Get with range const object = await env.MY_BUCKET.get("file.txt", { range: { offset: 0, length: 1024 } }); // Head (metadata only) const object = await env.MY_BUCKET.head("file.txt"); // Delete await env.MY_BUCKET.delete("file.txt"); // List objects const objects = await env.MY_BUCKET.list({ prefix: "images/", limit: 1000, }); // Multipart upload (for large files) const upload = await env.MY_BUCKET.createMultipartUpload("large.bin"); const part = await upload.uploadPart(1, data); await upload.complete([part]); ``` **Features:** - Automatic multipart uploads - Object versioning - Event notifications - Public buckets - Custom domains **Limits:** - Max object size: 5 TB - Storage: unlimited - Operations: unlimited ## Compute Bindings ### Durable Objects Strongly consistent, coordinated stateful objects with SQLite storage. **Best for:** - Real-time collaboration - WebSocket servers - Coordination - Strong consistency - Per-user/per-room state **Configuration:** ```toml [[durable_objects.bindings]] name = "COUNTER" class_name = "Counter" script_name = "my-worker" # Optional: if in different Worker [[migrations]] tag = "v1" new_classes = ["Counter"] ``` **Durable Object Class:** ```typescript export class Counter { state: DurableObjectState; constructor(state: DurableObjectState, env: Env) { this.state = state; } async fetch(request: Request): Promise { // Get from storage let count = (await this.state.storage.get("count")) || 0; // Increment count++; // Put to storage await this.state.storage.put("count", count); return Response.json({ count }); } // Alarms (scheduled actions) async alarm() { await this.state.storage.delete("count"); } } ``` **Worker Usage:** ```typescript export default { async fetch(request: Request, env: Env): Promise { // Get Durable Object ID const id = env.COUNTER.idFromName("global-counter"); // Get stub (reference) const stub = env.COUNTER.get(id); // Call via fetch return stub.fetch(request); }, }; ``` **Storage API:** ```typescript // Single operations await this.state.storage.put("key", "value"); const value = await this.state.storage.get("key"); await this.state.storage.delete("key"); // Batch operations await this.state.storage.put({ key1: "value1", key2: "value2", }); const values = await this.state.storage.get(["key1", "key2"]); // List const entries = await this.state.storage.list(); // SQL (new) const result = await this.state.storage.sql.exec( "SELECT * FROM users WHERE id = ?", userId ); ``` **Features:** - SQLite-backed storage - Automatic persistence - Alarms (scheduled actions) - WebSocket Hibernation - Point-in-time recovery ### Queues Message queuing for async processing with guaranteed delivery. **Best for:** - Background jobs - Async processing - Decoupling services - Retry logic **Configuration:** ```toml [[queues.producers]] binding = "MY_QUEUE" queue = "my-queue" [[queues.consumers]] queue = "my-queue" max_batch_size = 100 max_batch_timeout = 30 ``` **Producer (send messages):** ```typescript export default { async fetch(request: Request, env: Env): Promise { // Send single message await env.MY_QUEUE.send({ userId: 123, action: "process" }); // Send batch await env.MY_QUEUE.sendBatch([ { body: { userId: 123 } }, { body: { userId: 456 } }, ]); return Response.json({ queued: true }); }, }; ``` **Consumer (receive messages):** ```typescript export default { async queue(batch: MessageBatch, env: Env): Promise { for (const message of batch.messages) { try { await processMessage(message.body); message.ack(); // Mark as processed } catch (error) { message.retry(); // Retry later } } }, }; ``` **Features:** - Guaranteed delivery - Automatic retries - Dead letter queues - Batch processing - Pull consumers (API-based) ## AI & ML Bindings ### Workers AI Run AI models directly from Workers. **Best for:** - Text generation (LLMs) - Embeddings - Image generation - Speech recognition - Translation **Configuration:** ```toml [ai] binding = "AI" ``` **API:** ```typescript // Text generation const response = await env.AI.run("@cf/meta/llama-3-8b-instruct", { messages: [ { role: "system", content: "You are a helpful assistant" }, { role: "user", content: "What is Cloudflare?" } ], }); // Embeddings const embeddings = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: "The quick brown fox jumps over the lazy dog", }); // Image generation const image = await env.AI.run("@cf/stabilityai/stable-diffusion-xl-base-1.0", { prompt: "A sunset over the ocean", }); // Speech to text const result = await env.AI.run("@cf/openai/whisper", { audio: audioData, }); // Streaming const stream = await env.AI.run("@cf/meta/llama-3-8b-instruct", { messages: [{ role: "user", content: "Tell me a story" }], stream: true, }); ``` ### Vectorize Vector database for similarity search. **Best for:** - Semantic search - RAG (Retrieval Augmented Generation) - Recommendations - Embeddings storage **Configuration:** ```toml [[vectorize]] binding = "VECTORIZE" index_name = "my-index" ``` **API:** ```typescript // Insert vectors await env.VECTORIZE.insert([ { id: "1", values: [0.1, 0.2, ...], metadata: { text: "..." } }, { id: "2", values: [0.3, 0.4, ...], metadata: { text: "..." } }, ]); // Query (similarity search) const results = await env.VECTORIZE.query( [0.15, 0.25, ...], // Query vector { topK: 5, returnMetadata: true, } ); // With metadata filtering const results = await env.VECTORIZE.query(vector, { topK: 5, filter: { category: "technology" }, }); ``` ## Database Bindings ### Hyperdrive Accelerate access to existing databases via connection pooling and caching. **Best for:** - Connecting to existing Postgres/MySQL - Reducing latency to traditional databases - Connection pooling **Configuration:** ```toml [[hyperdrive]] binding = "HYPERDRIVE" id = "your-hyperdrive-id" ``` **Usage with postgres:** ```typescript import { Client } from "pg"; const client = new Client({ connectionString: env.HYPERDRIVE.connectionString, }); await client.connect(); const result = await client.query("SELECT * FROM users"); await client.end(); ``` **Features:** - Connection pooling - Query caching - Read replicas support ## Service Bindings Call other Workers via RPC or HTTP. **Configuration:** ```toml [[services]] binding = "AUTH_SERVICE" service = "auth-worker" environment = "production" ``` **HTTP-based:** ```typescript const response = await env.AUTH_SERVICE.fetch(new Request("http://auth/verify")); ``` **RPC-based (recommended):** ```typescript // In auth-worker export class AuthService extends WorkerEntrypoint { async verifyToken(token: string): Promise { // Verify logic return true; } } // In calling worker const isValid = await env.AUTH_SERVICE.verifyToken(token); ``` ## Additional Bindings ### Analytics Engine Write custom analytics and metrics. ```toml [[analytics_engine_datasets]] binding = "ANALYTICS" ``` ```typescript env.ANALYTICS.writeDataPoint({ blobs: ["user-123", "click"], doubles: [1.5], indexes: ["button-1"], }); ``` ### Browser Rendering Control headless browsers. ```toml browser = { binding = "BROWSER" } ``` ```typescript const browser = await puppeteer.launch(env.BROWSER); const page = await browser.newPage(); await page.goto("https://example.com"); const screenshot = await page.screenshot(); ``` ### Rate Limiting Built-in rate limiting. ```toml [[unsafe.bindings]] name = "RATE_LIMITER" type = "ratelimit" namespace_id = "your-namespace-id" simple = { limit = 100, period = 60 } ``` ```typescript const { success } = await env.RATE_LIMITER.limit({ key: userId }); if (!success) { return new Response("Rate limited", { status: 429 }); } ``` ### mTLS Present client certificates. ```toml [[mtls_certificates]] binding = "CERT" certificate_id = "your-cert-id" ``` ```typescript const response = await fetch("https://api.example.com", { certificate: env.CERT, }); ``` ## Best Practices ### Binding Selection - **KV**: Configuration, sessions, cache - **D1**: Structured data, complex queries - **R2**: Large files, media, backups - **Durable Objects**: Real-time, strong consistency, coordination - **Queues**: Background jobs, async processing - **Workers AI**: AI/ML inference - **Vectorize**: Similarity search, RAG ### Performance - Use `ctx.waitUntil()` for non-critical writes - Batch operations when possible - Use appropriate consistency models - Cache frequently accessed data ### Error Handling Always handle errors from bindings: ```typescript try { const value = await env.MY_KV.get("key"); } catch (error) { // Handle error console.error("KV error:", error); return new Response("Service unavailable", { status: 503 }); } ``` ### Local Development Use Wrangler for local testing with bindings: ```bash # KV wrangler kv:namespace create MY_KV --preview # D1 wrangler d1 create my-database # Local dev with bindings wrangler dev ``` ## Additional Resources - **Bindings Reference**: https://developers.cloudflare.com/workers/runtime-apis/bindings/ - **KV**: https://developers.cloudflare.com/kv/ - **D1**: https://developers.cloudflare.com/d1/ - **R2**: https://developers.cloudflare.com/r2/ - **Durable Objects**: https://developers.cloudflare.com/durable-objects/ - **Queues**: https://developers.cloudflare.com/queues/ - **Workers AI**: https://developers.cloudflare.com/workers-ai/ - **Vectorize**: https://developers.cloudflare.com/vectorize/