Cloudflare Workers Performance Optimization Techniques for maximizing Worker performance and minimizing latency. Quick Wins Critical Rules 1. Stay under CPU limits - 10ms (free), 30ms (paid), 50ms (unbound) 2. Minimize cold starts - Keep bundles < 1MB, avoid dynamic imports 3. Use Cache API - Cache responses at the edge 4. Stream large payloads - Don't buffer entire responses 5. Batch operations - Combine multiple KV/D1 calls Top 10 Performance Errors | Error | Symptom | Fix | |-------|---------|-----| | CPU limit exceeded | Worker terminated | Optimize hot paths, use streaming | | Cold start…

\\n' sorted=($(sort -n \u003c\u003c\u003c\"${times[*]}\"))\n unset IFS\n\n local min=\"${sorted[0]}\"\n local max=\"${sorted[$((count-1))]}\"\n local avg=$(echo \"scale=2; $total_time / $count\" | bc)\n\n # Percentiles\n local p50_idx=$((count * 50 / 100))\n local p90_idx=$((count * 90 / 100))\n local p95_idx=$((count * 95 / 100))\n local p99_idx=$((count * 99 / 100))\n\n local p50=\"${sorted[$p50_idx]}\"\n local p90=\"${sorted[$p90_idx]}\"\n local p95=\"${sorted[$p95_idx]}\"\n local p99=\"${sorted[$p99_idx]}\"\n\n # Standard deviation\n local sum_sq=0\n for t in \"${times[@]}\"; do\n local diff=$(echo \"$t - $avg\" | bc)\n sum_sq=$(echo \"$sum_sq + $diff * $diff\" | bc)\n done\n local stddev=$(echo \"scale=2; sqrt($sum_sq / $count)\" | bc)\n\n # Requests per second\n local total_sec=$(echo \"scale=3; $total_time / 1000\" | bc)\n local rps=$(echo \"scale=2; $count / $total_sec\" | bc)\n\n # Output based on format\n case \"$OUTPUT_FORMAT\" in\n json)\n output_json \"$total_requests\" \"$successful\" \"$failed\" \\\n \"$min\" \"$max\" \"$avg\" \"$stddev\" \\\n \"$p50\" \"$p90\" \"$p95\" \"$p99\" \"$rps\"\n ;;\n csv)\n output_csv \"$total_requests\" \"$successful\" \"$failed\" \\\n \"$min\" \"$max\" \"$avg\" \"$stddev\" \\\n \"$p50\" \"$p90\" \"$p95\" \"$p99\" \"$rps\"\n ;;\n *)\n output_text \"$total_requests\" \"$successful\" \"$failed\" \\\n \"$min\" \"$max\" \"$avg\" \"$stddev\" \\\n \"$p50\" \"$p90\" \"$p95\" \"$p99\" \"$rps\"\n ;;\n esac\n}\n\n# Text output\noutput_text() {\n local total=$1 successful=$2 failed=$3\n local min=$4 max=$5 avg=$6 stddev=$7\n local p50=$8 p90=$9 p95=${10} p99=${11} rps=${12}\n\n echo \"╔══════════════════════════════════════════════════════════════╗\"\n echo \"║ BENCHMARK RESULTS ║\"\n echo \"╚══════════════════════════════════════════════════════════════╝\"\n echo \"\"\n echo \"Summary:\"\n echo \" Total Requests: $total\"\n echo \" Successful: $successful ($(echo \"scale=1; $successful * 100 / $total\" | bc)%)\"\n echo \" Failed: $failed\"\n echo \" Requests/sec: $rps\"\n echo \"\"\n echo \"Latency (ms):\"\n echo \" Min: ${min}ms\"\n echo \" Max: ${max}ms\"\n echo \" Avg: ${avg}ms\"\n echo \" Std Dev: ${stddev}ms\"\n echo \"\"\n echo \"Percentiles:\"\n echo \" p50 (median): ${p50}ms\"\n echo \" p90: ${p90}ms\"\n echo \" p95: ${p95}ms\"\n echo \" p99: ${p99}ms\"\n echo \"\"\n\n # Performance assessment\n echo \"Assessment:\"\n if (( $(echo \"$p50 \u003c 50\" | bc -l) )); then\n echo -e \" ${GREEN}✓ Excellent p50 latency (\u003c 50ms)${NC}\"\n elif (( $(echo \"$p50 \u003c 100\" | bc -l) )); then\n echo -e \" ${YELLOW}○ Good p50 latency (50-100ms)${NC}\"\n else\n echo -e \" ${RED}✗ High p50 latency (> 100ms)${NC}\"\n fi\n\n if (( $(echo \"$p99 \u003c 200\" | bc -l) )); then\n echo -e \" ${GREEN}✓ Excellent p99 latency (\u003c 200ms)${NC}\"\n elif (( $(echo \"$p99 \u003c 500\" | bc -l) )); then\n echo -e \" ${YELLOW}○ Good p99 latency (200-500ms)${NC}\"\n else\n echo -e \" ${RED}✗ High p99 latency (> 500ms)${NC}\"\n fi\n\n if [ -n \"$OUTPUT_FILE\" ]; then\n # Save to file as well\n {\n echo \"url: $URL\"\n echo \"total_requests: $total\"\n echo \"successful: $successful\"\n echo \"failed: $failed\"\n echo \"rps: $rps\"\n echo \"min_ms: $min\"\n echo \"max_ms: $max\"\n echo \"avg_ms: $avg\"\n echo \"stddev_ms: $stddev\"\n echo \"p50_ms: $p50\"\n echo \"p90_ms: $p90\"\n echo \"p95_ms: $p95\"\n echo \"p99_ms: $p99\"\n } > \"$OUTPUT_FILE\"\n info \"Results saved to $OUTPUT_FILE\"\n fi\n}\n\n# JSON output\noutput_json() {\n local total=$1 successful=$2 failed=$3\n local min=$4 max=$5 avg=$6 stddev=$7\n local p50=$8 p90=$9 p95=${10} p99=${11} rps=${12}\n\n local json=$(cat \u003c\u003cEOF\n{\n \"url\": \"$URL\",\n \"method\": \"$METHOD\",\n \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\n \"summary\": {\n \"total_requests\": $total,\n \"successful\": $successful,\n \"failed\": $failed,\n \"requests_per_second\": $rps\n },\n \"latency_ms\": {\n \"min\": $min,\n \"max\": $max,\n \"avg\": $avg,\n \"stddev\": $stddev\n },\n \"percentiles_ms\": {\n \"p50\": $p50,\n \"p90\": $p90,\n \"p95\": $p95,\n \"p99\": $p99\n }\n}\nEOF\n)\n\n if [ -n \"$OUTPUT_FILE\" ]; then\n echo \"$json\" | jq '.' > \"$OUTPUT_FILE\"\n info \"Results saved to $OUTPUT_FILE\"\n else\n echo \"$json\" | jq '.'\n fi\n}\n\n# CSV output\noutput_csv() {\n local total=$1 successful=$2 failed=$3\n local min=$4 max=$5 avg=$6 stddev=$7\n local p50=$8 p90=$9 p95=${10} p99=${11} rps=${12}\n\n local csv=\"url,method,timestamp,total,successful,failed,rps,min_ms,max_ms,avg_ms,stddev_ms,p50_ms,p90_ms,p95_ms,p99_ms\"\n csv+=\"\\n$URL,$METHOD,$(date -u +%Y-%m-%dT%H:%M:%SZ),$total,$successful,$failed,$rps,$min,$max,$avg,$stddev,$p50,$p90,$p95,$p99\"\n\n if [ -n \"$OUTPUT_FILE\" ]; then\n echo -e \"$csv\" > \"$OUTPUT_FILE\"\n info \"Results saved to $OUTPUT_FILE\"\n else\n echo -e \"$csv\"\n fi\n}\n\n# Main\nmain() {\n parse_args \"$@\"\n check_deps\n warmup\n run_benchmark\n}\n\nmain \"$@\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":11985,"content_sha256":"6509a9455ba8a1c311c6a0fc35aaf8301603fcc95f6109552be0e4262d7375b3"},{"filename":"scripts/profile-worker.sh","content":"#!/bin/bash\n\n# Worker Profiling Script\n#\n# Features:\n# - CPU time analysis from Server-Timing headers\n# - Cold start detection and tracking\n# - Response time breakdown\n# - Memory estimation via payload size\n# - Comparative analysis (before/after)\n#\n# Usage:\n# ./profile-worker.sh \u003curl> [options]\n#\n# Examples:\n# ./profile-worker.sh https://my-worker.workers.dev/api\n# ./profile-worker.sh https://my-worker.workers.dev/api --iterations 20\n# ./profile-worker.sh https://my-worker.workers.dev/api --compare baseline.json\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nNC='\\033[0m'\n\n# Configuration\nURL=\"\"\nITERATIONS=10\nDELAY=0.5\nFORCE_COLD=false\nCOMPARE_FILE=\"\"\nOUTPUT_FILE=\"\"\nVERBOSE=false\n\n# Logging\ninfo() { echo -e \"${BLUE}[INFO]${NC} $1\"; }\nsuccess() { echo -e \"${GREEN}[SUCCESS]${NC} $1\"; }\nwarn() { echo -e \"${YELLOW}[WARN]${NC} $1\"; }\nerror() { echo -e \"${RED}[ERROR]${NC} $1\"; exit 1; }\ndebug() { [ \"$VERBOSE\" = true ] && echo -e \"${CYAN}[DEBUG]${NC} $1\"; }\n\n# Usage\nusage() {\n cat \u003c\u003c EOF\nWorker Profiling Tool\n\nAnalyzes Cloudflare Worker performance by examining Server-Timing headers\nand response characteristics.\n\nUsage: $0 \u003curl> [options]\n\nOptions:\n -i, --iterations NUM Number of profiling iterations (default: 10)\n -d, --delay SEC Delay between requests (default: 0.5)\n --force-cold Wait 30s between requests to force cold starts\n -c, --compare FILE Compare with baseline JSON file\n -o, --output FILE Save results to JSON file\n -v, --verbose Verbose output\n -h, --help Show this help\n\nExamples:\n $0 https://api.example.com/profile\n $0 https://api.example.com/api -i 20 -o profile.json\n $0 https://api.example.com/api --force-cold\n $0 https://api.example.com/api --compare old-profile.json\n\nThe worker should include Server-Timing headers:\n Server-Timing: total;dur=15.5, db;dur=8.2, cache;dur=0.5\n\nAnd optionally:\n X-Cold-Start: true/false\n X-Response-Time: 15.5ms\n\nEOF\n exit 0\n}\n\n# Parse arguments\nparse_args() {\n if [ $# -eq 0 ]; then\n usage\n fi\n\n URL=\"$1\"\n shift\n\n while [ $# -gt 0 ]; do\n case \"$1\" in\n -i|--iterations)\n ITERATIONS=\"$2\"\n shift 2\n ;;\n -d|--delay)\n DELAY=\"$2\"\n shift 2\n ;;\n --force-cold)\n FORCE_COLD=true\n shift\n ;;\n -c|--compare)\n COMPARE_FILE=\"$2\"\n shift 2\n ;;\n -o|--output)\n OUTPUT_FILE=\"$2\"\n shift 2\n ;;\n -v|--verbose)\n VERBOSE=true\n shift\n ;;\n -h|--help)\n usage\n ;;\n *)\n error \"Unknown option: $1\"\n ;;\n esac\n done\n\n if [ -z \"$URL\" ]; then\n error \"URL is required\"\n fi\n}\n\n# Check dependencies\ncheck_deps() {\n for cmd in curl jq bc; do\n if ! command -v \"$cmd\" &> /dev/null; then\n error \"$cmd is required. Please install it.\"\n fi\n done\n}\n\n# Parse Server-Timing header\nparse_server_timing() {\n local header=\"$1\"\n local timings=\"{}\"\n\n # Parse each timing entry: name;dur=value,name2;dur=value2\n while IFS=',' read -ra entries; do\n for entry in \"${entries[@]}\"; do\n entry=$(echo \"$entry\" | xargs) # Trim whitespace\n if [[ \"$entry\" =~ ([^;]+)\\;dur=([0-9.]+) ]]; then\n local name=\"${BASH_REMATCH[1]}\"\n local duration=\"${BASH_REMATCH[2]}\"\n timings=$(echo \"$timings\" | jq --arg n \"$name\" --arg d \"$duration\" '. + {($n): ($d | tonumber)}')\n fi\n done\n done \u003c\u003c\u003c \"$header\"\n\n echo \"$timings\"\n}\n\n# Make profiling request\nprofile_request() {\n local result\n local headers_file=$(mktemp)\n\n # Make request and capture headers\n local body\n body=$(curl -s -D \"$headers_file\" \\\n --max-time 30 \\\n -H \"Accept: application/json\" \\\n \"$URL\" 2>/dev/null)\n\n local status=$(grep -i \"HTTP/\" \"$headers_file\" | tail -1 | awk '{print $2}')\n local server_timing=$(grep -i \"Server-Timing:\" \"$headers_file\" | sed 's/[Ss]erver-[Tt]iming: //i' | tr -d '\\r')\n local response_time=$(grep -i \"X-Response-Time:\" \"$headers_file\" | sed 's/[Xx]-[Rr]esponse-[Tt]ime: //i' | tr -d '\\r' | sed 's/ms//')\n local cold_start=$(grep -i \"X-Cold-Start:\" \"$headers_file\" | sed 's/[Xx]-[Cc]old-[Ss]tart: //i' | tr -d '\\r')\n local content_length=$(grep -i \"Content-Length:\" \"$headers_file\" | sed 's/[Cc]ontent-[Ll]ength: //i' | tr -d '\\r')\n\n # Parse timings\n local timings=\"{}\"\n if [ -n \"$server_timing\" ]; then\n timings=$(parse_server_timing \"$server_timing\")\n fi\n\n # Estimate response size\n local size=${content_length:-$(echo -n \"$body\" | wc -c)}\n\n # Build result\n local result=$(jq -n \\\n --arg status \"$status\" \\\n --arg response_time \"${response_time:-0}\" \\\n --arg cold \"${cold_start:-false}\" \\\n --arg size \"$size\" \\\n --argjson timings \"$timings\" \\\n '{\n status: ($status | tonumber),\n response_time_ms: ($response_time | tonumber),\n cold_start: ($cold == \"true\"),\n size_bytes: ($size | tonumber),\n timings: $timings\n }')\n\n rm -f \"$headers_file\"\n echo \"$result\"\n}\n\n# Run profiling\nrun_profiling() {\n info \"Profiling: $URL\"\n info \"Iterations: $ITERATIONS\"\n echo \"\"\n\n local results=\"[]\"\n local cold_count=0\n local warm_count=0\n\n for i in $(seq 1 \"$ITERATIONS\"); do\n printf \"\\r[%3d%%] Iteration %d/%d\" \"$((i * 100 / ITERATIONS))\" \"$i\" \"$ITERATIONS\"\n\n local result=$(profile_request)\n results=$(echo \"$results\" | jq --argjson r \"$result\" '. + [$r]')\n\n # Count cold/warm\n if echo \"$result\" | jq -e '.cold_start == true' > /dev/null; then\n ((cold_count++)) || true\n else\n ((warm_count++)) || true\n fi\n\n debug \"Result: $result\"\n\n # Delay between requests\n if [ \"$FORCE_COLD\" = true ]; then\n info \"Waiting 30s for cold start...\"\n sleep 30\n else\n sleep \"$DELAY\"\n fi\n done\n\n echo \"\"\n echo \"\"\n\n # Analyze results\n analyze_results \"$results\" \"$cold_count\" \"$warm_count\"\n}\n\n# Analyze and display results\nanalyze_results() {\n local results=\"$1\"\n local cold_count=\"$2\"\n local warm_count=\"$3\"\n\n # Calculate statistics\n local stats=$(echo \"$results\" | jq '\n {\n count: length,\n response_times: [.[].response_time_ms] | sort,\n sizes: [.[].size_bytes],\n cold_starts: [.[] | select(.cold_start == true)] | length,\n all_timings: [.[].timings] | add\n } |\n {\n count: .count,\n cold_starts: .cold_starts,\n response: {\n min: (.response_times | min),\n max: (.response_times | max),\n avg: ((.response_times | add) / .count),\n p50: .response_times[(.count / 2 | floor)],\n p95: .response_times[((.count * 0.95) | floor)],\n p99: .response_times[((.count * 0.99) | floor)]\n },\n size: {\n avg: ((.sizes | add) / .count)\n },\n timings: (\n if .all_timings then\n .all_timings | to_entries | group_by(.key) | map({\n key: .[0].key,\n value: {\n avg: ([.[].value] | add / length),\n min: ([.[].value] | min),\n max: ([.[].value] | max)\n }\n }) | from_entries\n else {}\n end\n )\n }\n ')\n\n # Display results\n echo \"╔══════════════════════════════════════════════════════════════╗\"\n echo \"║ PROFILING RESULTS ║\"\n echo \"╚══════════════════════════════════════════════════════════════╝\"\n echo \"\"\n\n echo \"Summary:\"\n echo \" Iterations: $ITERATIONS\"\n echo \" Cold Starts: $cold_count ($(echo \"scale=1; $cold_count * 100 / $ITERATIONS\" | bc)%)\"\n echo \" Warm Requests: $warm_count ($(echo \"scale=1; $warm_count * 100 / $ITERATIONS\" | bc)%)\"\n echo \"\"\n\n echo \"Response Time (ms):\"\n echo \"$stats\" | jq -r '.response | \" Min: \\(.min)ms\\n Max: \\(.max)ms\\n Avg: \\(.avg | floor)ms\\n p50: \\(.p50)ms\\n p95: \\(.p95)ms\\n p99: \\(.p99)ms\"'\n echo \"\"\n\n echo \"Response Size:\"\n echo \"$stats\" | jq -r '.size | \" Average: \\(.avg | floor) bytes\"'\n echo \"\"\n\n # Show individual timing breakdowns\n local timing_keys=$(echo \"$stats\" | jq -r '.timings | keys[]' 2>/dev/null)\n if [ -n \"$timing_keys\" ]; then\n echo \"Server Timing Breakdown (avg ms):\"\n echo \"$stats\" | jq -r '.timings | to_entries[] | \" \\(.key): \\(.value.avg | floor)ms (min: \\(.value.min), max: \\(.value.max))\"'\n echo \"\"\n fi\n\n # Performance assessment\n echo \"Assessment:\"\n local avg_time=$(echo \"$stats\" | jq '.response.avg')\n\n if (( $(echo \"$avg_time \u003c 20\" | bc -l) )); then\n echo -e \" ${GREEN}✓ Excellent average response time (\u003c 20ms)${NC}\"\n elif (( $(echo \"$avg_time \u003c 50\" | bc -l) )); then\n echo -e \" ${GREEN}✓ Good average response time (20-50ms)${NC}\"\n elif (( $(echo \"$avg_time \u003c 100\" | bc -l) )); then\n echo -e \" ${YELLOW}○ Moderate response time (50-100ms)${NC}\"\n else\n echo -e \" ${RED}✗ High response time (> 100ms)${NC}\"\n fi\n\n if [ \"$cold_count\" -gt 0 ]; then\n if (( $(echo \"$cold_count > $ITERATIONS / 2\" | bc -l) )); then\n echo -e \" ${RED}✗ High cold start rate - consider warming${NC}\"\n else\n echo -e \" ${YELLOW}○ Some cold starts detected${NC}\"\n fi\n else\n echo -e \" ${GREEN}✓ No cold starts detected${NC}\"\n fi\n\n # Compare with baseline\n if [ -n \"$COMPARE_FILE\" ] && [ -f \"$COMPARE_FILE\" ]; then\n echo \"\"\n echo \"Comparison with baseline ($COMPARE_FILE):\"\n compare_with_baseline \"$stats\"\n fi\n\n # Save output\n if [ -n \"$OUTPUT_FILE\" ]; then\n local full_results=$(jq -n \\\n --arg url \"$URL\" \\\n --arg timestamp \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \\\n --argjson stats \"$stats\" \\\n --argjson raw \"$results\" \\\n '{\n url: $url,\n timestamp: $timestamp,\n stats: $stats,\n raw_results: $raw\n }')\n\n echo \"$full_results\" > \"$OUTPUT_FILE\"\n info \"Results saved to $OUTPUT_FILE\"\n fi\n}\n\n# Compare with baseline\ncompare_with_baseline() {\n local current=\"$1\"\n local baseline=$(cat \"$COMPARE_FILE\")\n\n local curr_avg=$(echo \"$current\" | jq '.response.avg')\n local base_avg=$(echo \"$baseline\" | jq '.stats.response.avg')\n\n local diff=$(echo \"scale=2; $curr_avg - $base_avg\" | bc)\n local pct=$(echo \"scale=1; ($diff / $base_avg) * 100\" | bc)\n\n if (( $(echo \"$diff \u003c 0\" | bc -l) )); then\n echo -e \" ${GREEN}↓ Response time improved by ${diff#-}ms (${pct#-}% faster)${NC}\"\n elif (( $(echo \"$diff > 0\" | bc -l) )); then\n echo -e \" ${RED}↑ Response time degraded by ${diff}ms (${pct}% slower)${NC}\"\n else\n echo -e \" ${BLUE}= Response time unchanged${NC}\"\n fi\n\n local curr_cold=$(echo \"$current\" | jq '.cold_starts')\n local base_cold=$(echo \"$baseline\" | jq '.stats.cold_starts')\n\n if [ \"$curr_cold\" -lt \"$base_cold\" ]; then\n echo -e \" ${GREEN}↓ Fewer cold starts ($curr_cold vs $base_cold)${NC}\"\n elif [ \"$curr_cold\" -gt \"$base_cold\" ]; then\n echo -e \" ${RED}↑ More cold starts ($curr_cold vs $base_cold)${NC}\"\n fi\n}\n\n# Main\nmain() {\n parse_args \"$@\"\n check_deps\n run_profiling\n}\n\nmain \"$@\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":12407,"content_sha256":"68ee20a09cde9124d3aa7d2577999cf64e01148f5e21e0c8cbc7dad9bc01cc9e"},{"filename":"templates/caching-layer.ts","content":"/**\n * Multi-Layer Caching System for Cloudflare Workers\n *\n * Features:\n * - Memory cache (request-scoped, fastest)\n * - Edge cache (Cache API, per-colo)\n * - KV cache (global, persistent)\n * - Stale-while-revalidate pattern\n * - Cache tags for invalidation\n * - TTL management\n *\n * Usage:\n * 1. Initialize cache layers\n * 2. Use get/set methods\n * 3. Implement cache-aside pattern\n */\n\n// ============================================\n// TYPES\n// ============================================\n\ninterface CacheEntry\u003cT> {\n data: T;\n timestamp: number;\n ttl: number;\n tags?: string[];\n}\n\ninterface CacheLayer\u003cT> {\n get(key: string): Promise\u003cT | null>;\n set(key: string, value: T, options?: CacheOptions): Promise\u003cvoid>;\n delete(key: string): Promise\u003cvoid>;\n has(key: string): Promise\u003cboolean>;\n}\n\ninterface CacheOptions {\n ttl?: number; // Time to live in seconds\n tags?: string[]; // Cache tags for invalidation\n staleWhileRevalidate?: number; // Serve stale for this many seconds\n}\n\ninterface CacheStats {\n hits: number;\n misses: number;\n hitRate: number;\n}\n\n// ============================================\n// MEMORY CACHE (Request-Scoped)\n// ============================================\n\nexport class MemoryCache\u003cT> implements CacheLayer\u003cT> {\n private cache = new Map\u003cstring, CacheEntry\u003cT>>();\n private maxSize: number;\n private stats = { hits: 0, misses: 0 };\n\n constructor(maxSize = 100) {\n this.maxSize = maxSize;\n }\n\n async get(key: string): Promise\u003cT | null> {\n const entry = this.cache.get(key);\n\n if (!entry) {\n this.stats.misses++;\n return null;\n }\n\n // Check expiration\n if (this.isExpired(entry)) {\n this.cache.delete(key);\n this.stats.misses++;\n return null;\n }\n\n this.stats.hits++;\n return entry.data;\n }\n\n async set(key: string, value: T, options?: CacheOptions): Promise\u003cvoid> {\n // Evict if at capacity (LRU-style)\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey) this.cache.delete(firstKey);\n }\n\n this.cache.set(key, {\n data: value,\n timestamp: Date.now(),\n ttl: options?.ttl ?? 60,\n tags: options?.tags,\n });\n }\n\n async delete(key: string): Promise\u003cvoid> {\n this.cache.delete(key);\n }\n\n async has(key: string): Promise\u003cboolean> {\n const entry = this.cache.get(key);\n return entry !== undefined && !this.isExpired(entry);\n }\n\n getStats(): CacheStats {\n const total = this.stats.hits + this.stats.misses;\n return {\n ...this.stats,\n hitRate: total > 0 ? this.stats.hits / total : 0,\n };\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n private isExpired(entry: CacheEntry\u003cT>): boolean {\n return Date.now() > entry.timestamp + entry.ttl * 1000;\n }\n}\n\n// ============================================\n// EDGE CACHE (Cache API)\n// ============================================\n\nexport class EdgeCache\u003cT> implements CacheLayer\u003cT> {\n private cache: Cache;\n private prefix: string;\n private stats = { hits: 0, misses: 0 };\n\n constructor(prefix = 'edge-cache:') {\n this.cache = caches.default;\n this.prefix = prefix;\n }\n\n private getCacheKey(key: string): Request {\n return new Request(`https://cache/${this.prefix}${key}`);\n }\n\n async get(key: string): Promise\u003cT | null> {\n const response = await this.cache.match(this.getCacheKey(key));\n\n if (!response) {\n this.stats.misses++;\n return null;\n }\n\n this.stats.hits++;\n return response.json();\n }\n\n async set(key: string, value: T, options?: CacheOptions): Promise\u003cvoid> {\n const ttl = options?.ttl ?? 3600;\n\n const response = new Response(JSON.stringify(value), {\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': `max-age=${ttl}`,\n 'X-Cache-Tags': options?.tags?.join(',') ?? '',\n 'X-Cache-Timestamp': Date.now().toString(),\n },\n });\n\n await this.cache.put(this.getCacheKey(key), response);\n }\n\n async delete(key: string): Promise\u003cvoid> {\n await this.cache.delete(this.getCacheKey(key));\n }\n\n async has(key: string): Promise\u003cboolean> {\n const response = await this.cache.match(this.getCacheKey(key));\n return response !== undefined;\n }\n\n getStats(): CacheStats {\n const total = this.stats.hits + this.stats.misses;\n return {\n ...this.stats,\n hitRate: total > 0 ? this.stats.hits / total : 0,\n };\n }\n}\n\n// ============================================\n// KV CACHE (Global)\n// ============================================\n\nexport class KVCache\u003cT> implements CacheLayer\u003cT> {\n private kv: KVNamespace;\n private prefix: string;\n private stats = { hits: 0, misses: 0 };\n\n constructor(kv: KVNamespace, prefix = 'kv-cache:') {\n this.kv = kv;\n this.prefix = prefix;\n }\n\n async get(key: string): Promise\u003cT | null> {\n const value = await this.kv.get\u003cCacheEntry\u003cT>>(this.prefix + key, 'json');\n\n if (!value) {\n this.stats.misses++;\n return null;\n }\n\n // Check if expired (belt and suspenders with KV expirationTtl)\n if (Date.now() > value.timestamp + value.ttl * 1000) {\n this.stats.misses++;\n return null;\n }\n\n this.stats.hits++;\n return value.data;\n }\n\n async set(key: string, value: T, options?: CacheOptions): Promise\u003cvoid> {\n const ttl = options?.ttl ?? 3600;\n\n const entry: CacheEntry\u003cT> = {\n data: value,\n timestamp: Date.now(),\n ttl,\n tags: options?.tags,\n };\n\n await this.kv.put(this.prefix + key, JSON.stringify(entry), {\n expirationTtl: ttl,\n });\n\n // Store tag associations\n if (options?.tags) {\n for (const tag of options.tags) {\n const tagKey = `tag:${tag}`;\n const existingKeys = await this.kv.get\u003cstring[]>(tagKey, 'json') ?? [];\n if (!existingKeys.includes(key)) {\n existingKeys.push(key);\n await this.kv.put(tagKey, JSON.stringify(existingKeys));\n }\n }\n }\n }\n\n async delete(key: string): Promise\u003cvoid> {\n await this.kv.delete(this.prefix + key);\n }\n\n async has(key: string): Promise\u003cboolean> {\n const value = await this.kv.get(this.prefix + key);\n return value !== null;\n }\n\n async invalidateByTag(tag: string): Promise\u003cvoid> {\n const tagKey = `tag:${tag}`;\n const keys = await this.kv.get\u003cstring[]>(tagKey, 'json') ?? [];\n\n await Promise.all([\n ...keys.map((key) => this.delete(key)),\n this.kv.delete(tagKey),\n ]);\n }\n\n getStats(): CacheStats {\n const total = this.stats.hits + this.stats.misses;\n return {\n ...this.stats,\n hitRate: total > 0 ? this.stats.hits / total : 0,\n };\n }\n}\n\n// ============================================\n// MULTI-LAYER CACHE\n// ============================================\n\nexport class MultiLayerCache\u003cT> implements CacheLayer\u003cT> {\n private layers: CacheLayer\u003cT>[];\n\n constructor(layers: CacheLayer\u003cT>[]) {\n this.layers = layers;\n }\n\n async get(key: string): Promise\u003cT | null> {\n for (let i = 0; i \u003c this.layers.length; i++) {\n const value = await this.layers[i].get(key);\n\n if (value !== null) {\n // Populate upper layers (don't await, do in background)\n this.populateUpperLayers(key, value, i);\n return value;\n }\n }\n\n return null;\n }\n\n async set(key: string, value: T, options?: CacheOptions): Promise\u003cvoid> {\n // Set in all layers\n await Promise.all(\n this.layers.map((layer) => layer.set(key, value, options))\n );\n }\n\n async delete(key: string): Promise\u003cvoid> {\n await Promise.all(this.layers.map((layer) => layer.delete(key)));\n }\n\n async has(key: string): Promise\u003cboolean> {\n for (const layer of this.layers) {\n if (await layer.has(key)) {\n return true;\n }\n }\n return false;\n }\n\n private async populateUpperLayers(\n key: string,\n value: T,\n foundAtIndex: number\n ): Promise\u003cvoid> {\n // Populate all layers above where we found the value\n const upperLayers = this.layers.slice(0, foundAtIndex);\n await Promise.all(upperLayers.map((layer) => layer.set(key, value)));\n }\n}\n\n// ============================================\n// CACHE-ASIDE PATTERN\n// ============================================\n\nexport class CacheAside\u003cT> {\n constructor(\n private cache: CacheLayer\u003cT>,\n private defaultTTL: number = 3600\n ) {}\n\n async get(\n key: string,\n fetcher: () => Promise\u003cT>,\n options?: CacheOptions\n ): Promise\u003cT> {\n // Try cache first\n const cached = await this.cache.get(key);\n if (cached !== null) {\n return cached;\n }\n\n // Cache miss - fetch data\n const data = await fetcher();\n\n // Store in cache (don't await for faster response)\n this.cache.set(key, data, {\n ttl: options?.ttl ?? this.defaultTTL,\n tags: options?.tags,\n });\n\n return data;\n }\n\n async invalidate(key: string): Promise\u003cvoid> {\n await this.cache.delete(key);\n }\n\n async refresh(\n key: string,\n fetcher: () => Promise\u003cT>,\n options?: CacheOptions\n ): Promise\u003cT> {\n const data = await fetcher();\n await this.cache.set(key, data, options);\n return data;\n }\n}\n\n// ============================================\n// STALE-WHILE-REVALIDATE\n// ============================================\n\ninterface SWREntry\u003cT> {\n data: T;\n timestamp: number;\n maxAge: number;\n staleWhileRevalidate: number;\n}\n\nexport class SWRCache\u003cT> {\n private cache: CacheLayer\u003cSWREntry\u003cT>>;\n private revalidating = new Set\u003cstring>();\n\n constructor(cache: CacheLayer\u003cSWREntry\u003cT>>) {\n this.cache = cache;\n }\n\n async get(\n key: string,\n fetcher: () => Promise\u003cT>,\n options: { maxAge: number; staleWhileRevalidate: number }\n ): Promise\u003cT> {\n const cached = await this.cache.get(key);\n\n if (cached) {\n const age = (Date.now() - cached.timestamp) / 1000;\n\n // Fresh\n if (age \u003c cached.maxAge) {\n return cached.data;\n }\n\n // Stale but within SWR window\n if (age \u003c cached.maxAge + cached.staleWhileRevalidate) {\n // Revalidate in background\n if (!this.revalidating.has(key)) {\n this.revalidating.add(key);\n this.revalidate(key, fetcher, options).finally(() => {\n this.revalidating.delete(key);\n });\n }\n return cached.data;\n }\n }\n\n // No cache or too stale - fetch fresh\n return this.revalidate(key, fetcher, options);\n }\n\n private async revalidate(\n key: string,\n fetcher: () => Promise\u003cT>,\n options: { maxAge: number; staleWhileRevalidate: number }\n ): Promise\u003cT> {\n const data = await fetcher();\n\n await this.cache.set(key, {\n data,\n timestamp: Date.now(),\n maxAge: options.maxAge,\n staleWhileRevalidate: options.staleWhileRevalidate,\n });\n\n return data;\n }\n}\n\n// ============================================\n// RESPONSE CACHE (HTTP Responses)\n// ============================================\n\nexport class ResponseCache {\n private cache = caches.default;\n\n async match(request: Request): Promise\u003cResponse | undefined> {\n return this.cache.match(this.getCacheKey(request));\n }\n\n async put(\n request: Request,\n response: Response,\n options?: { maxAge?: number; vary?: string[] }\n ): Promise\u003cvoid> {\n const cacheableResponse = new Response(response.body, response);\n\n // Set cache headers\n cacheableResponse.headers.set(\n 'Cache-Control',\n `public, max-age=${options?.maxAge ?? 3600}`\n );\n\n if (options?.vary) {\n cacheableResponse.headers.set('Vary', options.vary.join(', '));\n }\n\n await this.cache.put(this.getCacheKey(request), cacheableResponse);\n }\n\n async delete(request: Request): Promise\u003cboolean> {\n return this.cache.delete(this.getCacheKey(request));\n }\n\n private getCacheKey(request: Request): Request {\n // Normalize cache key\n const url = new URL(request.url);\n url.searchParams.sort();\n\n // Remove tracking params\n ['utm_source', 'utm_medium', 'utm_campaign', 'fbclid'].forEach((param) => {\n url.searchParams.delete(param);\n });\n\n return new Request(url.toString(), {\n method: 'GET',\n });\n }\n}\n\n// ============================================\n// FACTORY FUNCTION\n// ============================================\n\nexport function createCacheSystem\u003cT>(\n kv?: KVNamespace,\n options?: { memorySize?: number; prefix?: string }\n): MultiLayerCache\u003cT> {\n const layers: CacheLayer\u003cT>[] = [\n new MemoryCache\u003cT>(options?.memorySize ?? 100),\n new EdgeCache\u003cT>(options?.prefix ?? 'cache:'),\n ];\n\n if (kv) {\n layers.push(new KVCache\u003cT>(kv, options?.prefix ?? 'cache:'));\n }\n\n return new MultiLayerCache\u003cT>(layers);\n}\n\n// ============================================\n// EXAMPLE USAGE\n// ============================================\n\n/*\nimport { createCacheSystem, CacheAside, ResponseCache } from './caching-layer';\n\ninterface Env {\n KV: KVNamespace;\n}\n\ninterface User {\n id: string;\n name: string;\n}\n\nexport default {\n async fetch(request: Request, env: Env): Promise\u003cResponse> {\n // Option 1: Multi-layer cache\n const cache = createCacheSystem\u003cUser>(env.KV);\n const user = await cache.get('user:123');\n\n // Option 2: Cache-aside pattern\n const userCache = new CacheAside\u003cUser>(cache);\n const userData = await userCache.get(\n 'user:123',\n async () => {\n return fetchUserFromDB('123');\n },\n { ttl: 3600, tags: ['users'] }\n );\n\n // Option 3: Response caching\n const responseCache = new ResponseCache();\n const cached = await responseCache.match(request);\n if (cached) {\n return cached;\n }\n\n const response = await generateResponse(request);\n await responseCache.put(request, response.clone(), { maxAge: 300 });\n\n return response;\n },\n};\n*/\n","content_type":"text/typescript; charset=utf-8","language":"typescript","size":13724,"content_sha256":"7fa4f696580dca50ba6d6f01a242caed96cad6e689c055e304862841a0dda242"},{"filename":"templates/optimized-worker.ts","content":"/**\n * Optimized Cloudflare Worker Template\n *\n * Features:\n * - Performance-first architecture\n * - Multi-layer caching\n * - Lazy initialization\n * - Streaming responses\n * - Cold start optimization\n * - Request coalescing\n *\n * Usage:\n * 1. Copy as src/index.ts\n * 2. Configure wrangler.jsonc\n * 3. Customize handlers\n */\n\nimport { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { compress } from 'hono/compress';\n\n// ============================================\n// TYPES\n// ============================================\n\ninterface Env {\n ENVIRONMENT: string;\n KV: KVNamespace;\n DB: D1Database;\n ANALYTICS?: AnalyticsEngineDataset;\n}\n\ninterface CacheEntry\u003cT> {\n data: T;\n timestamp: number;\n ttl: number;\n}\n\n// ============================================\n// LAZY INITIALIZATION\n// ============================================\n\n// Avoid expensive top-level operations\n// Initialize on first use, reuse across requests\n\nlet dbInitialized = false;\nlet routeCache: Map\u003cstring, unknown> | undefined;\n\nfunction getRouteCache(): Map\u003cstring, unknown> {\n if (!routeCache) {\n routeCache = new Map();\n }\n return routeCache;\n}\n\n// ============================================\n// COLD START TRACKING\n// ============================================\n\nlet isWarm = false;\nlet requestCount = 0;\n\nfunction trackColdStart(): boolean {\n const wasCold = !isWarm;\n isWarm = true;\n requestCount++;\n return wasCold;\n}\n\n// ============================================\n// MEMORY CACHE (Per-Isolate)\n// ============================================\n\nclass IsolateCache\u003cT> {\n private cache = new Map\u003cstring, CacheEntry\u003cT>>();\n private maxSize: number;\n\n constructor(maxSize = 50) {\n this.maxSize = maxSize;\n }\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n // Check TTL\n if (Date.now() > entry.timestamp + entry.ttl * 1000) {\n this.cache.delete(key);\n return undefined;\n }\n\n return entry.data;\n }\n\n set(key: string, data: T, ttl = 60): void {\n // Evict oldest if full\n if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey) this.cache.delete(oldestKey);\n }\n\n this.cache.set(key, { data, timestamp: Date.now(), ttl });\n }\n\n delete(key: string): void {\n this.cache.delete(key);\n }\n}\n\n// Singleton cache instance (persists across requests in same isolate)\nconst memoryCache = new IsolateCache\u003cunknown>(100);\n\n// ============================================\n// REQUEST COALESCING\n// ============================================\n\nconst inflight = new Map\u003cstring, Promise\u003cunknown>>();\n\nasync function coalesce\u003cT>(key: string, fetcher: () => Promise\u003cT>): Promise\u003cT> {\n // Check if request already in flight\n const existing = inflight.get(key);\n if (existing) {\n return existing as Promise\u003cT>;\n }\n\n // Start new request\n const promise = fetcher().finally(() => {\n inflight.delete(key);\n });\n\n inflight.set(key, promise);\n return promise;\n}\n\n// ============================================\n// MULTI-LAYER CACHE\n// ============================================\n\nasync function getCached\u003cT>(\n key: string,\n kv: KVNamespace,\n fetcher: () => Promise\u003cT>,\n ttl = 300\n): Promise\u003cT> {\n // Layer 1: Memory cache\n const memCached = memoryCache.get(key) as T | undefined;\n if (memCached !== undefined) {\n return memCached;\n }\n\n // Layer 2: Edge cache\n const edgeCache = caches.default;\n const cacheKey = new Request(`https://cache/${key}`);\n const edgeCached = await edgeCache.match(cacheKey);\n\n if (edgeCached) {\n const data = await edgeCached.json\u003cT>();\n memoryCache.set(key, data, ttl);\n return data;\n }\n\n // Layer 3: KV\n const kvCached = await kv.get\u003cT>(key, 'json');\n if (kvCached !== null) {\n // Populate upper layers\n memoryCache.set(key, kvCached, ttl);\n edgeCache.put(\n cacheKey,\n new Response(JSON.stringify(kvCached), {\n headers: { 'Cache-Control': `max-age=${ttl}` },\n })\n );\n return kvCached;\n }\n\n // Cache miss - fetch and populate all layers\n const data = await coalesce(key, fetcher);\n\n // Don't await - populate cache in background\n Promise.all([\n kv.put(key, JSON.stringify(data), { expirationTtl: ttl }),\n edgeCache.put(\n cacheKey,\n new Response(JSON.stringify(data), {\n headers: { 'Cache-Control': `max-age=${ttl}` },\n })\n ),\n ]);\n\n memoryCache.set(key, data, ttl);\n\n return data;\n}\n\n// ============================================\n// STREAMING UTILITIES\n// ============================================\n\nfunction streamJSON\u003cT>(\n items: AsyncIterable\u003cT>,\n transform?: (item: T) => unknown\n): ReadableStream {\n let first = true;\n\n return new ReadableStream({\n async start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode('['));\n\n for await (const item of items) {\n if (!first) {\n controller.enqueue(encoder.encode(','));\n }\n first = false;\n\n const data = transform ? transform(item) : item;\n controller.enqueue(encoder.encode(JSON.stringify(data)));\n }\n\n controller.enqueue(encoder.encode(']'));\n controller.close();\n },\n });\n}\n\n// ============================================\n// OPTIMIZED DATABASE QUERIES\n// ============================================\n\nasync function* queryBatched\u003cT>(\n db: D1Database,\n sql: string,\n batchSize = 100\n): AsyncGenerator\u003cT> {\n let offset = 0;\n\n while (true) {\n const { results } = await db\n .prepare(`${sql} LIMIT ${batchSize} OFFSET ${offset}`)\n .all\u003cT>();\n\n if (results.length === 0) break;\n\n for (const row of results) {\n yield row;\n }\n\n if (results.length \u003c batchSize) break;\n offset += batchSize;\n }\n}\n\n// ============================================\n// APP SETUP\n// ============================================\n\nconst app = new Hono\u003c{ Bindings: Env }>();\n\n// Middleware\napp.use('*', cors());\napp.use('*', compress());\n\n// Performance tracking middleware\napp.use('*', async (c, next) => {\n const start = performance.now();\n const isCold = trackColdStart();\n\n await next();\n\n const duration = performance.now() - start;\n\n // Add timing headers\n c.res.headers.set('X-Response-Time', `${duration.toFixed(2)}ms`);\n c.res.headers.set('X-Cold-Start', isCold.toString());\n c.res.headers.set('X-Request-Count', requestCount.toString());\n\n // Log slow requests\n if (duration > 50) {\n console.warn('Slow request:', {\n path: c.req.path,\n duration: `${duration.toFixed(2)}ms`,\n cold: isCold,\n });\n }\n});\n\n// ============================================\n// ROUTES\n// ============================================\n\n// Health check (minimal processing)\napp.get('/health', (c) => {\n return c.json({\n status: 'healthy',\n cold: !isWarm,\n requests: requestCount,\n });\n});\n\n// Cached data endpoint\napp.get('/api/data/:key', async (c) => {\n const key = c.req.param('key');\n\n const data = await getCached(\n `data:${key}`,\n c.env.KV,\n async () => {\n // Expensive fetch - only runs on cache miss\n const result = await c.env.DB\n .prepare('SELECT * FROM data WHERE key = ?')\n .bind(key)\n .first();\n return result;\n },\n 300 // 5 min TTL\n );\n\n if (!data) {\n return c.json({ error: 'Not found' }, 404);\n }\n\n return c.json(data);\n});\n\n// Streaming large dataset\napp.get('/api/items', async (c) => {\n const items = queryBatched\u003c{ id: string; name: string }>(\n c.env.DB,\n 'SELECT id, name FROM items ORDER BY created_at DESC'\n );\n\n return new Response(streamJSON(items), {\n headers: {\n 'Content-Type': 'application/json',\n 'Transfer-Encoding': 'chunked',\n },\n });\n});\n\n// Batch operations\napp.post('/api/batch', async (c) => {\n const { operations } = await c.req.json\u003c{\n operations: Array\u003c{ type: string; data: unknown }>;\n }>();\n\n // Process in parallel batches\n const batchSize = 10;\n const results: unknown[] = [];\n\n for (let i = 0; i \u003c operations.length; i += batchSize) {\n const batch = operations.slice(i, i + batchSize);\n const batchResults = await Promise.all(\n batch.map((op) => processOperation(c.env, op))\n );\n results.push(...batchResults);\n }\n\n return c.json({ results });\n});\n\nasync function processOperation(\n env: Env,\n op: { type: string; data: unknown }\n): Promise\u003cunknown> {\n // Implementation\n return { success: true, type: op.type };\n}\n\n// ============================================\n// ERROR HANDLING\n// ============================================\n\napp.notFound((c) => {\n return c.json({ error: 'Not Found' }, 404);\n});\n\napp.onError((err, c) => {\n console.error('Error:', {\n message: err.message,\n stack: err.stack,\n path: c.req.path,\n });\n\n return c.json(\n {\n error: 'Internal Server Error',\n message: c.env.ENVIRONMENT === 'development' ? err.message : undefined,\n },\n 500\n );\n});\n\n// ============================================\n// EXPORT\n// ============================================\n\nexport default {\n fetch: app.fetch,\n\n // Optional: Scheduled handler for cache warming\n async scheduled(\n event: ScheduledEvent,\n env: Env,\n ctx: ExecutionContext\n ): Promise\u003cvoid> {\n console.log('Scheduled task running:', event.cron);\n\n // Pre-warm popular caches\n ctx.waitUntil(prewarmCaches(env));\n },\n};\n\nasync function prewarmCaches(env: Env): Promise\u003cvoid> {\n const popularKeys = ['config', 'featured', 'categories'];\n\n await Promise.all(\n popularKeys.map(async (key) => {\n await getCached(\n `data:${key}`,\n env.KV,\n async () => {\n return env.DB\n .prepare('SELECT * FROM data WHERE key = ?')\n .bind(key)\n .first();\n },\n 3600\n );\n })\n );\n}\n","content_type":"text/typescript; charset=utf-8","language":"typescript","size":9835,"content_sha256":"d575dd893ddbae8fdfe9c9388827e8e39b7565741cf466598619f6c6a4d04394"},{"filename":"templates/performance-middleware.ts","content":"/**\n * Performance Monitoring Middleware for Cloudflare Workers\n *\n * Features:\n * - Request timing and profiling\n * - Server-Timing headers\n * - Cold start detection\n * - Slow request logging\n * - Memory monitoring\n * - Performance analytics\n *\n * Usage:\n * 1. Import middleware functions\n * 2. Wrap handlers with performance tracking\n * 3. Monitor via headers or analytics\n */\n\n// ============================================\n// TYPES\n// ============================================\n\ninterface Env {\n ENVIRONMENT: string;\n ANALYTICS?: AnalyticsEngineDataset;\n}\n\ninterface TimingEntry {\n name: string;\n duration: number;\n description?: string;\n}\n\ninterface PerformanceContext {\n requestId: string;\n startTime: number;\n timings: TimingEntry[];\n isCold: boolean;\n marks: Map\u003cstring, number>;\n}\n\ninterface PerformanceMetrics {\n requestId: string;\n totalDuration: number;\n isCold: boolean;\n timings: Record\u003cstring, number>;\n url: string;\n method: string;\n status: number;\n colo?: string;\n}\n\ntype Handler = (\n request: Request,\n env: Env,\n ctx: ExecutionContext\n) => Promise\u003cResponse>;\n\n// ============================================\n// COLD START DETECTION\n// ============================================\n\nlet isWarm = false;\nlet isolateStartTime: number | undefined;\n\nfunction detectColdStart(): boolean {\n if (!isWarm) {\n isWarm = true;\n isolateStartTime = Date.now();\n return true;\n }\n return false;\n}\n\n// ============================================\n// PERFORMANCE CONTEXT\n// ============================================\n\nfunction createPerformanceContext(): PerformanceContext {\n return {\n requestId: crypto.randomUUID(),\n startTime: performance.now(),\n timings: [],\n isCold: detectColdStart(),\n marks: new Map(),\n };\n}\n\n// ============================================\n// TIMING HELPERS\n// ============================================\n\nfunction mark(ctx: PerformanceContext, name: string): void {\n ctx.marks.set(name, performance.now());\n}\n\nfunction measure(\n ctx: PerformanceContext,\n name: string,\n startMark: string,\n description?: string\n): number {\n const start = ctx.marks.get(startMark);\n if (!start) {\n console.warn(`Mark \"${startMark}\" not found`);\n return 0;\n }\n\n const duration = performance.now() - start;\n ctx.timings.push({ name, duration, description });\n return duration;\n}\n\nasync function timeAsync\u003cT>(\n ctx: PerformanceContext,\n name: string,\n fn: () => Promise\u003cT>,\n description?: string\n): Promise\u003cT> {\n const start = performance.now();\n try {\n return await fn();\n } finally {\n const duration = performance.now() - start;\n ctx.timings.push({ name, duration, description });\n }\n}\n\nfunction timeSync\u003cT>(\n ctx: PerformanceContext,\n name: string,\n fn: () => T,\n description?: string\n): T {\n const start = performance.now();\n try {\n return fn();\n } finally {\n const duration = performance.now() - start;\n ctx.timings.push({ name, duration, description });\n }\n}\n\n// ============================================\n// SERVER-TIMING HEADER\n// ============================================\n\nfunction buildServerTimingHeader(ctx: PerformanceContext): string {\n const entries: string[] = [];\n\n // Add total time\n entries.push(`total;dur=${(performance.now() - ctx.startTime).toFixed(2)}`);\n\n // Add cold start indicator\n if (ctx.isCold) {\n entries.push('cold;desc=\"Cold Start\"');\n }\n\n // Add individual timings\n for (const timing of ctx.timings) {\n let entry = `${timing.name};dur=${timing.duration.toFixed(2)}`;\n if (timing.description) {\n entry += `;desc=\"${timing.description}\"`;\n }\n entries.push(entry);\n }\n\n return entries.join(', ');\n}\n\n// ============================================\n// PERFORMANCE MIDDLEWARE\n// ============================================\n\nexport function withPerformanceTracking(handler: Handler): Handler {\n return async (request, env, ctx) => {\n const perfCtx = createPerformanceContext();\n\n mark(perfCtx, 'start');\n\n try {\n const response = await timeAsync(\n perfCtx,\n 'handler',\n () => handler(request, env, ctx),\n 'Request handler'\n );\n\n // Add performance headers\n const newResponse = new Response(response.body, response);\n\n newResponse.headers.set('X-Request-Id', perfCtx.requestId);\n newResponse.headers.set(\n 'X-Response-Time',\n `${(performance.now() - perfCtx.startTime).toFixed(2)}ms`\n );\n newResponse.headers.set('Server-Timing', buildServerTimingHeader(perfCtx));\n\n if (perfCtx.isCold) {\n newResponse.headers.set('X-Cold-Start', 'true');\n }\n\n // Log metrics\n logMetrics(perfCtx, request, newResponse, env);\n\n return newResponse;\n } catch (error) {\n // Log error with timing\n console.error('Request failed:', {\n requestId: perfCtx.requestId,\n duration: performance.now() - perfCtx.startTime,\n error: (error as Error).message,\n });\n throw error;\n }\n };\n}\n\n// ============================================\n// SLOW REQUEST DETECTION\n// ============================================\n\nconst SLOW_THRESHOLD_MS = 100;\n\nexport function withSlowRequestLogging(\n handler: Handler,\n threshold = SLOW_THRESHOLD_MS\n): Handler {\n return async (request, env, ctx) => {\n const start = performance.now();\n\n try {\n return await handler(request, env, ctx);\n } finally {\n const duration = performance.now() - start;\n\n if (duration > threshold) {\n console.warn('Slow request detected:', {\n url: request.url,\n method: request.method,\n duration: `${duration.toFixed(2)}ms`,\n threshold: `${threshold}ms`,\n cf: request.cf,\n });\n }\n }\n };\n}\n\n// ============================================\n// METRICS LOGGING\n// ============================================\n\nfunction logMetrics(\n ctx: PerformanceContext,\n request: Request,\n response: Response,\n env: Env\n): void {\n const metrics: PerformanceMetrics = {\n requestId: ctx.requestId,\n totalDuration: performance.now() - ctx.startTime,\n isCold: ctx.isCold,\n timings: Object.fromEntries(ctx.timings.map((t) => [t.name, t.duration])),\n url: new URL(request.url).pathname,\n method: request.method,\n status: response.status,\n colo: (request.cf as { colo?: string })?.colo,\n };\n\n // Console logging (appears in wrangler tail)\n if (env.ENVIRONMENT === 'development' || ctx.isCold || metrics.totalDuration > 50) {\n console.log('Performance metrics:', JSON.stringify(metrics));\n }\n\n // Analytics Engine (if available)\n if (env.ANALYTICS) {\n env.ANALYTICS.writeDataPoint({\n blobs: [\n metrics.url,\n metrics.method,\n ctx.isCold ? 'cold' : 'warm',\n metrics.colo || 'unknown',\n ],\n doubles: [metrics.totalDuration, metrics.status],\n indexes: [metrics.requestId],\n });\n }\n}\n\n// ============================================\n// PROFILER CLASS\n// ============================================\n\nexport class RequestProfiler {\n private ctx: PerformanceContext;\n\n constructor() {\n this.ctx = createPerformanceContext();\n }\n\n mark(name: string): void {\n mark(this.ctx, name);\n }\n\n measure(name: string, startMark: string, description?: string): number {\n return measure(this.ctx, name, startMark, description);\n }\n\n async time\u003cT>(name: string, fn: () => Promise\u003cT>, description?: string): Promise\u003cT> {\n return timeAsync(this.ctx, name, fn, description);\n }\n\n timeSync\u003cT>(name: string, fn: () => T, description?: string): T {\n return timeSync(this.ctx, name, fn, description);\n }\n\n getTimings(): TimingEntry[] {\n return [...this.ctx.timings];\n }\n\n getTotalDuration(): number {\n return performance.now() - this.ctx.startTime;\n }\n\n isColdStart(): boolean {\n return this.ctx.isCold;\n }\n\n getRequestId(): string {\n return this.ctx.requestId;\n }\n\n getServerTimingHeader(): string {\n return buildServerTimingHeader(this.ctx);\n }\n\n getSummary(): Record\u003cstring, unknown> {\n return {\n requestId: this.ctx.requestId,\n totalDuration: this.getTotalDuration(),\n isCold: this.ctx.isCold,\n timings: Object.fromEntries(this.ctx.timings.map((t) => [t.name, t.duration])),\n };\n }\n}\n\n// ============================================\n// CPU GUARD\n// ============================================\n\nconst CPU_LIMIT_MS = 30; // Paid plan limit\n\nexport function withCPUGuard(handler: Handler, limit = CPU_LIMIT_MS): Handler {\n return async (request, env, ctx) => {\n const start = performance.now();\n let checkCount = 0;\n\n // Periodic CPU check\n const checkCPU = () => {\n checkCount++;\n const elapsed = performance.now() - start;\n if (elapsed > limit * 0.8) {\n console.warn('Approaching CPU limit:', {\n elapsed: `${elapsed.toFixed(2)}ms`,\n limit: `${limit}ms`,\n checks: checkCount,\n });\n }\n };\n\n // Check every 100 iterations or time-based\n const interval = setInterval(checkCPU, 10);\n\n try {\n return await handler(request, env, ctx);\n } finally {\n clearInterval(interval);\n const total = performance.now() - start;\n if (total > limit) {\n console.error('CPU limit exceeded:', {\n duration: `${total.toFixed(2)}ms`,\n limit: `${limit}ms`,\n });\n }\n }\n };\n}\n\n// ============================================\n// COMBINED MIDDLEWARE\n// ============================================\n\nexport function withFullPerformanceMonitoring(handler: Handler): Handler {\n // Stack middlewares\n return withCPUGuard(withSlowRequestLogging(withPerformanceTracking(handler)));\n}\n\n// ============================================\n// EXAMPLE USAGE\n// ============================================\n\n/*\nimport {\n withFullPerformanceMonitoring,\n RequestProfiler,\n} from './performance-middleware';\n\n// Option 1: Use middleware wrapper\nexport default {\n fetch: withFullPerformanceMonitoring(async (request, env, ctx) => {\n // Your handler code\n return new Response('OK');\n }),\n};\n\n// Option 2: Use profiler for granular timing\nexport default {\n async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise\u003cResponse> {\n const profiler = new RequestProfiler();\n\n profiler.mark('start');\n\n const user = await profiler.time('fetchUser', async () => {\n return await db.getUser(userId);\n });\n\n profiler.mark('postFetch');\n\n const data = profiler.timeSync('transform', () => {\n return transformData(user);\n });\n\n profiler.measure('afterTransform', 'postFetch');\n\n const response = Response.json(data);\n response.headers.set('Server-Timing', profiler.getServerTimingHeader());\n\n return response;\n },\n};\n*/\n","content_type":"text/typescript; charset=utf-8","language":"typescript","size":10767,"content_sha256":"54a138f1e234e6716c4f6793aa2367715a73225e3fcc0b977fb8840db3e23c6d"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Cloudflare Workers Performance Optimization","type":"text"}]},{"type":"paragraph","content":[{"text":"Techniques for maximizing Worker performance and minimizing latency.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Wins","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// 1. Avoid unnecessary cloning\n// ❌ Bad: Clones entire request\nconst body = await request.clone().json();\n\n// ✅ Good: Parse directly when not re-using body\nconst body = await request.json();\n\n// 2. Use streaming instead of buffering\n// ❌ Bad: Buffers entire response\nconst text = await response.text();\nreturn new Response(transform(text));\n\n// ✅ Good: Stream transformation\nreturn new Response(response.body.pipeThrough(new TransformStream({\n transform(chunk, controller) {\n controller.enqueue(process(chunk));\n }\n})));\n\n// 3. Cache expensive operations\nconst cache = caches.default;\nconst cached = await cache.match(request);\nif (cached) return cached;","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Critical Rules","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Stay under CPU limits","type":"text","marks":[{"type":"strong"}]},{"text":" - 10ms (free), 30ms (paid), 50ms (unbound)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Minimize cold starts","type":"text","marks":[{"type":"strong"}]},{"text":" - Keep bundles \u003c 1MB, avoid dynamic imports","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use Cache API","type":"text","marks":[{"type":"strong"}]},{"text":" - Cache responses at the edge","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Stream large payloads","type":"text","marks":[{"type":"strong"}]},{"text":" - Don't buffer entire responses","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Batch operations","type":"text","marks":[{"type":"strong"}]},{"text":" - Combine multiple KV/D1 calls","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Top 10 Performance Errors","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Symptom","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CPU limit exceeded","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Worker terminated","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Optimize hot paths, use streaming","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cold start latency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"First request slow","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reduce bundle size, avoid top-level await","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory pressure","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slow GC, timeouts","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stream data, avoid large arrays","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"KV latency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slow reads","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use Cache API, batch reads","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"D1 slow queries","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"High latency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add indexes, optimize SQL","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Large bundles","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slow cold starts","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tree-shake, code split","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Blocking operations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Request timeouts","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use Promise.all, streaming","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unnecessary cloning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory spike","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Only clone when needed","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Missing cache","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repeated computation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Implement caching layer","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sync operations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CPU spikes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use async alternatives","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"CPU Optimization","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Profile Hot Paths","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"async function profiledHandler(request: Request): Promise\u003cResponse> {\n const timing: Record\u003cstring, number> = {};\n\n const time = async \u003cT>(name: string, fn: () => Promise\u003cT>): Promise\u003cT> => {\n const start = Date.now();\n const result = await fn();\n timing[name] = Date.now() - start;\n return result;\n };\n\n const data = await time('fetch', () => fetchData());\n const processed = await time('process', () => processData(data));\n const response = await time('serialize', () => serialize(processed));\n\n console.log('Timing:', timing);\n return new Response(response);\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Optimize JSON Operations","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// For large JSON, use streaming parser\nimport { JSONParser } from '@streamparser/json';\n\nasync function parseStreamingJSON(stream: ReadableStream): Promise\u003cunknown[]> {\n const parser = new JSONParser();\n const results: unknown[] = [];\n\n parser.onValue = (value) => results.push(value);\n\n for await (const chunk of stream) {\n parser.write(chunk);\n }\n\n return results;\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Memory Optimization","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Avoid Large Arrays","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// ❌ Bad: Loads all into memory\nconst items = await db.prepare('SELECT * FROM items').all();\nconst processed = items.results.map(transform);\n\n// ✅ Good: Process in batches\nasync function* batchProcess(db: D1Database, batchSize = 100) {\n let offset = 0;\n while (true) {\n const { results } = await db\n .prepare('SELECT * FROM items LIMIT ? OFFSET ?')\n .bind(batchSize, offset)\n .all();\n\n if (results.length === 0) break;\n\n for (const item of results) {\n yield transform(item);\n }\n offset += batchSize;\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Caching Strategies","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Multi-Layer Cache","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"interface CacheLayer {\n get(key: string): Promise\u003cunknown | null>;\n set(key: string, value: unknown, ttl?: number): Promise\u003cvoid>;\n}\n\n// Layer 1: In-memory (request-scoped)\nconst memoryCache = new Map\u003cstring, unknown>();\n\n// Layer 2: Cache API (edge-local)\nconst edgeCache: CacheLayer = {\n async get(key) {\n const response = await caches.default.match(new Request(`https://cache/${key}`));\n return response ? response.json() : null;\n },\n async set(key, value, ttl = 60) {\n await caches.default.put(\n new Request(`https://cache/${key}`),\n new Response(JSON.stringify(value), {\n headers: { 'Cache-Control': `max-age=${ttl}` }\n })\n );\n }\n};\n\n// Layer 3: KV (global)\n// Use env.KV.get/put","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Bundle Optimization","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// 1. Tree-shake imports\n// ❌ Bad\nimport * as lodash from 'lodash';\n\n// ✅ Good\nimport { debounce } from 'lodash-es';\n\n// 2. Lazy load heavy dependencies\nlet heavyLib: typeof import('heavy-lib') | undefined;\n\nasync function getHeavyLib() {\n if (!heavyLib) {\n heavyLib = await import('heavy-lib');\n }\n return heavyLib;\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Load References","type":"text"}]},{"type":"paragraph","content":[{"text":"Load specific references based on the task:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Optimizing CPU usage?","type":"text","marks":[{"type":"strong"}]},{"text":" → Load ","type":"text"},{"text":"references/cpu-optimization.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory issues?","type":"text","marks":[{"type":"strong"}]},{"text":" → Load ","type":"text"},{"text":"references/memory-optimization.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implementing caching?","type":"text","marks":[{"type":"strong"}]},{"text":" → Load ","type":"text"},{"text":"references/caching-strategies.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reducing bundle size?","type":"text","marks":[{"type":"strong"}]},{"text":" → Load ","type":"text"},{"text":"references/bundle-optimization.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cold start problems?","type":"text","marks":[{"type":"strong"}]},{"text":" → Load ","type":"text"},{"text":"references/cold-starts.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Templates","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Template","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use When","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"templates/performance-middleware.ts","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Performance monitoring","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Adding timing/profiling","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"templates/caching-layer.ts","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multi-layer caching","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Implementing cache","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"templates/optimized-worker.ts","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Performance patterns","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Starting optimized worker","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Scripts","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Script","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/benchmark.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Load testing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./benchmark.sh \u003curl>","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/profile-worker.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CPU profiling","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./profile-worker.sh","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Resources","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Performance: https://developers.cloudflare.com/workers/platform/performance/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Limits: https://developers.cloudflare.com/workers/platform/limits/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Caching: https://developers.cloudflare.com/workers/runtime-apis/cache/","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"cloudflare-workers-performance","author":"@skillopedia","source":{"stars":162,"repo_name":"claude-skills","origin_url":"https://github.com/secondsky/claude-skills/blob/HEAD/plugins/cloudflare-workers/skills/cloudflare-workers-performance/SKILL.md","repo_owner":"secondsky","body_sha256":"712088af2df70d255c6590621513d3416ba2b0dc7070ec4942e73f5088a009a0","cluster_key":"0ba2463e17b1b32d846587d0354d8f0470aab1a35aa0aac763c23a819fbca510","clean_bundle":{"format":"clean-skill-bundle-v1","source":"secondsky/claude-skills/plugins/cloudflare-workers/skills/cloudflare-workers-performance/SKILL.md","attachments":[{"id":"b2aac8ef-8ef5-5b45-bbd6-1558c5479261","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b2aac8ef-8ef5-5b45-bbd6-1558c5479261/attachment.md","path":"references/bundle-optimization.md","size":8719,"sha256":"e8d6be5b31e0e925e02e522919b7b982fb4cffdc2a60fb576d2c8de7d8982559","contentType":"text/markdown; charset=utf-8"},{"id":"542cb62a-8e1b-52c2-b81c-5c8f6cf1b69d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/542cb62a-8e1b-52c2-b81c-5c8f6cf1b69d/attachment.md","path":"references/caching-strategies.md","size":11208,"sha256":"6f02e47ec27ca78e3e41910f2124b015c4a4ee40f61725380e7a6ab8d3fa5f6d","contentType":"text/markdown; charset=utf-8"},{"id":"a1be0357-cbb7-5d79-8c99-0f713126c493","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a1be0357-cbb7-5d79-8c99-0f713126c493/attachment.md","path":"references/cold-starts.md","size":9454,"sha256":"c9d230f5b51e4bcfe3d5f7f1de3b754b5c71bd081cf7948dacd15dd1184480da","contentType":"text/markdown; charset=utf-8"},{"id":"82132e29-dcec-5acc-8965-ad13ce2c2be6","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/82132e29-dcec-5acc-8965-ad13ce2c2be6/attachment.md","path":"references/cpu-optimization.md","size":9686,"sha256":"bbd09f87e4e726ffb97596de0818bd99bab21b45fe7f3278db57cc0c1e875b8c","contentType":"text/markdown; charset=utf-8"},{"id":"46aef743-b0a3-5064-bf2a-ca24b8f72b0a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/46aef743-b0a3-5064-bf2a-ca24b8f72b0a/attachment.md","path":"references/memory-optimization.md","size":9976,"sha256":"66421c661a08d0989b375acb423185743bb257f9cd1fe91a5b146e316c0a47da","contentType":"text/markdown; charset=utf-8"},{"id":"4050c067-c75c-572f-8c26-3d58fd611caf","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4050c067-c75c-572f-8c26-3d58fd611caf/attachment.sh","path":"scripts/benchmark.sh","size":11985,"sha256":"6509a9455ba8a1c311c6a0fc35aaf8301603fcc95f6109552be0e4262d7375b3","contentType":"application/x-sh; charset=utf-8"},{"id":"ad3d03e5-0050-5750-9dc2-1679c40d10e1","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ad3d03e5-0050-5750-9dc2-1679c40d10e1/attachment.sh","path":"scripts/profile-worker.sh","size":12407,"sha256":"68ee20a09cde9124d3aa7d2577999cf64e01148f5e21e0c8cbc7dad9bc01cc9e","contentType":"application/x-sh; charset=utf-8"},{"id":"5689a19a-f68c-5c30-8508-8a850d3b204a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5689a19a-f68c-5c30-8508-8a850d3b204a/attachment.ts","path":"templates/caching-layer.ts","size":13724,"sha256":"7fa4f696580dca50ba6d6f01a242caed96cad6e689c055e304862841a0dda242","contentType":"text/typescript; charset=utf-8"},{"id":"c8316a33-df2e-5ffe-b3bf-b3e0e295fb28","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c8316a33-df2e-5ffe-b3bf-b3e0e295fb28/attachment.ts","path":"templates/optimized-worker.ts","size":9835,"sha256":"d575dd893ddbae8fdfe9c9388827e8e39b7565741cf466598619f6c6a4d04394","contentType":"text/typescript; charset=utf-8"},{"id":"5656e6b7-9eb0-5c06-b2dd-c74c416957ee","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5656e6b7-9eb0-5c06-b2dd-c74c416957ee/attachment.ts","path":"templates/performance-middleware.ts","size":10767,"sha256":"54a138f1e234e6716c4f6793aa2367715a73225e3fcc0b977fb8840db3e23c6d","contentType":"text/typescript; charset=utf-8"}],"bundle_sha256":"0da83439cab92d5effc1bb9a1dacfbdf136644446d5c0c1bdb9d1fbeed99a84c","attachment_count":10,"text_attachments":10,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"plugins/cloudflare-workers/skills/cloudflare-workers-performance/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"devops-infrastructure","category_label":"DevOps"},"exact_dupes_collapsed_into_this":0},"license":"MIT","version":"v1","category":"devops-infrastructure","import_tag":"clean-skills-v1","description":"Cloudflare Workers performance optimization with CPU, memory, caching, bundle size. Use for slow workers, high latency, cold starts, or encountering CPU limits, memory issues, timeout errors."}},"renderedAt":1782979720314}

Cloudflare Workers Performance Optimization Techniques for maximizing Worker performance and minimizing latency. Quick Wins Critical Rules 1. Stay under CPU limits - 10ms (free), 30ms (paid), 50ms (unbound) 2. Minimize cold starts - Keep bundles < 1MB, avoid dynamic imports 3. Use Cache API - Cache responses at the edge 4. Stream large payloads - Don't buffer entire responses 5. Batch operations - Combine multiple KV/D1 calls Top 10 Performance Errors | Error | Symptom | Fix | |-------|---------|-----| | CPU limit exceeded | Worker terminated | Optimize hot paths, use streaming | | Cold start…