Alguna vez te has quedado mirando un incidente en producción pensando Qué demonios pasó aquí. Sabes que algo salió mal, pero el sistema no recuerda lo ocurrido. Si te suena, no estás solo.
Tras años construyendo sistemas distribuidos, me he topado con esta frustración demasiadas veces. Las arquitecturas tradicionales, aunque familiares, a menudo nos dejan ciegos cuando fallan. Perdemos contexto, perdemos historia y perdemos la capacidad de entender nuestros propios sistemas.
Y si te dijera que hay otra forma. Una que le da a tus sistemas memoria perfecta, trazabilidad completa y superpoderes de depuración que hacen que los enfoques tradicionales parezcan primitivos.
Esta es la historia de cómo aprendí a dejar de preocuparme y a amar los eventos en crudo. Va sobre event sourcing, CQRS y cómo el ecosistema de Python te da todo lo necesario para construir sistemas que se explican a sí mismos.
El problema: cuando los sistemas olvidan
Un caso muy común: es lunes por la tarde y te llega el aviso por chat interno de que falta la cuenta de Sarah. Revisas la base de datos. Nada. El registro del usuario ha desaparecido. A la mañana siguiente sigues sin saber cuándo se borró, quién lo hizo y por qué. Tu responsable pregunta y no tienes respuestas.
Este es el peor escenario. Tu sistema no tiene memoria y tú intentas recomponer pistas de logs y monitores. Todo por un diseño centrado solo en el estado actual.
Por qué nos fallan los sistemas tradicionales
Las arquitecturas tradicionales giran en torno al estado actual. Una fila por entidad y cuando algo cambia, se actualiza esa fila. Si algo se elimina, desaparece. Con suerte hay soft deletes con un deleted_at y quizá un updated_by. Pero incluso así solo capturas lo básico. Pierdes el por qué, el contexto y la secuencia de cambios que te llevó hasta ese punto. Y si no hay soft deletes, no queda rastro alguno.
Estos sistemas están optimizados para almacenar el presente, no para recordar el pasado. Optimizan eficiencia, no comprensión. Qué pasaría si le diéramos la vuelta y almacenáramos cada cambio que ocurre. Qué pasaría si el sistema tuviera memoria perfecta.
La solución: eventos como fuente de la verdad
Con event sourcing no almacenamos el estado actual, sino eventos: hechos inmutables que representan cada cambio que ocurre en el sistema. Piensa en los eventos como el ADN de tu aplicación. Cada decisión y acción se registra como un hecho que no se altera ni se borra. Se guardan sin interpretación, lo que permite que distintas partes del sistema los interpreten de formas diferentes.
Un evento típico de usuario eliminado puede incluir campos como id, aggregate_id, event_type igual a USER_DELETED, version, timestamp, revision y un bloque de datos con deleted_by y reason. Los puntos clave son: los eventos son inmutables; version permite evolucionarlos sin romper compatibilidad; revision asegura el orden correcto de reproducción; y data captura el contexto completo de quién lo hizo y por qué.
En vez de perder información, la capturamos toda. Construimos el historial completo del sistema.
Event store: la memoria del sistema
Estos eventos se almacenan en un event store de solo anexado, organizado en streams por agregado. Cada usuario tiene su historia contada como secuencia: UserCreated, UserNameChanged, UserEmailChanged, UserStatusChanged, UserDeleted. El stream se convierte en la fuente de la verdad. Podemos reconstruir cualquier instante reproduciendo los eventos en orden. Quieres saber cómo estaba la cuenta de Sarah el martes pasado, reproduce hasta ese momento. Es viajar en el tiempo.
CQRS: separar lo que escribimos de lo que leemos
En sistemas tradicionales usamos los mismos modelos para escribir y leer. Con CQRS separamos responsabilidades. El camino de escritura se optimiza para consistencia y el de lectura para rendimiento.
Los comandos expresan intención de cambiar el sistema, se validan, son idempotentes y al ejecutarse generan eventos en el event store. Las consultas se optimizan para acceder y no tienen por qué ser normalizadas. Puedes tener múltiples modelos de lectura para un mismo dato, cada uno adaptado a un caso de uso. Resultado: consistencia fuerte al escribir y alto rendimiento al leer.
Agregados: donde vive la lógica de negocio
La lógica de dominio vive en agregados. El flujo es simple: 1 reconstruyes el estado aplicando eventos anteriores, 2 validas reglas de negocio frente al comando, 3 si todo pasa generas nuevos eventos, 4 si no, devuelves errores. Así preservas invariantes y mantienes el estado coherente.
Proyecciones: convertir eventos en modelos de lectura
Las proyecciones escuchan eventos y construyen modelos de lectura optimizados. Un UserCreated crea el registro de usuario; un EmailChanged actualiza su email. Las proyecciones permiten que un mismo evento dispare múltiples acciones: crear registro en el modelo de lectura, enviar email de bienvenida, generar auditoría, actualizar analítica. Este desacoplamiento facilita añadir nuevos comportamientos sin tocar lógica existente.
De la teoría a la práctica con Python
El ecosistema Python ya tiene todo lo necesario. FastAPI para la capa web, Celery para el procesamiento asíncrono de eventos y una integración limpia entre piezas para un sistema robusto y escalable.
La imagen completa
En el camino de comandos el usuario invoca un endpoint de FastAPI para cambiar contraseña, se construye un ChangePasswordCommand y un handler orquesta: 1 recupera el stream del usuario, 2 reconstruye el UserAggregate aplicando eventos, 3 llama a change_password que valida y genera nuevos eventos, 4 persiste en el event store y despacha al bus de eventos. En el camino de consultas, un endpoint de lectura accede directamente al modelo optimizado. Misma API, caminos distintos: eso es CQRS.
FastAPI como interfaz de comandos y consultas
Los endpoints convierten la petición en objetos de comando o consulta con modelos Pydantic, resuelven handlers por inyección de dependencias y ejecutan handle. Sencillo y explícito.
Handlers de comandos: orquestación
El handler no contiene lógica de negocio, solo coordina. Un patrón Unit of Work asegura atomicidad: si persiste eventos y despacha al bus y algo falla, se revierte todo. Nada de estados a medias.
Agregados: reglas en Python puro
Los agregados son clases puras que reciben entradas, validan reglas y producen eventos como PASSWORD_CHANGED. El método apply permite reconstruir el estado aplicando cada evento histórico, base del event sourcing.
Manejador de eventos: integración con Celery
Un CeleryEventHandler mapea cada tipo de evento a una o más tareas Celery. Así definimos qué efectos secundarios ejecutar por evento. Añadir nuevos efectos es tan fácil como sumar tareas al mapeo, sin tocar agregados ni handlers de comandos.
Tareas Celery: procesamiento fiable
Las tareas invocan proyecciones y usan acks_late true para asegurar que un fallo devuelve el mensaje a la cola y se reintenta. Fiabilidad ante todo.
Proyecciones: modelos de lectura event driven
Una UserCreatedProjection transforma el evento en un documento de lectura con id, nombre, email, estado y created_at, y lo persiste. Su misión es mantener actualizado el modelo de lectura, no validar negocio ni orquestar procesos.
Realidad en producción: lo que de verdad ocurre
El reto UX de la consistencia eventual
Sarah cambia su nombre a Sara. El API responde éxito, pero la lectura todavía muestra Sarah. La proyección sigue procesando. Dos enfoques comunes: 1 actualizaciones optimistas en front, suficientes en muchos casos; 2 patrón outbox con tabla de eventos pendientes, estados de procesamiento y vistas de control. La consistencia eventual es tan técnica como de experiencia de usuario.
Rendimiento con snapshots
A medida que crece el stream, reconstruir puede tardar segundos. Solución: snapshots periódicos de estado, por ejemplo cada 1000 eventos. Al manejar un comando solo reproduces los eventos posteriores al snapshot, reduciendo tiempos drásticamente.
Superpoderes de depuración: pruebas con datos reales
Puedes reconstruir exactamente el estado de cualquier momento reproduciendo eventos. Esto permite depurar y probar casos reales de producción con precisión absoluta. Responder qué estado tenía Sarah cuando se borró su cuenta deja de ser un misterio.
Conclusiones prácticas y decisiones estratégicas
Empieza simple y evoluciona
No necesitas Kafka ni un event store especializado para empezar. PostgreSQL como event store, un broker sencillo y Celery funcionan de maravilla. FastAPI, SQLAlchemy y Pydantic están más que probados. Empieza simple, valida valor y aprende los patrones antes de sofisticar tu infraestructura.
Cuándo no usar event sourcing
Si tu caso es CRUD sencillo con auditoría básica, un logging tradicional basta. Si necesitas consistencia inmediata en lecturas de alta frecuencia como trading, la consistencia eventual te penalizará. Si tu equipo no tiene experiencia en sistemas distribuidos, evalúa empezar por patrones más simples y subir el nivel después.
Lo que ganas cuando encaja
Trazabilidad completa y viaje en el tiempo, depuración con datos reales, escalabilidad separando escrituras de lecturas y sistemas que se explican solos. No solo funcionales, también entendibles, escalables, depurables y fiables.
Implementación con Python y valor de negocio
El ecosistema Python es potentísimo para sistemas distribuidos. Con FastAPI, Celery y Pydantic puedes construir plataformas que escalan y se auditan a sí mismas. En Q2BSTUDIO diseñamos e implementamos arquitecturas de event sourcing y CQRS como parte de nuestras soluciones de aplicaciones a medida y software a medida, integrándolas con pipelines de datos, automatización y prácticas de ciberseguridad para entornos exigentes. Si buscas un partner para crear plataformas robustas, descubre cómo abordamos el desarrollo de aplicaciones a medida y software a medida con estas técnicas.
Además, nuestros equipos despliegan y operan estos sistemas en nubes públicas con observabilidad avanzada y seguridad de extremo a extremo. Optimizamos costes y resiliencia con infraestructura como código y flujos CI CD. Si te interesa modernizar tu plataforma con alta disponibilidad y consistencia eventual controlada, revisa nuestros servicios cloud aws y azure.
SEO y servicios de Q2BSTUDIO
Más allá de event sourcing, en Q2BSTUDIO ofrecemos inteligencia artificial e ia para empresas con agentes IA, ciberseguridad y pentesting, servicios inteligencia de negocio con power bi, automatización de procesos y analítica avanzada. Integramos modelos y microservicios con prácticas de seguridad, observabilidad y gobierno de datos, alineados a objetivos de negocio.
Recursos
Repositorio de referencia y demo completa de event sourcing con CQRS, FastAPI y Celery disponible en GitHub. Adáptalo a tu dominio y evoluciona hacia snapshots, outbox y modelos de lectura especializados conforme crezcan tus necesidades.
Cierre
Con este enfoque ya no hay pesadillas de registros perdidos. Podemos decirle a Sarah exactamente cuándo, por qué y quién eliminó su cuenta. La historia está en el stream y la plataforma puede explicarse sola. Así es como pasas de apagar incendios a construir sistemas confiables y listos para crecer, apoyados por prácticas modernas y por un socio experto como Q2BSTUDIO en aplicaciones a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio con power bi y automatización de procesos.