Files
2026-01-30 03:04:10 +00:00

2.3 KiB

Analytics Engine Patterns

Use Cases

Use Case Key Metrics Index On
API Metering requests, bytes, compute_units api_key
Feature Usage feature, action, duration user_id
Error Tracking error_type, endpoint, count customer_id
Performance latency_ms, cache_status endpoint
A/B Testing variant, conversions user_id

API Metering (Billing)

env.ANALYTICS.writeDataPoint({
  blobs: [pathname, method, status, tier],
  doubles: [1, computeUnits, bytes, latencyMs],
  indexes: [apiKey]
});

// Query: Monthly usage by customer
// SELECT index1 AS api_key, SUM(double2) AS compute_units
// FROM usage WHERE timestamp >= DATE_TRUNC('month', NOW()) GROUP BY index1

Error Tracking

env.ANALYTICS.writeDataPoint({
  blobs: [endpoint, method, errorName, errorMessage.slice(0, 1000)],
  doubles: [1, timeToErrorMs],
  indexes: [customerId]
});

Performance Monitoring

env.ANALYTICS.writeDataPoint({
  blobs: [pathname, method, cacheStatus, status],
  doubles: [latencyMs, 1],
  indexes: [userId]
});

// Query: P95 latency by endpoint
// SELECT blob1, quantile(0.95)(double1) AS p95_ms FROM perf GROUP BY blob1

Anti-Patterns

Wrong Correct
await writeDataPoint() writeDataPoint() (fire-and-forget)
indexes: [method] (low cardinality) blobs: [method], indexes: [userId]
blobs: [JSON.stringify(obj)] Store ID in blob, full object in D1/KV
Write every request at 10M/min Pre-aggregate per second
Query from Worker Query from external service/API

Best Practices

  1. Design schema upfront - Document blob/double/index assignments
  2. Always include count metric - doubles: [latency, 1] for AVG calculations
  3. Use enums for blobs - Consistent values like Status.SUCCESS
  4. Handle sampling - Use ratios (avg_latency = SUM(latency)/SUM(count))
  5. Test queries early - Validate schema before heavy writes

Schema Template

/**
 * Dataset: my_metrics
 * 
 * Blobs:
 *   blob1: endpoint, blob2: method, blob3: status
 * 
 * Doubles:
 *   double1: latency_ms, double2: count (always 1)
 * 
 * Indexes:
 *   index1: customer_id (high cardinality)
 */