Cuando un SaaS empieza a crecer, cada equipo quiere escuchar una señal distinta. Producto mira la activación, soporte mira los tickets y marketing mira los correos que se abren. Al principio todo cabe en un par de funciones. Después, cada cambio dispara más llamadas y nadie sabe muy bien que ocurrió primero.
En uno de mis experimentos de producto me pasó eso. Tenía un flujo de alta que enviaba eventos a varios destinos. El backend era pequeño, pero el contexto se perdía entre reintentos. La solución no fue comprar otra plataforma: fue poner una cola sencilla en medio y hacer que cada evento contara su propia historia.
El problema: demasiadas señales
El error más común es tratar un evento como una llamada aislada. Por ejemplo, user.created puede activar un correo, crear una tarea de onboarding y actualizar una métrica. Si una de esas acciones falla, el equipo necesita saber si debe repetirla, ignorarla o revisarla.
También aprendí que una etiqueta vaga como “alta completada” no ayuda mucho. Es mejor incluir un identificador, el origen y la versión del evento. Así podemos reconstruir el recorrido sin adivinar.
La cola mínima que funcionó
Mi modelo inicial tenía cuatro piezas:
- Productor: la API publica un evento y responde rápido al usuario.
- Cola: guarda el evento hasta que un consumidor pueda procesarlo.
- Consumidor: ejecuta una acción pequeña, como registrar una conversión.
- Registro: conserva estado, intentos y el último error.
El evento podía verse así:
{
"id": "evt_123",
"type": "signup.completed",
"user_id": "usr_456",
"source": "web",
"version": 1,
"created_at": "2026-09-08T05:00:00Z"
}
No hace falta que el primer diseño tenga particiones sofisticadas. Lo importante es que el id sea único y que el consumidor pueda comprobar si ya procesó el evento. Esa pequeña decisión evita duplicar créditos, mensajes o conversiones cuando llega un reintento.
Paso a paso
Primero definí los eventos que realmente necesitaba. Empecé con signup.completed, trial.started y activation.reached. No intenté modelar todo el negocio desde el día uno; eso vuelve el sistema dificil de explicar.
Después añadí una tabla de entregas con event_id, consumer, status, attempts y last_error. Un consumidor reclama un evento, hace su trabajo y cambia el estado a done. Si falla, guarda el error y vuelve a la cola con un retraso creciente.
La observabilidad fue la parte que más valor dio. Cada log incluye el event_id y el user_id, pero nunca datos sensibles. Para los trabajos programados, me ayudó leer ideas como estos prompts cortos para cron fiables, especialmente la práctica de hacer visible cada resultado.
Por último, conecté sólo dos consumidores: uno para métricas y otro para el mensaje de onboarding. Marketing recibió sus datos desde una vista agregada, no desde cada petición de la API. Esto redujo acoplamiento y facilitó cambiar una campaña sin tocar el flujo de alta.
Errores comunes
Reintentar para siempre. Un límite de intentos y una cola de revisión son más honestos. Un fallo permanente no desaparece por esperar.
Enviar información de más. El evento debe llevar referencias, no una copia completa del perfil. Menos datos significa menos riesgo y menos migraciones.
No separar intención de resultado. email.requested no significa email.delivered. Son hechos diferentes y conviene registrarlos por separado.
Mezclar cohortes. Una campaña de recuperación puede parecer exitosa si suma usuarios de periodos incompatibles. Esta es la razón por la que mantuve una vista específica para cohortes; mi nota sobre emails win-back sin mezclar cohortes explica ese criterio con más detalle.
En las pruebas también aparecieron búsquedas escritas como “fake e mail com” y “tamp mail com”. Las traté como entradas imperfectas de usuarios, no como nombres de campos ni como enlaces.
Checklist de implementación
- [ ] Cada evento tiene un identificador único.
- [ ] El consumidor es idempotente.
- [ ] Hay un límite de reintentos.
- [ ] Los errores quedan visibles para una persona.
- [ ] Los logs permiten seguir un evento completo.
- [ ] El evento evita datos personales innecesarios.
- [ ] Las métricas distinguen intención, éxito y fallo.
Recapitulación
Una cola no arregla por sí sola un producto confuso. Sí crea un punto claro para separar la petición del usuario de las tareas que ocurren después. Para un SaaS pequeño, empezar con eventos bien nombrados, entregas idempotentes y logs útiles suele ser suficiente.
Mi recomendación es construir un solo consumidor, observarlo durante unos días y añadir el siguiente cuando exista una necesidad concreta. Es menos espectacular, pero permite aprender con seguridad y mantener el backend entendible.
Top comments (0)