Codex Cloudflarensis · Volumen III · Folio I

De
Operationibus

Defectiones · Pretia · Observatio · Migrationes

Saber qué primitivas existen es la teoría. Saber cómo fallan, cuánto cuestan, cómo observarlas, cómo migrar hacia ellas es la práctica. Este volumen recoge la operación real del stack — los números, los modos de falla, los playbooks que sólo se aprenden en producción.

I
Pars Prima

Modi Defectionis

Cada primitiva tiene maneras específicas de fallar. Conocerlas no es paranoia — es saber dónde poner monitores, retries, fallbacks.

W
— Operarius Defectus —
Worker
CPU Limit
10ms free / 30s paid. Loop infinito o regex catastrófico → Worker exceeded CPU time. Request muere, no hay retry automático.
Wall Time
30s default. Llamada externa lenta + sin timeout = exceedes wall. Diferente de CPU — wall incluye I/O wait.
Memory OOM
128MB limit. Cargar JSON gigante o buffer enorme → kill. Streaming es la solución.
Subrequest Limit
50 free / 1000 paid subrequests por invocation. Loops haciendo fetches → corta.
Cold Start
~5ms típico, hasta 50ms si import grande. NO es problema usual pero impacta p99 en regiones nuevas.
K
— Bibliothecarius Defectus —
KV
Write Throttle
1 write/sec/key. Más rápido que esto = HTTP 429. Distribuye writes entre keys o usa DO.
Propagation Lag
~60s para propagar globalmente. Read-after-write en otro PoP puede retornar valor viejo. NO uses para pricing/auth.
Read Inconsistency
Dos PoPs pueden retornar valores distintos durante propagación. Para idempotencia, lee siempre desde mismo PoP (sticky).
Value Size
25MB max value, 512 bytes max key. Excederlo = error. Para blobs grandes usa R2.
List Pagination
List operations paginated, complete consistency NO garantizada durante list. Mid-list-add puede no aparecer.
D
— Tabularium Defectus —
D1
Primary Saturation
~1000 writes/sec límite primary. Excederlo = queue + timeouts. Cache-aside KV protege.
Replica Staleness
Read replicas pueden estar ~10s atrás del primary. Read-after-write inmediato puede leer datos viejos. read_replication: { mode: 'auto' } mitiga.
Query Timeout
30s default. Joins complejos sin index = timeout. Schema y EXPLAIN ayudan.
Database Size
10GB hard limit por DB. Multi-tenant grande requiere DB-per-tenant o particiones manuales.
Migration Locks
ALTER TABLE bloquea writes durante el cambio. En producción, plan rolling migrations con dual-write.
O
— Custos Singularis Defectus —
Durable Object
Migration Window
DO migra entre PoPs (load balancing). Durante la migración, requests pueden ver latencia elevada o errores transient. Retry handler esencial.
Hibernation Wake-up
DO idle hiberna. Primera request post-hibernation = ~10-50ms wake-up latency. Subsecuentes son hot.
Storage Limits
10GB SQLite por DO. Excederlo requiere shard manual.
Single-Writer Bottleneck
Si TODA tu carga pega 1 DO = bottleneck global. idFromName(...) debe ser por entidad lógica, no global.
WebSocket Disconnects
Client networks tiran conexiones. Reconnect logic + state replay obligatorios. Hibernation no destruye state pero conexiones sí.
Q
— Cursus Publicus Defectus —
Queue
At-Least-Once
Cada mensaje puede entregarse 1+ veces. Sin idempotency en consumer = side effects duplicados.
Out-of-Order
Sin garantía de orden estricto. Si tu lógica depende de orden, usa DO + Queue (DO ordena, Queue distribuye).
Visibility Timeout
Consumer tiene 30s default para procesar antes de redelivery. Trabajos lentos = mensajes duplicados visibles.
DLQ Required
Tras N reintentos sin DLQ configurado, mensajes se pierden silenciosamente. SIEMPRE configura DLQ.
Backpressure
Producer puede llenar queue más rápido que consumer drena. Monitor lag, scale consumers o slow producer.
F
— Ordo Operum Defectus —
Workflow
Replay Non-Determinism
Si un step usa Date.now(), Math.random(), o lectura externa no-cacheada → replay genera valores distintos → state divergente. Captura side effects en steps explícitos.
Step Timeout
Cada step tiene timeout. Long-running work debe partirse en steps más pequeños o usar step.sleep.
Compensation Bugs
Saga necesita compensación correcta. Bug en refund() → estado inconsistente irrecuperable. Test compensations exhaustively.
Schema Evolution
Workflow en vuelo cuando cambias código → replay con código nuevo puede romper. Versioning de workflows obligatorio.
H
— Aquaeductus Defectus —
Hyperdrive
Pool Exhaustion
Si tu DB origen tiene max_connections=100 y traffic pico requiere más, queries esperan o fallan. Configura pool size acorde.
Query Cache Staleness
Hyperdrive cachea SELECT queries idénticas. Updates en DB pueden no reflejarse hasta TTL expire. Disable cache en queries críticas.
Origin Down
Hyperdrive no es replicación — si Postgres origen cae, queries fallan. No es failover automático.
Region Latency
Worker en Europa + Postgres en us-east = pool warm pero query cruza océano. Co-locate origen al traffic dominante.
R
— Thesaurus Defectus —
R2
Eventual Listing
PUT objeto + LIST inmediato puede no incluirlo. List es eventually consistent. Object reads son strong.
Multipart Required
Objects > 5GB requieren multipart upload. Streaming upload simple falla.
Class A Cost Trap
Operaciones de escritura (Class A) cuestan ~10× operaciones lectura (Class B). Bulk uploads con muchos archivos pequeños = factura inesperada.
No Server-Side Compute
A diferencia de S3 (Lambda triggers), R2 no tiene triggers nativos. Procesamiento async via Worker + Queue.
II
Pars Secunda

Aestimatio Pretii

Precios oficiales por primitiva, más tres ejemplos calculados en escenarios reales. Saber el costo de un diseño antes de construirlo separa al arquitecto del entusiasta.

Pricing Compute · Workers
— De Operario —
PlanIncluidoExcedenteNotas
Free100K req/díaNo disponible10ms CPU max
Paid $5/mes10M req/mes$0.30 / M req30s wall, 50ms CPU
Standard CPU30M CPU-ms/mes$0.02 / M CPU-msCobra solo CPU activo, no wall
Pricing State
— De Custodibus Datorum —
PrimitivaLecturaEscrituraStorageNotas
KV$0.50 / M reads$5.00 / M writes$0.50 / GB-moFree: 100K reads, 1K writes/día
D1$0.001 / M rows read$1.00 / M rows written$0.75 / GB-moFree: 5M reads, 100K writes/día
DO$0.15 / M reqincluido$0.20 / GB-mo storage SQLite+ duration $12.50 / M GB-s
R2Class B $0.36 / M opsClass A $4.50 / M ops$0.015 / GB-moEgress GRATIS (vs S3 $0.09/GB)
Vectorize$0.04 / M dim queried$0.04 / M dim storedincluido en queriedFree: 30M queried/mo
Pricing Async + AI
— De Asynchronia et Intellectu —
PrimitivaOperaciónPrecioNotas
QueueOperations (push + pull + delete)$0.40 / M opsFree: 1M ops/mo
WorkflowStep invocations~Workers pricingCobra como Worker req
Workers AIPor modelo, por tokenLlama 3.1 8B: ~$0.10 / M tokens10K neurons free/día
AI GatewayProxy$0 base + storage cacheCache hit ahorra costo LLM externo
Browser RenderPer session$0.09 per browser-hourSessions de pocos segundos típico
I
— Exemplum Primum —
SmartLinks · 1M clicks/día
URL shortener servicio. 1 millón de clicks por día (~12 rps promedio, picos 100 rps). Cache-aside KV con 99% hit ratio. Click counter en DO con flush cada 30s. Analytics async vía Queue.
Worker requests · 30M/mes
$5 + (20M × $0.30/M) = $11
KV reads · 30M/mes (99% hit)
30M × $0.50/M = $15
D1 reads · 300K/mes (1% miss)
$0 (free tier)
DO requests · 30M flushes/mes
30M × $0.15/M = $4.50
Queue ops · 60M/mes (push+pull)
60M × $0.40/M = $24
D1 writes events · 30M/mes
30M × $1/M = $30
Total Mensual
≈ $85 USD
II
— Exemplum Secundum —
AI Agent · 10K conversaciones/mes
Chatbot RAG. 10K conversaciones × 8 mensajes promedio = 80K LLM calls/mes. Vectorize search. AI Gateway con 40% cache hit. LLM externo (Claude Sonnet vía gateway).
Worker requests · 80K/mes
$5 (dentro de plan)
Vectorize queries · 80K × 1024 dim
82M dim × $0.04/M = $3.28
DO conversation state · 80K req
$0.01
LLM calls · 48K (60% miss)
~$0.025 ea = $1,200
AI Gateway cache savings
−$800 (40% hit)
D1 history · 80K writes
$0 (free)
Total Mensual
≈ $408 USD
III
— Exemplum Tertium —
Multi-Tenant SaaS · 100 tenants activos
SaaS B2B con DO-per-tenant. 100 tenants × 1K req/día/tenant = 3M req/mes total. Dashboard reads cacheados en KV. State crítico en DO. Datos compartidos en D1.
Worker requests · 3M/mes
$5 (within plan)
DO requests · 3M (1 per req)
3M × $0.15/M = $0.45
DO duration · ~100GB-s
100 × $12.50/M GB-s = $1.25
DO storage · 100 × 50MB = 5GB
5GB × $0.20 = $1
KV cache reads · 3M
3M × $0.50/M = $1.50
D1 shared data · <1GB
$0.75
Total Mensual
≈ $10 USD · ~$0.10/tenant
III
Pars Tertia

Observatio

No puedes mejorar lo que no puedes medir. Las herramientas para ver dentro del stack — desde live tail hasta time-series custom.

I
— Visio Vivax —
Tail Workers
Stream live de logs de tu Worker en producción. wrangler tail muestra console.log, errors, requests en tiempo real. Filter por status, sampling rate, predicate.
wrangler tail my-worker --status error --sampling-rate 0.1
Cuándo: debugging activo, repro en producción, demo en vivo.
II
— Annales Externi —
Logpush
Exporta logs a destino externo: R2, S3, Datadog, Sentry, Splunk. Configurable per-worker. Logs incluyen request, response, headers, timing, errors. JSON estructurado.
Setup: dashboard CF → Logs → Logpush → destino + dataset.
Cuándo: retención larga, integración con stack observability existente, compliance.
III
— Annales Tempore —
Analytics Engine
Time-series database serverless propia. Worker escribe events con dimensiones + métricas. Query con SQL como ClickHouse. Casi gratis, alta cardinalidad OK.
env.AE.writeDataPoint({ blobs: ['user-id'], doubles: [latency], indexes: ['endpoint'] })
Cuándo: métricas custom de producto, dashboards internos, alerting basado en business metrics.
IV
— Tracing Distributum —
Workers Tracing
OpenTelemetry support para tracing cross-worker. Visualiza qué Worker llamó a qué DO/KV/D1. Identifica latencia hidden en service bindings.
Sentry, Honeycomb, Datadog APM lo consumen vía OTLP.
Cuándo: arquitecturas con >3 workers vinculados, debugging latencia p99, AI orchestration.
V
— Observatio Cliens —
RUM · Real User Monitoring
Cloudflare Web Analytics o Browser Insights. Mide Core Web Vitals (LCP, INP, CLS) desde browsers reales. Sin cookies, sin tracking pixels.
Setup: 1 line snippet en HTML. Dashboard nativo CF.
Cuándo: optimizar frontend perceived performance, A/B tests, regression detection.
VI
— Pulsus Sanitatis —
Health Checks + Alerting
Cron Triggers + Worker health endpoint. Worker hace checks periódicos, escribe a Analytics Engine, dispara webhook si falla. Builds your own Pingdom.
Combinar con Discord/Slack/Email Workers para alertas.
Cuándo: dependencies externas críticas, SLA monitoring, on-call rotations.
IV
Pars Quarta

Migrationes

Playbooks para mover sistemas existentes hacia Cloudflare. Cada migración tiene su orden óptimo — conocerlo evita meses de fricción.

Express / NodeWorkers
— Migratio Prima · De Servo Tradicional ad Operarium —
I
Audit dependencies. Workers no tiene Node APIs (fs, net, child_process). Identifica usos. Reemplaza con Web Standards (fetch, Web Crypto, Streams).
II
Reemplaza framework. Express no corre en Workers. Migra a Hono (más cercano a Express) o itty-router (minimal). API similar, fetch-based.
III
Estado en sesiones. Express usa req.session in-memory. Workers son stateless. Mueve a JWT en cookie (stateless) o DO con session ID (stateful).
IV
Database connection. Si Postgres, agrega Hyperdrive. Si rediseñas, considera D1. Conexión TCP per-request mata performance — Hyperdrive obligatorio.
V
Background jobs. setInterval no funciona. Reemplaza con Cron Triggers (Worker corre on schedule) o Queues (jobs reactivos).
VI
Static files. Express express.staticWorkers Static Assets (nuevo, integrado) o R2 público con custom domain.
VII
Env vars + secrets. process.envenv.MY_VAR en handler. Secrets via wrangler secret put. Bindings declarados en wrangler.toml.
Warning: Apps con sockets persistentes (chat con Socket.io, etc.) requieren rediseño completo a DO + WebSockets. No es port directo.
PostgresD1
— Migratio Secunda · De Tabulario Maximo ad Tabularium Edicto —
I
Validate fit. D1 tiene 10GB hard limit, ~1K writes/sec, sólo SQLite (subset SQL). Si tu DB >10GB o usa stored procedures complejos, quédate en Postgres + Hyperdrive.
II
Schema translation. PG → SQLite: SERIALINTEGER PRIMARY KEY AUTOINCREMENT, JSONBTEXT con JSON funciones, UUIDTEXT, no arrays.
III
Export data. pg_dump --data-only --inserts. Edita schema diffs. Sqlite3-compatible SQL.
IV
Import a D1. wrangler d1 execute MY_DB --file=dump.sql. Para datasets grandes (>100K rows), batches de 5K-10K.
V
Reescribe queries. ORMs: Drizzle tiene driver D1. Prisma TODAVÍA no oficial (workaround: @prisma/adapter-d1).
VI
Indexes. SQLite indexes son simples — añade EXPLAIN QUERY PLAN para identificar full scans. Compound indexes para queries frecuentes.
VII
Dual-write period. Para cero downtime: Worker escribe a ambos (PG + D1) durante semana, lee de D1. Verifica consistency. Apaga PG.
Warning: Si usas extensions (PostGIS, pgvector, full-text search), D1 NO las soporta. Considera Vectorize (vectors), Workers AI (embeddings), o quédate en PG.
AWS LambdaWorkers
— Migratio Tertia · De Servo Sine Servo ad Operarium —
I
Cold start. Lambda cold start ~100-1000ms. Workers ~5ms. Quitar warmup hacks (Lambda warmer schedule, etc.) — ya no aplican.
II
Event sources. Lambda tiene S3, SQS, EventBridge, etc. Mapea: S3 → R2 events (limitado, vía Worker poll), SQS → Queues, API Gateway → Worker fetch.
III
VPC connectivity. Lambda en VPC accede recursos privados. Workers no tienen VPC — usa Tunnel para exponer servicios on-prem o bring-your-own a CF.
IV
IAM roles. Lambda tiene IAM role. Workers usan secrets + bindings. Migra credentials AWS a secrets si necesitas seguir llamando S3/RDS.
V
Step Functions → Workflows. AWS Step Functions tiene 1:1 con CF Workflows. Reescribe state machine en TS con steps.
VI
DynamoDB → DO o D1. Single-table design DynamoDB → DO con SQLite local. GSIs → indices D1. Streams → Workflow listeners.
Warning: Lambda 15min timeout. Workers 30s wall paid. Long-running jobs: Workflow + sleep, no Worker directo.
V
Pars Quinta

Limites Performantiae

Los números reales que debes memorizar. Cuando alguien te pregunta "¿escala a X?", la respuesta vive en esta tabla.

PrimitivaMétricaValor TípicoNotas
WorkerCold start~5msUp to 50ms con bundle grande
CPU time10ms free / 50ms paid / 30s standardPor request
Wall time30s defaultConfigurable hasta 15min
Memory128MBHard limit
KVRead p50~10msCache hit edge local
Write throughput1 / sec / keyHard rate limit
Propagation~60s globalmenteEventual consistency
D1Query p50~5-30ms (read replica)Primary write ~50-100ms
Write throughput~1000 / sec primarySingle primary
Database size10GB hard limitPer database
Durable ObjectRequest rate~1000 / sec / DOSingle-writer
Wake from hibernation~10-50msPrimera request
SQLite storage10GB / DOHard limit
In-memory state~128MBMismo que Worker
QueueThroughput5K msg/sec / queueSustained
Visibility timeout30s defaultConfigurable
Max retention4 díasAntes de DLQ
Workers AILlama 3.1 8B TTFT~200-500msTime to first token
Llama 3.3 70B TTFT~1-2sSlower model
R2PUT throughput~100MB/s / objectMultipart para >5GB
HyperdrivePool warm latency+0-2ms vs directVs ~50-200ms cold connection
Epilogo
De Disciplina Operationis

El arquitecto que sólo conoce primitivas y patrones es teórico. El arquitecto que opera sin medir es supersticioso. La maestría completa requiere las tres dimensiones: qué existe (Vol I), cómo componer (Vol II), cómo opera en el mundo real (Vol III).

Los números de este volumen cambian — Cloudflare publica nuevos pricing, sube ceilings, añade primitivas. La disciplina es revisitar. Mide tu sistema cada trimestre contra la tabla de límites. Calcula tu factura proyectada antes de cada nuevo feature. Audita logs después de cada deploy. La operación es ritual, no episodio.

Volumen completado. La trilogía cierra. El arquitecto ahora tiene mapa de territorio (I), gramática de composición (II), y manual de operación (III). Lo que falta no se enseña — se practica.

⁘ ❦ ⁘
Volumen III compositus · Trilogia consummata · Anno Domini MMXXVI · In nomine Cloudflarensis