El problema fundamental que Workers Cache aborda es la ineficiencia inherente de las aplicaciones server-rendered (SSR) cuando se ejecutan en entornos de edge computing sin una capa de caché adecuada. Tradicionalmente, los Workers de Cloudflare se posicionaban delante de la caché, permitiendo la manipulación de solicitudes antes de que llegaran a un origen o a la caché de zona. Sin embargo, con la evolución de los Workers para convertirse en el origen mismo (especialmente con frameworks modernos como Next.js, Remix, Astro), esta arquitectura original significaba que cada solicitud, incluso para contenido idéntico, incurría en el costo de ejecución del Worker y la latencia asociada.

Workers Cache invierte esta arquitectura, colocando la caché delante del Worker. Esto permite que las respuestas previamente generadas se sirvan directamente desde la caché global de Cloudflare, eliminando la necesidad de ejecutar el Worker en un hit. La relevancia actual radica en la creciente adopción de SSR para ofrecer experiencias de usuario dinámicas y frescas, sin sacrificar la velocidad de los sitios estáticos. Este cambio de paradigma permite a los desarrolladores obtener lo mejor de ambos mundos: contenido siempre actualizado con la velocidad de la caché de borde, sin la complejidad de la generación estática incremental o la gestión manual de cachés externas.

Arquitectura del Sistema

Workers Cache implementa una arquitectura de caché tiered por defecto, compuesta por dos capas: una capa inferior (lower tier) en el data center de Cloudflare más cercano al usuario y una capa superior (upper tier) que agrega los 'fills' de caché a través de toda la red. Cuando una solicitud llega, primero consulta la lower tier. Si hay un hit, la respuesta se sirve inmediatamente. Si hay un miss, la lower tier consulta la upper tier. Un hit en la upper tier resulta en que la respuesta se sirve y se almacena en la lower tier. Solo si ambas capas fallan, el Worker se ejecuta, y su respuesta se almacena en ambas tiers.

La configuración se realiza a través de un simple flag en wrangler.jsonc y mediante encabezados HTTP estándar como Cache-Control (con directivas como max-age, public, stale-while-revalidate) y Vary. Esto permite un control granular sobre el TTL, la revalidación en segundo plano y la negociación de contenido. La clave de caché se construye a partir del entrypoint del Worker, la ruta, la query string y, crucialmente, ctx.props para escenarios multi-tenant. Las purgas programáticas se realizan mediante ctx.cache.purge() y pueden dirigirse por tags o prefijos de ruta. Una característica distintiva es que la caché es 'propiedad' del Worker, no de la zona, lo que significa que sigue al Worker a través de diferentes dominios y entornos (workers.dev, previews, Workers for Platforms) y las purgas están scoped al entrypoint del Worker. Además, la caché se interpone entre cada entrypoint de Worker, permitiendo patrones de composición donde diferentes etapas de una aplicación (autenticación, normalización, lógica de negocio) pueden tener sus propias políticas de caché.

Flujo de Solicitud con Workers Cache

  1. 1 Usuario Envía solicitud HTTP
  2. 2 Cloudflare Edge Recibe solicitud, consulta Lower Tier Cache
  3. 3 Lower Tier Cache Hit: Sirve respuesta. Miss: Consulta Upper Tier Cache
  4. 4 Upper Tier Cache Hit: Sirve respuesta, almacena en Lower Tier. Miss: Ejecuta Worker
  5. 5 Worker Se ejecuta, genera respuesta, almacena en ambas Tiers
  6. 6 Cloudflare Edge Devuelve respuesta al usuario

Flujo de Composición de Workers con Cache

  1. 1 Usuario Envía solicitud HTTP
  2. 2 Worker A (Gateway) Autentica, normaliza, enruta. Caching deshabilitado.
  3. 3 Worker A Llama a Worker B vía Service Binding/ctx.exports con ctx.props
  4. 4 Workers Cache Consulta caché para Worker B (keyed por URL + ctx.props)
  5. 5 Workers Cache Hit: Devuelve respuesta a Worker A. Miss: Ejecuta Worker B
  6. 6 Worker B (Backend) Lógica de negocio costosa, acceso a datos. Caching habilitado.
  7. 7 Worker B Genera respuesta, almacena en Workers Cache
  8. 8 Worker A Recibe respuesta de Worker B (o caché), la devuelve al usuario
CapaTecnologíaJustificación
cache Cloudflare Workers Cache Proporciona una capa de caché distribuida y tiered directamente frente a los Workers, optimizando la entrega de contenido y reduciendo la carga de ejecución. vs Cloudflare Zone Cache (Page Rules, Cache Rules), Cachés de origen personalizadas, Generación de sitios estáticos (SSG) enabled: true en wrangler.jsonc; Cache-Control, Vary, Cache-Tag en headers de respuesta HTTP.
compute Cloudflare Workers Plataforma de ejecución de código serverless en el edge, que ahora puede operar tanto delante como detrás de la capa de caché. vs AWS Lambda@Edge, Fastly Compute@Edge, Netlify Functions Uso de service bindings y ctx.exports para la composición de Workers y la interacción con la caché interna.
networking HTTP/1.1, HTTP/2 Protocolo subyacente para la comunicación y la configuración de la caché mediante encabezados estándar. Encabezados Cache-Control (max-age, stale-while-revalidate), Vary, Cache-Tag.

Trade-offs

Ganancias
  • Reducción de latencia para usuarios
  • Reducción de costos de CPU para Workers
  • Mayor hit ratio de caché global
  • Simplificación de la arquitectura para SSR
  • Flexibilidad de composición de Workers
Costes
  • Incremento en el costo de solicitudes para activos estáticos y Worker-to-Worker invocations (ahora pasan por la caché y se facturan)
  • Complejidad potencial en la gestión de Vary headers para evitar fan-out excesivo de variantes de caché
{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2026-05-01",
  "cache": {
    "enabled": true
  }
}
Habilitar Workers Cache para un Worker en el archivo wrangler.jsonc.
return new Response(body, {
  headers: {
    "Cache-Control": "public, max-age=300, stale-while-revalidate=3600",
    "Cache-Tag": "products,product:123"
  }
});
Establecer encabezados HTTP para controlar el comportamiento de la caché y permitir purgas por tags.
await ctx.cache.purge({ tags: ["product:123"] });
Invalidar entradas de caché específicas utilizando tags.
{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2026-05-01",
  "cache": { "enabled": true },
  "exports": {
    "default": { "type": "worker", "cache": { "enabled": false } },
    "CachedBackend": { "type": "worker", "cache": { "enabled": true } }
  }
}

// En src/index.ts
export class CachedBackend extends WorkerEntrypoint<Env, Props> {
  async fetch(request: Request): Promise<Response> {
    const { userId } = this.ctx.props;
    const data = await loadExpensiveData(userId);
    return new Response(JSON.stringify(data), {
      headers: {
        "Content-Type": "application/json",
        "Cache-Control": "public, max-age=300, stale-while-revalidate=3600",
        "Cache-Tag": `user:${userId}`,
      },
    });
  }

  async invalidate(userId: string): Promise<void> {
    await this.ctx.cache.purge({ tags: [`user:${userId}`] });
  }
}

export default {
  async fetch(request, env, ctx): Promise<Response> {
    const userId = await authenticate(request, env);
    if (!userId) return new Response("Unauthorized", { status: 401 });

    if (request.method === "POST") {
      await handleWrite(request, userId);
      await ctx.exports.CachedBackend.invalidate(userId);
      return new Response("OK");
    }

    const forwarded = new Request(request);
    forwarded.headers.delete("Authorization");
    return ctx.exports.CachedBackend.fetch(forwarded, {
      props: { userId },
    });
  },
} satisfies ExportedHandler<Env>;
Ejemplo de un Worker con un entrypoint de gateway (sin caché) y un backend cacheado, utilizando ctx.props para aislamiento multi-tenant.

Fundamentos Teóricos

El concepto de caching distribuido y tiered se remonta a los fundamentos de los sistemas distribuidos y las redes de entrega de contenido (CDN). Principios como la localidad de referencia y la jerarquía de memoria, estudiados en la arquitectura de computadoras, se aplican directamente a las arquitecturas de caché tiered. La directiva stale-while-revalidate tiene sus raíces en RFC 5861 (2010), que formalizó este comportamiento para mejorar la percepción de latencia del usuario al servir contenido ligeramente obsoleto mientras se refresca en segundo plano. La negociación de contenido a través del encabezado Vary está definida en RFC 9110 y RFC 9111, que son los estándares modernos para HTTP Semantics y Caching, respectivamente. Estos RFCs establecen las bases para cómo los proxies y cachés deben manejar múltiples representaciones de un recurso, asegurando la corrección y la eficiencia. La idea de una caché que se interpone entre componentes de una aplicación, más allá de un origen externo, recuerda a los patrones de memoización y los sistemas de 'middleware' con capacidades de caché, donde la optimización se aplica a nivel de función o servicio interno.