Colas vs. Streams: Cómo Elegir Bien en Arquitectura Orientada a Eventos (2026) · Daniel Tinizaray

Colas vs. Streams: Cómo Elegir Bien en Arquitectura Orientada a Eventos (2026) · Daniel Tinizaray

En 2026, la arquitectura orientada a eventos (EDA) ya no es un diferenciador: es la línea de base. La mayoría de empresas con escala publican eventos de dominio en un broker duradero, los servicios se comunican de forma asíncrona y el monolitio quedó descompuesto en servicios que emiten eventos cuando su estado cambia. La conversación maduró: ya no preguntamos "¿Kafka o RabbitMQ?", sino ¿qué problema estoy resolviendo: distribución de trabajo o historia de eventos? Esa distinción importa más que los nombres de los productos.

La distinción que lo cambia todo: trabajo vs. historia

Una tarea dice "haz esto". Un evento dice "esto ocurrió". Suena sutil, pero define toda la arquitectura. OrderPlaced, PaymentCaptured o InventoryReserved son hechos del dominio; "enviar el email de confirmación" es una instrucción.

  • Colas: optimizadas para procesamiento punto a punto. Un worker toma el mensaje, lo procesa y confirma. Perfectas para jobs en background, load leveling, reintentos diferidos y suavizar picos de tráfico.
  • Streams: un log append-only y durable. Ideales para replay, múltiples consumidores independientes, reconstrucción de estado, auditoría y análisis en tiempo real.

Si tu preocupación principal es "toma este trabajo y hazlo una vez", quieres una cola. Si necesitas que varios servicios lean el mismo hecho, o reconstruir estado desde la historia, quieres un stream.

Regla práctica: usa una cola cuando necesitas que alguien haga algo una vez; usa un stream cuando necesitas saber qué pasó y permitir que varios consumidores se enteren.

Colas: el caballo de batalla confiable

Las colas absorben ráfagas, dejan que los consumidores escalen de forma independiente y hacen manejable el backpressure: si el servicio downstream se lentifica, la cola amortigua la presión en lugar de sincronizar todo el sistema en pánico colectivo. Siguen siendo la herramienta correcta para:

  • Background jobs y comandos procesados una sola vez.
  • Load leveling y suavizado de picos estacionales.
  • Reintentos con backoff y retraso programado.
  • Desacoplar productor y worker con backpressure controlada.

Pero las colas no son magia: traen entrega at-least-once, mensajes duplicados, timeouts de visibilidad y limitaciones de orden. No eliminan la necesidad de código defensivo: solo mueven la complejidad al consumidor.

Streams: la memoria del sistema

Un stream no es "una cola más elegante": es un ledger opinado que lo recuerda todo. Ahí radica su poder: recomputar proyecciones, alimentar pipelines de analytics, añadir consumidores nuevos sin tocar productores y recuperarse de bugs reproduciendo eventos. Exige disciplina:

  • Las particiones afectan el orden; el orden global es una trampa cara.
  • Las políticas de retención deben entenderse y dimensionarse.
  • Los consumidores deben trackear offsets y ser replay-safe.

Si intentas que cada evento esté estrictamente ordenado en todo el sistema, convertirás una arquitectura escalable en una cola muy cara con título de filosofía.

Idempotencia: tu mejor amiga en un mundo de duplicados

En producción, at-least-once es el contrato por defecto: los mensajes pueden llegar más de una vez, los consumidores pueden caer tras procesar pero antes de confirmar, y los reintentos generan duplicados. El objetivo real es procesamiento effectively-once, y eso es una decisión de diseño de la aplicación, no una feature del broker.

-- Dedupe store: tabla con constraint único
CREATE TABLE processed_events (
  event_id      UUID PRIMARY KEY,
  payload       JSONB,
  processed_at  TIMESTAMPTZ DEFAULT now()
);

-- Todo path de escritura pasa por aquí:
INSERT INTO processed_events (event_id, payload)
VALUES ($1, $2)
ON CONFLICT (event_id) DO NOTHING;

El patrón funciona igual con Redis + TTL, con un outbox/inbox transaccional o con la tabla anterior: hacer que los duplicados sean aburridos. Un consumidor idempotente, deduplicador y replay-safe convierte los reintentos en no-eventos.

Schema registry: el contrato entre productor y consumidor

Si el schema discrepa con los datos serializados, el schema registry lanza una excepción y evita que datos malformados entren al topic. Productores y consumidores obtienen el schema del registry para deserializar, y las reglas de compatibilidad (backward, forward, full) permiten evolucionar contratos sin romper a nadie. Avro y Protobuf son el estándar; el registro de schemas es lo que hace que "agregar un campo" sea un cambio seguro en lugar de un incidente.

El patrón híbrido y la capa de streaming SQL

Los sistemas maduros de 2026 no eligen uno: combinan ambos. Colas para comandos y jobs; streams para eventos e historia. Por ejemplo: el checkout emite OrderPlaced a un stream; inventory, billing, shipping y analytics lo consumen de forma independiente; una cola separada gestiona emails, PDFs y demás trabajo orientado a tareas.

Orden de compra → Stream (evento de dominio)
  ├── inventory   (consumidor independiente)
  ├── billing     (consumidor independiente)
  ├── shipping    (consumidor independiente)
  └── analytics   (consumidor independiente)

Email / PDF / notificación → Cola (trabajo, 1 consumidor)

La novedad de 2026: sobre el stream se monta una capa de procesamiento con SQL (Flink, plataformas de streaming database) que mantiene vistas materializadas continuamente actualizadas. El broker responde "qué eventos ocurrieron"; la vista materializada responde "cuál es el estado actual de X".

Vistas materializadas y agentes AI (lo nuevo del 2026)

Un agente que consulta el topic directamente recibe un log crudo y debe reconstruir estado — caro y lento. Un agente que consulta la capa de streaming obtiene estado precomputado y siempre fresco: estado de la orden, violaciones de SLA activas, inventario en tiempo real. En 2026 los agentes se conectan vía MCP a estas vistas en lugar de parsear logs, lo que convierte la observabilidad en tiempo real en una capacidad consultable de forma nativa. Para equipos que ya tienen eventos en producción, esta es la evolución natural, no un rewrite.

Checklist antes de adoptar EDA

  1. ¿Cada evento de dominio tiene un event_id y un schema versionado en el registry?
  2. ¿Todos tus consumidores son idempotentes y replay-safe, o confían en "el broker nunca duplica"?
  3. ¿Sabes si tu caso es trabajo (cola) o historia (stream), o estás usando un stream como cola cara?
  4. ¿Tienes políticas de retención y particionado dimensionadas, no los defaults?
  5. ¿Puedes reintroducir un consumidor nuevo y reconstruir su estado desde el log sin tocar productores?

La EDA no resuelve la consistencia distribuida: para eso siguen existiendo los patrones saga. Pero elegir bien entre cola y stream, hacer los duplicados aburridos con idempotencia y contratar tus eventos con schemas versionados es lo que separa una arquitectura que escala de una que solo parece moderna.


¿Te gustó este artículo?

Si estás lidiando con estos desafíos en tu empresa, hablemos. Sin compromiso. 30 minutos para entender tu situación.

Agenda una llamada gratuita →