¿Qué es Idempotencia? Métodos HTTP, API Keys, Ejemplos

Idempotencia: llamar a una operación N veces tiene el mismo efecto que una vez — crítico para retries seguros. GET/PUT/DELETE son idempotentes.

¿Qué es idempotencia?

Idempotencia es una propiedad de una operación donde ejecutarla múltiples veces produce el mismo resultado que ejecutarla una sola vez. En notación matemática: f(x) = f(f(x)) = f(f(f(x))). En contextos de APIs y sistemas distribuidos, una operación idempotente puede ser reintentada con seguridad sin causar side effects no intencionados — crítico cuando las redes son no fiables y no sabes si tu request anterior tuvo éxito.

El ejemplo clásico es un botón de elevador: presionarlo una o diez veces produce el mismo resultado (el elevador llega una vez). Compara con cobrar una tarjeta de crédito: presionar "pagar" diez veces sin idempotencia produce diez cargos. El diseño idempotente hace que los sistemas sean seguros para reintentar.

Idempotencia en APIs HTTP/REST

La especificación HTTP (RFC 7231) define qué métodos son idempotentes:

Método HTTP¿Idempotente?Uso típico
GETLee un recurso — llamado N veces devuelve los mismos datos, sin cambio de estado
HEADComo GET pero solo headers
PUTReemplaza un recurso — llamado N veces deja el recurso en el mismo estado final
DELETERemueve un recurso — N veces: la primera lo remueve, las siguientes son no-ops
OPTIONSDescubrir métodos permitidos
TRACELoopback diagnóstico
POSTNoCrea un recurso — llamado N veces típicamente crea N recursos
PATCHNo (por defecto)Update parcial — depende de semántica

Nota que idempotente NO significa "devuelve la misma response". DELETE devuelve 204 la primera vez y 404 en subsiguientes — responses diferentes, pero el estado del servidor es idéntico. La propiedad es sobre estado final, no equivalencia de response.

Ejemplos: idempotente vs no-idempotente

Operaciones idempotentes

  • PUT /users/123 {"name": "Alice"} — setea el nombre del user a Alice. Llamarlo 10 veces deja el nombre como Alice.
  • DELETE /sessions/abc — remueve session abc.
  • GET /products/42 — lee producto 42.
  • PUT /flags/feature-x {"enabled": true} — toggle de feature flag por valor absoluto.

Operaciones no-idempotentes

  • POST /orders {...} — crea una nueva orden. 10 veces crea 10 órdenes.
  • POST /charges {...} — cobra una tarjeta. 10 veces cobra 10 veces.
  • PATCH /counters/x {"increment": 1} — incrementa por 1 cada call.
  • POST /emails {"to": "..."} — envía un email. 10 calls = 10 emails.

Por qué importa la idempotencia

En un mundo single-machine transactional, nunca llamarías la misma operación dos veces. Pero los sistemas modernos son distribuidos — y eso cambia todo:

  • Fallas de red. Tu cliente envía un request, no obtiene response. ¿Tuvo éxito? No sabes. Idempotente → reintentas con seguridad.
  • Timeouts. Mismo problema. El server puede haber procesado el request después que el cliente se rindió.
  • Reintentos distribuidos. Service meshes, load balancers y SDKs auto-reintentan. Solo seguro si upstream es idempotente.
  • Arquitecturas basadas en colas. Mensajes pueden ser entregados más de una vez (at-least-once). Consumers deben manejar duplicados idempotentemente.
  • Comportamiento de usuarios. Los usuarios doble-clickean botones submit, refrescan páginas mid-request.

Idempotency keys

Para operaciones naturalmente no-idempotentes como crear una orden o cobrar una tarjeta, el patrón estándar es la idempotency key: un identificador único generado por el cliente (típicamente UUID) enviado con cada request. El server registra el resultado indexado por este ID y devuelve el mismo resultado para cualquier request subsecuente con la misma key.

POST /charges
Idempotency-Key: 8e0a4e6b-1b8e-4e3a-b9f7-5e1d3f9c4b8a
{
  "amount": 5000,
  "currency": "USD"
}

El primer call procesa el cargo y guarda el resultado. Calls subsecuentes con la misma key devuelven el resultado guardado sin re-procesar. La key típicamente expira después de un window (ej. 24 horas).

Implementando idempotency keys server-side

  1. Recibe request con idempotency key.
  2. Chequea el key store (Redis, tabla DB) por entrada existente.
  3. Si encontrada: devuelve la response guardada (sin side effects).
  4. Si no encontrada: adquiere un lock en la key, procesa el request, guarda la response, libera el lock.
  5. Maneja in-flight requests: si llega un duplicado mientras el primero procesa, espera o devuelve 409 Conflict.
  6. Expira keys después del window acordado.

Ejemplos del mundo real

  • Stripe. La implementación de referencia. Cada endpoint API que cambia estado acepta un header Idempotency-Key.
  • AWS SDK. Muchas APIs AWS usan parámetros ClientToken (idempotency keys) — EC2 RunInstances, RDS CreateDBInstance.
  • PayPal, Square, Adyen. Todos los procesadores de pago usan idempotency keys.
  • HTTP/2 + clientes retry-aware. Clientes HTTP modernos auto-reintentan métodos idempotentes en fallas de conexión.

Pitfalls comunes

  • Tratar PATCH como siempre idempotente. Depende de semántica.
  • Side effects más allá de la base de datos. Si tu endpoint "idempotente" envía un email, llamarlo dos veces envía dos emails.
  • Idempotency keys sin expiry. Almacenar cada key forever causa crecimiento ilimitado. Setea TTLs.
  • Race conditions en reintentos concurrentes. Usa locks o constraints DB.
  • Confundir idempotencia con safety. Safe = sin side effects (GET). Idempotente = N calls = efecto de 1 call. PUT/DELETE son idempotentes pero no safe.

Idempotencia en load testing

  • Endpoints POST acumulan estado. Un load test 1000-VU contra POST /orders crea 1000 × duración × rps órdenes. Cleanup después.
  • Reuso de idempotency key cachea la response. Si tu script reusa la misma key entre VUs, todos los VUs obtienen la response cacheada.
  • Genera idempotency keys únicas por VU/iteración.
  • Testea el mecanismo de idempotencia mismo.

FAQ: Idempotencia

¿Es GET siempre idempotente?

Por la spec HTTP, sí — GET nunca debería modificar estado. En la práctica, algunas APIs hacen mal uso de GET para cambios de estado.

¿Es PATCH idempotente?

Depende de la operación. PATCH {set: x} es idempotente. PATCH {increment: 1} no.

¿Cuál es la diferencia entre idempotencia y safety?

Safe significa sin side effects observables (GET, HEAD, OPTIONS). Idempotente significa N calls = estado final de 1 call. PUT y DELETE son idempotentes pero no safe.

¿Cómo hago POST idempotente?

Usa una idempotency key — un ID único generado por cliente (UUID) enviado con cada request.

¿Qué es un buen TTL de idempotency key?

Stripe usa 24 horas. Para APIs high-throughput, 1 hora puede ser suficiente. Para APIs de pago low-throughput, 7-30 días dan más tolerancia de retry.

¿Aplica idempotencia a gRPC y GraphQL?

Sí. Las definiciones de método gRPC pueden especificar nivel de idempotencia. Operaciones GraphQL Query son idempotentes por convención; Mutations necesitan diseño explícito de idempotencia.

Prueba LoadFocus para testear idempotencia at scale

Si estás diseñando un mecanismo de idempotencia y quieres verificarlo bajo carga (reintentos concurrentes, race conditions, expiry de keys), LoadFocus corre scripts JMeter y k6 desde 25+ regiones cloud con hasta 12.500 VUs. Regístrate en loadfocus.com/signup — sin tarjeta de crédito — y corre tu primer stress test de idempotencia en menos de 5 minutos.

¿Qué tan rápido es tu sitio web?

Mejora su velocidad y SEO sin problemas con nuestra Prueba de Velocidad gratuita.

Prueba de velocidad de sitio web gratis

Analice la velocidad de carga de su sitio web y mejore su rendimiento con nuestro comprobador de velocidad de página gratuito.

×