---
title: "CDN y headers de caché: pruebas de carga en hits, misses y riesgo de stampede"
description: "Ejercita comportamiento en edge de CDN, valida headers Age/TTL y detecta thundering herds cuando expiran cachés al unísono."
publishDate: "2026-09-03"
draft: false
keyword: "pruebas carga cdn cache headers"
intent: "MOFU"
cta: "Usa Performate para reproducir journeys conscientes de caché contra edges de staging sin improvisar bucles curl."
tags: ["k6", "pruebas-de-carga", "rendimiento-api", "cdn"]
translationOf: cdn-cache-headers-load-testing
---

El dashboard de CDN muestra 95% de hit ratio en producción, pero la última prueba de carga martilleó una URL estática durante diez minutos. Esa prueba no demostró nada sobre el edge: caminos hit y miss difieren órdenes de magnitud en latencia, carga en origen y firmas de error ([HTTP caching overview](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching)).

Las pruebas de carga de CDN y headers de caché validan **diversidad realista de claves**, **comportamiento al expirar TTL** y **riesgo de stampede** cuando muchos clientes fallan juntos. En esta guía verás por qué Age y Cache-Control importan bajo concurrencia, cómo etiquetar clases de hit en k6 y cuándo simular expiración coordinada.

## Por qué el comportamiento de caché cambia el rendimiento—no solo el ancho de banda

Bajo carga, las capas de caché mueven el cuello de botella:

- **Hits en edge** sirven desde memoria del PoP—sub-ms a decenas de ms según geografía ([pruebas geo](/es/blog/pruebas-de-carga-distribuidas-geo)).
- **Misses en edge** propagan a origen—de repente tu tier API ve picos de tráfico de marketing.
- **Stale-while-revalidate** responde rápido pero dispara fetches en background—la latencia se ve bien mientras RPS de origen sube en silencio.
- **Headers Vary** multiplican claves—una URL con distinto `Accept-Encoding` o cookies crea caminos fríos paralelos.

Martillar una URL produce una fantasía de caché caliente. Producción sirve miles de claves con TTLs escalonados.

### Cuando el hit ratio miente

Un hit ratio agregado alto oculta **misses en cola** en páginas de alto valor. Las pruebas deben variar URLs o claves según distribuciones de analytics—no un asset héroe.

Valida headers con [checks de k6](https://k6.io/docs/using-k6/checks/) mientras etiquetas `hit_class:edge|origin|unknown` según `Age`, `X-Cache` o `CF-Cache-Status` que exponga tu CDN.

## Implementación práctica con k6: tráfico mixto hit/miss con checks de headers

Modela una mezcla realista de assets cacheables desde CSV o selección aleatoria ponderada. Clasifica cada respuesta por headers.

**Script de ejemplo (ilustrativo—no es una prueba lista para producción).** Usa headers CDN y paths ficticios.

**Qué demuestra este ejemplo:**

- **Claves de caché variadas:** IDs aleatorios de un pool simulan muchas URLs, no un objeto caliente.
- **Clasificación por headers:** checks parsean `Age` y `X-Cache` para etiquetar métricas por clase de hit.
- **Escenario burst de miss:** segundo escenario martillea URLs frescas para simular arranques en frío coordinados.
- **Umbrales separados:** hits en edge esperan p95 menor que misses en origen—latencia agregada oculta regresiones.

```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';

const BASE = __ENV.CDN_BASE || 'https://cdn.staging.example.com';
const assets = new SharedArray('assets', () =>
  Array.from({ length: 200 }, (_, i) => `/static/product-${1000 + i}.webp`)
);

function classifyHit(res) {
  const age = Number(res.headers['Age'] || 0);
  const xCache = (res.headers['X-Cache'] || '').toLowerCase();
  if (xCache.includes('hit') || age > 0) return 'edge';
  if (xCache.includes('miss')) return 'origin';
  return 'unknown';
}

export const options = {
  scenarios: {
    steady_mix: {
      executor: 'constant-arrival-rate',
      rate: 80,
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 20,
      maxVUs: 60,
      exec: 'fetchAsset',
    },
    miss_burst: {
      executor: 'constant-arrival-rate',
      rate: 30,
      timeUnit: '1s',
      duration: '2m',
      startTime: '5m',
      preAllocatedVUs: 15,
      maxVUs: 40,
      exec: 'fetchColdAsset',
    },
  },
  thresholds: {
    'http_req_duration{hit_class:edge}': ['p(95)<120'],
    'http_req_duration{hit_class:origin}': ['p(95)<600'],
    http_req_failed: ['rate<0.01'],
  },
};

export function fetchAsset() {
  const path = assets[Math.floor(Math.random() * assets.length)];
  const res = http.get(`${BASE}${path}`, { tags: { asset: 'warm_pool' } });
  const hitClass = classifyHit(res);
  check(res, {
    'status 2xx': (r) => r.status >= 200 && r.status < 300,
    'cache-control present': (r) => !!r.headers['Cache-Control'],
  });
  sleep(0.1);
}

export function fetchColdAsset() {
  const coldPath = `/static/campaign-${__VU}-${__ITER}.jpg`;
  const res = http.get(`${BASE}${coldPath}`, { tags: { asset: 'cold', hit_class: 'origin' } });
  check(res, { 'cold fetch 2xx': (r) => r.status >= 200 && r.status < 300 });
  sleep(0.05);
}
```

**Patrones que funcionan**

- Calienta cachés con pre-test a baja tasa o paso `setup()` antes de medir hits.
- Coordina expiración TTL en staging seguro purgando subconjuntos o usando assets con TTL corto—observa picos en origen ([análisis de cuellos](/es/blog/analisis-cuellos-de-botella-api)).
- Compara tiempos edge vs origen; si saturan edges primero, ajusta PoPs—no GC de aplicación.

**Anti-patrones a evitar**

- Probar solo hits porque «eso ven los usuarios»—tormentas de miss causan caídas.
- Ignorar headers `Vary` que fragmentan efectividad de caché.
- Usar APIs de purge de CDN en prod sin ventana aprobada.

## Marco de decisión: mezcla estable vs simulación de stampede

| Situación | Acción recomendada |
|:---|:---|
| Validar tráfico cotidiano | URLs aleatorias ponderadas desde analytics; tag hit class |
| Lanzamiento de campaña con assets nuevos | Escenario burst de URLs frías tras warm-up estable |
| Alineación TTL entre clases de asset | Prueba de expiración escalonada en staging con fixtures TTL corto |
| Cambio de config CDN (PoP, tiered cache) | Re-corre mix idéntico; compara delta de RPS origen |
| Claves de caché con auth | Escenarios separados por variante cookie/header |

**Usa mezcla estable si** necesitas líneas base de regresión en comportamiento normal de caché.

**Usa burst de miss si** debes demostrar que origen aguanta arranques en frío coordinados.

**Usa assertions de headers si** mala config CDN devuelve 200 con Cache-Control incorrecto—deuda silenciosa.

## Observabilidad, documentación y siguientes pasos

- [ ] Documenta vendor CDN, regiones PoP y nombres de headers para clasificación hit.
- [ ] Registra ratio hit/miss por escenario—no solo http_req_duration agregado.
- [ ] Alerta cuando RPS origen en prueba supere fracción acordada de capacidad origen.
- [ ] Correlaciona tags k6 con dashboards de analytics CDN en la misma ventana.
- [ ] Archiva definiciones del pool de assets para reruns con distribución idéntica.

## Cómo Performate simplifica pruebas de carga conscientes de CDN

**Ejemplo: reproducir journeys cache-aware sin bucles curl**

1. **Importa colección** con GETs de assets estáticos más llamadas API que fijan headers que varían caché. *Problema resuelto:* un workspace cubre HTML, API y paths CDN.
2. **Parametriza URLs de assets** desde CSV de IDs de producto alineado a producción. *Problema resuelto:* diversidad realista de claves sin editar paths cada sprint.
3. **Agrega checks de Cache-Control y Age** en el editor visual. *Problema resuelto:* autores no-script validan headers de forma consistente.
4. **Corre mix estable, duplica escenario como burst de miss** con patrón de URL fresca. *Problema resuelto:* pruebas stampede son cambio de parámetro, no repo nuevo.
5. **Filtra reporte integrado por tag hit_class** y compara p95 edge vs origen. *Problema resuelto:* un export para equipos CDN y backend.
6. **Exporta script k6 para smoke CI** con checks de headers a baja tasa tras cambios de config CDN.

## Cierre

El rendimiento CDN es una **mezcla de hits y misses**, no una URL caliente única. Varía claves de caché con realismo, valida headers bajo carga y trata picos de origen en bursts de miss como puerta de release.

Corre esta semana el escenario mixto hit/miss contra staging antes del próximo cambio de CDN o TTL—y anota dónde RPS origen cruza tu techo acordado.

[Try Performate free](https://performate.app) | [Book a demo](/demo) | [k6 scenarios](https://k6.io/docs/using-k6/scenarios/)
