---
title: "Webhooks bajo fuego: reintentos, idempotencia y verificación de firma a escala"
description: "Pruebas de carga de webhooks: reintentos, verificación HMAC, replay en ráfaga—buenas prácticas Stripe y patrones k6 de stress."
publishDate: "2026-10-01"
draft: false
keyword: "pruebas carga webhooks"
intent: "MOFU"
cta: "Usa Performate para convertir este playbook en escenarios k6 ejecutables, umbrales y reportes compartibles sin perder días en código de integración."
tags: ["k6", "pruebas-de-carga", "rendimiento-api", "webhook"]
translationOf: webhooks-retries-idempotency-load-testing
---

Los webhooks fallan bajo carga cuando **reintentos duplican trabajo**, **firmas** queman CPU y **ráfagas** superan la concurrencia de handlers—no cuando entregas sueltas funcionan en Postman. La [guía de webhooks de Stripe](https://docs.stripe.com/webhooks/best-practices) insiste en claves de idempotencia y handlers tolerantes—tus pruebas deben golpear esa realidad antes de que el proveedor de pagos reintente mil eventos `payment.succeeded` en tu cluster de staging.

Esta guía modela entrega en ráfaga, replay de `event_id` duplicado, costo de verificación de firma y enlaza efectos de backlog async ([pipelines de cola](/es/blog/pruebas-carga-pipeline-async-queue-worker)). Obtienes un script k6 de ráfaga con firma HMAC, enrutamiento de decisión por tipo de riesgo y criterios de aborto cuando suben 5xx o tasas de DLQ.

## Escenarios a modelar

El perf de webhooks no es latencia media de POST—es **forma** y **duplicación**:

- **Entrega en ráfaga**—tormenta de reintentos del proveedor tras que tu endpoint se ralentizó dos minutos.
- **Payloads duplicados con mismo `event_id`**—mismo evento entregado dos veces; el handler debe 200 o 409, no cobrar doble.
- **Ruta de firma inválida**—muestra baja tasa de 401/403 para asegurar que fallo crypto es barato vs ruta de éxito.
- **Backlog en cola downstream**—handler acepta rápido pero workers van retrasados; HTTP verde, SLO de negocio rojo.
- **Verificación concurrente**—HMAC por request a alto RPS CPU-bound en instancias pequeñas.

### Forma Stripe vs inbound genérico

Adapta headers (`Stripe-Signature`, `X-Signature` custom) a tu proveedor; el patrón k6 se mantiene: firmar body, POST, comprobar códigos idempotentes. Nunca uses secretos de firma de prod en git—solo [secretos k6](/es/blog/k6-secretos-entornos-prueba).

## k6 ráfaga + eventos duplicados

**Ilustrativo—no listo para producción.** Incluye escenario de eventos duplicados en plan de prueba extendido; el snippet se centra en ráfaga firmada.

**Qué demuestra este ejemplo:**

- Spike `ramping-arrival-rate` simula tormenta de reintentos—paso 10 → 200 req/s.
- Firma HMAC en script—modela costo CPU de verificación bajo carga.
- Check acepta 200 o 409—409 como éxito idempotente para `event_id` duplicado.
- Tags `route:webhook` para filtrar de escenarios REST en la misma suite.

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

const secret = __ENV.WEBHOOK_SECRET || 'test_secret';
const BASE = __ENV.API_BASE || 'https://staging.example.com';

function sign(body) {
  return crypto.hmac('sha256', secret, body, 'hex');
}

export const options = {
  scenarios: {
    webhook_burst: {
      executor: 'ramping-arrival-rate',
      startRate: 10,
      timeUnit: '1s',
      preAllocatedVUs: 30,
      maxVUs: 150,
      stages: [
        { duration: '1m', target: 10 },
        { duration: '30s', target: 200 },
        { duration: '2m', target: 200 },
        { duration: '1m', target: 10 },
      ],
      tags: { suite: 'webhook_burst' },
    },
  },
  thresholds: {
    http_req_failed: ['rate<0.02'],
    'http_req_duration{route:webhook}': ['p(95)<1500'],
  },
};

export default function () {
  const body = JSON.stringify({
    event_id: `evt-${__VU}-${__ITER}`,
    type: 'payment.succeeded',
  });
  const res = http.post(`${BASE}/webhooks/inbound`, body, {
    headers: {
      'Content-Type': 'application/json',
      'X-Signature': sign(body),
    },
    tags: { route: 'webhook', suite: 'webhook_burst' },
  });
  check(res, { accepted: (r) => r.status === 200 || r.status === 409 });
  sleep(0.05);
}
```

**Patrones que funcionan**

- **Subconjunto duplicado**—10% iteraciones reutilizan lista fija de `event_id`—valida dimensionado del store de idempotencia.
- **Tripwire de aborto** en 5xx > 1% durante ráfaga—para antes de corromper datos de staging compartido.
- **Monitorear DLQ e idempotency DB** durante corrida—HTTP es necesario, no suficiente.
- **Solo eventos sintéticos**—sin ids de clientes prod en payloads ([GDPR](/es/blog/datos-prueba-rendimiento-gdpr)).

**Antipatrones a evitar**

- Prueba de carga contra URL webhook de prod sin aprobación del proveedor.
- Medir solo tasa 200—ignorar semántica 409 y efectos secundarios duplicados.
- Ignorar backlog de workers async—emparejar con [lag de cola](/es/blog/pruebas-carga-pipeline-async-queue-worker).
- Cero fallos de firma en plan de prueba—regresiones crypto se esconden hasta intentos de falsificación en prod.

**Pro tip (comando de ejemplo):** exportar stats solo webhook para equipo de pagos.

```bash
k6 run webhook-burst.js --summary-trend-stats="p(95),p(99)" --tag route=webhook
```

**Qué demuestra este comando:** summary filtrado se adjunta a revisión de pagos sin ruido REST de escenarios no relacionados en el mismo repo.

## Marco de decisión: riesgo vs prueba

| Riesgo | Prueba | Criterio de pass |
|:---|:---|:---|
| Eventos duplicados | Repetir mismo `event_id` en subconjunto | 200 o 409; sin efectos secundarios dobles |
| Tormenta de retry | Spike ARR | Tasa de error + DLQ acotada |
| Falsificación | Firmas inválidas baja tasa | 401 rápido; sin enqueue worker |
| CPU handler | Ráfaga con firma activa | `p95` dentro SLO bajo spike |
| Lag end-to-end | HTTP + tendencia lag cola | SLA de negocio en tiempo de completado |

## Observabilidad y checklist pre-corrida

- [ ] Store de idempotencia dimensionado para duplicados en ráfaga—documentar cardinalidad máxima de `event_id` probada.
- [ ] Monitoreo DLQ durante prueba con owner de aborto nombrado.
- [ ] Solo eventos sintéticos; secreto de firma desde perfil env.
- [ ] Workers downstream escalados conscientemente—interpretar HTTP vs lag por separado.
- [ ] Comparar ráfaga con lenguaje de [spike test](/es/blog/stress-vs-carga-vs-spike-testing) en runbook de lanzamiento.
- [ ] Archivar export para pagos/cumplimiento si flujos regulados tocados.

## Cómo Performate apoya pruebas de carga de webhooks

Abajo hay un **ejemplo de flujo concreto** para webhooks inbound de pagos—adapta header de firma a tu proveedor.

**Ejemplo: import Postman → escenario ráfaga → export pagos**

1. **Importa** request webhook desde Postman—plantilla de body preservada. *Problema resuelto:* payload de firma coincide con lo que pruebas funcionales ya usan.
2. **Añade** lógica pre-request de firma en k6 exportado—HMAC desde secreto env. *Problema resuelto:* ruta crypto incluida sin reimplementación manual cada sprint.
3. **Configura** stages de ráfaga en UI—spike 30s a 200 req/s. *Problema resuelto:* stages visuales reducen errores YAML antes de revisión de pagos.
4. **Corre** con tripwire de aborto en 5xx—owner Slack etiquetado. *Problema resuelto:* staging compartido protegido durante ráfaga agresiva.
5. **Exporta** reporte para equipo de pagos—tasa 409 visible junto a 200. *Problema resuelto:* historia de idempotencia contada con números, no walkthrough de código.
6. **Promueve** smoke de entrega única a CI—ráfaga queda manual pre-release. *Problema resuelto:* regresión diaria en cableado sin tormenta de retry diaria.

Ese flujo mapea directamente al `cta` de este post: escenarios webhook ejecutables y reportes compartibles sin sprints de glue code.

## Cierre

El perf de webhooks es **ráfagas + duplicados + crypto**, no latencia media de POST. Programa un spike con forma de reintento antes del próximo incidente de pagos; valida rutas 409; vigila DLQ mientras HTTP sigue viéndose bien.

Importa tu webhook inbound, añade firma, corre una ráfaga en staging y registra dónde empiezan los 5xx—esa tasa pertenece al runbook de pagos.

[Try Performate free](https://performate.app) | [Book a demo](/demo) | [Webhooks Stripe](https://docs.stripe.com/webhooks)
