# Cloudflare Workers Advanced Patterns Advanced techniques for optimization, performance, and complex workflows. ## Session Reuse and Connection Pooling ### Durable Objects for Persistent Sessions ```typescript export class Browser { state: DurableObjectState; browser: any; lastUsed: number; constructor(state: DurableObjectState, env: Env) { this.state = state; this.lastUsed = Date.now(); } async fetch(request: Request, env: Env) { if (!this.browser) { this.browser = await puppeteer.launch(env.MYBROWSER); } this.lastUsed = Date.now(); await this.state.storage.setAlarm(Date.now() + 10000); const page = await this.browser.newPage(); await page.goto(new URL(request.url).searchParams.get('url')); const screenshot = await page.screenshot(); await page.close(); return new Response(screenshot); } async alarm() { if (Date.now() - this.lastUsed > 60000) { await this.browser?.close(); this.browser = null; } else { await this.state.storage.setAlarm(Date.now() + 10000); } } } ``` ## Multi-Tier Caching Strategy ```typescript const CACHE_TTL = 3600; export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { const cache = caches.default; const cacheKey = new Request(request.url); // 1. Check edge cache let response = await cache.match(cacheKey); if (response) return response; // 2. Check KV cache const kvCached = await env.MY_KV.get(request.url); if (kvCached) { response = new Response(kvCached); ctx.waitUntil(cache.put(cacheKey, response.clone())); return response; } // 3. Fetch from origin response = await fetch(request); // 4. Store in both caches ctx.waitUntil(Promise.all([ cache.put(cacheKey, response.clone()), env.MY_KV.put(request.url, await response.clone().text(), { expirationTtl: CACHE_TTL }) ])); return response; } }; ``` ## WebSocket with Durable Objects ```typescript export class ChatRoom { state: DurableObjectState; sessions: Set; constructor(state: DurableObjectState) { this.state = state; this.sessions = new Set(); } async fetch(request: Request) { const pair = new WebSocketPair(); const [client, server] = Object.values(pair); this.state.acceptWebSocket(server); this.sessions.add(server); return new Response(null, { status: 101, webSocket: client }); } async webSocketMessage(ws: WebSocket, message: string) { // Broadcast to all connected clients for (const session of this.sessions) { session.send(message); } } async webSocketClose(ws: WebSocket) { this.sessions.delete(ws); } } ``` ## Queue-Based Crawler ```typescript export default { async queue(batch: MessageBatch, env: Env): Promise { const browser = await puppeteer.launch(env.MYBROWSER); for (const message of batch.messages) { const page = await browser.newPage(); await page.goto(message.body.url); // Extract links const links = await page.evaluate(() => { return Array.from(document.querySelectorAll('a')) .map(a => a.href); }); // Queue new links for (const link of links) { await env.QUEUE.send({ url: link }); } await page.close(); message.ack(); } await browser.close(); } }; ``` ## Authentication Pattern ```typescript import { sign, verify } from 'hono/jwt'; async function authenticate(request: Request, env: Env): Promise { const authHeader = request.headers.get('Authorization'); if (!authHeader?.startsWith('Bearer ')) { throw new Error('Missing token'); } const token = authHeader.substring(7); const payload = await verify(token, env.JWT_SECRET); return payload; } export default { async fetch(request: Request, env: Env): Promise { try { const user = await authenticate(request, env); return new Response(`Hello ${user.name}`); } catch (error) { return new Response('Unauthorized', { status: 401 }); } } }; ``` ## Code Splitting ```typescript // Lazy load large dependencies export default { async fetch(request: Request): Promise { const url = new URL(request.url); if (url.pathname === '/heavy') { const { processHeavy } = await import('./heavy'); return processHeavy(request); } return new Response('OK'); } }; ``` ## Batch Operations with D1 ```typescript // Efficient bulk inserts const statements = users.map(user => env.DB.prepare('INSERT INTO users (name, email) VALUES (?, ?)') .bind(user.name, user.email) ); await env.DB.batch(statements); ``` ## Stream Processing ```typescript const { readable, writable } = new TransformStream({ transform(chunk, controller) { // Process chunk controller.enqueue(chunk); } }); response.body.pipeTo(writable); return new Response(readable); ``` ## AI-Powered Web Scraper ```typescript import { Ai } from '@cloudflare/ai'; export default { async fetch(request: Request, env: Env): Promise { // Render page const browser = await puppeteer.launch(env.MYBROWSER); const page = await browser.newPage(); await page.goto('https://news.ycombinator.com'); const content = await page.content(); await browser.close(); // Extract with AI const ai = new Ai(env.AI); const response = await ai.run('@cf/meta/llama-3-8b-instruct', { messages: [ { role: 'system', content: 'Extract top 5 article titles and URLs as JSON array' }, { role: 'user', content: content } ] }); return Response.json(response); } }; ``` ## Performance Optimization ### Bundle Size - Keep Workers <1MB bundled - Remove unused dependencies - Use code splitting - Check with: `wrangler deploy --dry-run --outdir=dist` ### Cold Starts - Minimize initialization code - Use bindings over fetch - Avoid large imports at top level ### Memory Management - Close pages when done: `await page.close()` - Disconnect browsers: `await browser.disconnect()` - Implement cleanup alarms in Durable Objects ### Request Optimization - Use server-side filtering with `--filter` - Batch operations with D1 `.batch()` - Stream large responses - Implement proper caching ## Monitoring & Debugging ```bash # Real-time logs wrangler tail --format pretty # Filter by status wrangler tail --status error # Check deployments wrangler deployments list # Rollback wrangler rollback [version-id] ``` ## Production Checklist - [ ] Multi-stage error handling implemented - [ ] Rate limiting configured - [ ] Caching strategy in place - [ ] Secrets managed with `wrangler secret` - [ ] Health checks implemented - [ ] Monitoring alerts configured - [ ] Session reuse for browser rendering - [ ] Resource cleanup (pages, browsers) - [ ] Proper timeout configurations - [ ] CI/CD pipeline set up ## Resources - Advanced Patterns: https://developers.cloudflare.com/workers/examples/ - Durable Objects: https://developers.cloudflare.com/workers/runtime-apis/durable-objects/ - Performance: https://developers.cloudflare.com/workers/platform/limits/