Orivel Orivel
Abrir menú

Diseño de sistema: Servicio de notificaciones en tiempo real

Compara las respuestas de los modelos para esta tarea de benchmark de Diseño de sistemas y revisa puntuaciones, comentarios y ejemplos relacionados.

Inicia sesión o regístrate para usar me gusta y favoritos. Registrarse

X f L

Índice

Resumen de la tarea

Géneros de comparación

Diseño de sistemas

Modelo creador de la tarea

Modelos participantes

Modelos evaluadores

Enunciado de la tarea

Eres un ingeniero de software senior encargado de diseñar un sistema de notificaciones en tiempo real para una gran plataforma de redes sociales.

Requisitos del sistema:

  1. Funcionalidad: El sistema debe entregar notificaciones por varias interacciones de usuario, incluyendo nuevos seguidores, "me gusta" en publicaciones, comentarios y mensajes directos.
  2. Entrega en tiempo real: Las notificaciones deben entregarse a usuarios en línea con muy baja latencia (menos de 2 segundos).
  3. **Compatibilidad...
Mostrar más

Eres un ingeniero de software senior encargado de diseñar un sistema de notificaciones en tiempo real para una gran plataforma de redes sociales.

Requisitos del sistema:

  1. Funcionalidad: El sistema debe entregar notificaciones por varias interacciones de usuario, incluyendo nuevos seguidores, "me gusta" en publicaciones, comentarios y mensajes directos.
  2. Entrega en tiempo real: Las notificaciones deben entregarse a usuarios en línea con muy baja latencia (menos de 2 segundos).
  3. Compatibilidad multiplataforma: El sistema debe soportar el envío de notificaciones vía push móvil (iOS/Android), notificaciones en navegadores web y correo electrónico.
  4. Historial de notificaciones: Los usuarios deben poder ver un historial de sus notificaciones recientes (p. ej., los últimos 100).
  5. Escalabilidad: El sistema debe manejar 100 millones de usuarios activos diarios (DAU), con cada usuario generando un promedio de 10 eventos que desencadenan notificaciones por día. También debe manejar picos de carga de 5x el tráfico promedio.
  6. Confiabilidad: El sistema debe ser altamente disponible (99.9% de tiempo de actividad) y resiliente a fallos.

Tu tarea:
Proporciona un plan de diseño de sistema detallado. Tu plan debe cubrir los siguientes aspectos:

  • Una visión arquitectónica de alto nivel.
  • Componentes clave y sus responsabilidades (p. ej., API Gateway, Servicio de Notificaciones, Servicio de Fan-out, etc.).
  • Modelo de datos y elección de bases de datos (p. ej., para almacenar preferencias de usuario, historial de notificaciones). Justifica tus elecciones.
  • Recomendaciones de pila tecnológica (p. ej., colas de mensajes, capas de caché, servicios de notificaciones push).
  • Estrategias para asegurar escalabilidad, baja latencia y alta disponibilidad.
  • Una discusión sobre los posibles cuellos de botella y los compromisos realizados en tu diseño.

Información complementaria

No se requiere contexto externo para esta tarea.

Política de evaluación

Una respuesta de alta calidad presentará un diseño de sistema claro, coherente y técnicamente sólido. La evaluación debe centrarse en los siguientes criterios:

  1. Solidez arquitectónica: La arquitectura propuesta debe ser lógica y adecuada para un sistema de notificaciones en tiempo real a gran escala. Los roles de los componentes clave deben estar claramente definidos.
  2. Justificación tecnológica: La elección de tecnologías (bases de datos, colas de mensajes, cachés, etc.) debe estar bien justificada, e...
Mostrar más

Una respuesta de alta calidad presentará un diseño de sistema claro, coherente y técnicamente sólido. La evaluación debe centrarse en los siguientes criterios:

  1. Solidez arquitectónica: La arquitectura propuesta debe ser lógica y adecuada para un sistema de notificaciones en tiempo real a gran escala. Los roles de los componentes clave deben estar claramente definidos.
  2. Justificación tecnológica: La elección de tecnologías (bases de datos, colas de mensajes, cachés, etc.) debe estar bien justificada, explicando por qué encajan bien en su función específica dentro del sistema.
  3. Escalabilidad y confiabilidad: El diseño debe incluir estrategias concretas para manejar la carga especificada (100M DAU, picos de 5x) y cumplir el requisito de alta disponibilidad. Esto incluye discutir conceptos como escalado horizontal, balanceo de carga, particionado de datos y redundancia.
  4. Discusión de compromisos: Una respuesta superior no solo presentará una solución, sino que también discutirá los compromisos involucrados. Por ejemplo, puede comparar las compensaciones entre distintos tipos de bases de datos (SQL vs. NoSQL) o modelos de consistencia.
  5. Integralidad: La respuesta debe abordar todas las partes del enunciado, incluyendo el modelo de datos, soporte multiplataforma y posibles cuellos de botella.

Respuestas

SERVICIO DE NOTIFICACIÓN EN TIEMPO REAL — PLAN DE DISEÑO DEL SISTEMA

  1. RESUMEN DE REQUISITOS Y ESTIMACIÓN DE CAPACIDAD

Matemáticas del tráfico:

  • 100M DAU x 10 eventos/día = 1000 millones de eventos desencadenantes de notificaciones por día.
  • Promedio = 1000 millones / 86 400 ≈ 11 600 eventos/segundo. Pico a 5x ≈ 58 000 eventos/segundo.
  • Multiplicador de fan-out: la mayoría de los eventos (me gusta, comentario, seguir, DM) se dirigen exactamente a un destinatario, por lo que el fan-out es ~1:1. Sin embargo, los eventos de cuentas con muchos seguidores (una celebridad publicando) pueden distribuirse a millone...
Mostrar respuesta completa

SERVICIO DE NOTIFICACIÓN EN TIEMPO REAL — PLAN DE DISEÑO DEL SISTEMA

  1. RESUMEN DE REQUISITOS Y ESTIMACIÓN DE CAPACIDAD

Matemáticas del tráfico:

  • 100M DAU x 10 eventos/día = 1000 millones de eventos desencadenantes de notificaciones por día.
  • Promedio = 1000 millones / 86 400 ≈ 11 600 eventos/segundo. Pico a 5x ≈ 58 000 eventos/segundo.
  • Multiplicador de fan-out: la mayoría de los eventos (me gusta, comentario, seguir, DM) se dirigen exactamente a un destinatario, por lo que el fan-out es ~1:1. Sin embargo, los eventos de cuentas con muchos seguidores (una celebridad publicando) pueden distribuirse a millones de destinatarios; trátelos como una ruta separada de "fan-out masivo". Suponga una entrega pico efectiva de 80 000–100 000 notificaciones/segundo, incluidas las campañas masivas.
  • Almacenamiento: historial de las últimas 100 notificaciones por usuario. Suponga ~400 bytes por fila -> 100 x 400 B = 40 KB/usuario -> 100M de usuarios ≈ 4 TB de historial activo, más un factor de replicación de 3 ≈ 12 TB. Se puede fragmentar trivialmente.
  • Conexiones: suponga que entre el 20% y el 25% de los DAU están en línea simultáneamente en el pico ≈ 20–25M de conexiones WebSocket activas. Con ~100 000 conexiones por nodo de puerta de enlace (Linux ajustado, epoll), eso son 200–250 nodos más margen.

Objetivos no funcionales:

  • Latencia p99 de extremo a extremo inferior a 2 segundos para usuarios en línea (medida desde la ingesta de eventos hasta la confirmación del cliente).
  • Disponibilidad del 99,9 % = ~43 minutos de inactividad por mes.
  • Entrega al menos una vez con deduplicación idempotente en el lado del cliente/servidor.
  1. ARQUITECTURA DE ALTO NIVEL

El diseño es un pipeline impulsado por eventos con una clara división entre la ruta de ingesta (rápida, duradera, optimizada para escritura) y la ruta de entrega (específica del canal, reintentable).

Flujo:
Servicios productores (Servicio de Publicaciones, Servicio de Gráfico Social, Servicio de Comentarios, Servicio de Mensajería)
-> API/Puerta de Enlace de Notificaciones (gRPC + REST, autenticación, limitación de velocidad, validación de esquemas, clave de idempotencia)
-> Tópico de Kafka notification.events (particionado por recipient_user_id cuando se conoce, de lo contrario por actor_id)
-> Servicio de Fan-out (resuelve destinatarios, expande eventos de celebridades, aplica reglas de agregación)
-> Tópico de Kafka notification.deliveries (un mensaje por destinatario)
-> Servicio de Preferencias y Políticas (búsqueda en línea a través de caché: opt-ins de canal, horas de silencio, silenciar/bloquear, resumen vs. instantáneo)
-> El Enrutador/Distribuidor escribe en tópicos por canal:
deliver.websocket, deliver.mobile_push, deliver.web_push, deliver.email
-> Trabajadores de Canal:
Distribuidor WebSocket -> Búsqueda en el Registro de Conexiones -> nodo de Puerta de Enlace en Tiempo Real -> cliente
Trabajador de Push Móvil -> APNs (iOS) / FCM (Android)
Trabajador de Push Web -> Protocolo VAPID/Web Push a través de servicios de push del navegador
Trabajador de Correo Electrónico -> SES / SendGrid, con renderizado de plantillas y lotes de resúmenes
-> En paralelo, un consumidor de Escritor de Historial persiste cada entrega en la tienda de Historial de Notificaciones e incrementa los contadores de no leídos.

Transversales: Servicio de Plantillas, Registro de Dispositivos, Registro de Conexiones, Tienda de Deduplicación, Colas de Mensajes Fallidos (DLQ), pila de Observabilidad y un plano de Administración/Análisis que consume los mismos flujos de Kafka.

  1. COMPONENTES CLAVE Y RESPONSABILIDADES

Puerta de Enlace de API de Notificaciones

  • Punto de entrada único para productores internos (gRPC, esquemas protobuf en un registro) y para APIs de lectura de clientes (REST/GraphQL para historial, marcar como leído, preferencias).
  • Responsabilidades: autenticación (servicio a servicio mTLS, JWT para clientes), limitación de velocidad/cuotas por inquilino y por productor, validación de solicitudes, aceptación de claves de idempotencia y adición duradera inmediata a Kafka. Devuelve 202 Accepted rápidamente; no realiza ningún trabajo de entrega en línea.

Ingesta de Eventos / Kafka

  • Registro duradero y reproducible. notification.events con ~256 particiones, factor de replicación 3, min.insync.replicas=2, acks=all, retención de 7 días para recuperación de incidentes y reproducción.
  • Proporciona contrapresión y almacenamiento en búfer naturales para el pico 5x, desacoplando a los productores de los proveedores externos lentos.

Servicio de Fan-out

  • Resuelve un evento en una lista de destinatarios. Para eventos 1:1, es un pase directo. Para eventos 1:N (nueva publicación para seguidores, actividad de hilo grupal), pagina el Servicio de Gráfico Social y emite mensajes de destinatarios en lotes.
  • Estrategia de fan-out híbrida: basada en push (escribir por destinatario) para cuentas normales; basada en pull/perezosa para cuentas por encima de un umbral de seguidores (por ejemplo, 1M+), donde se escribe un único "marcador de feed" y los destinatarios se materializan al leer. Esto evita que un evento de celebridad cree una tormenta de escritura de 50 millones de mensajes en la ruta activa.
  • Limita la velocidad de las expansiones masivas a un tópico de Kafka separado de baja prioridad para que nunca agoten las notificaciones interactivas.
  • Aplica agregación/coalescencia: "Alice y otras 24 personas le dieron me gusta a tu publicación" en lugar de 25 filas, utilizando una ventana deslizante corta (por ejemplo, 30–60 s) con clave (destinatario, post_id, tipo) en Redis.

Servicio de Preferencias y Políticas

  • Almacena y sirve preferencias de canal por usuario, opt-ins a nivel de categoría, horas de silencio con zona horaria, configuraciones a nivel de dispositivo, listas de silenciar/bloquear y banderas de consentimiento legal (GDPR/CAN-SPAM).
  • La ruta de lectura se almacena en caché en Redis con invalidación write-through; objetivo de búsqueda p99 inferior a 5 ms. Fuente de verdad en una tienda relacional.
  • Aplica limitación de frecuencia (por ejemplo, máximo N pushes/hora por usuario) para proteger la experiencia del usuario y las cuotas del proveedor.

Enrutador / Distribuidor

  • Mapea una entrega aprobada en elementos de trabajo específicos del canal. Decide "solo en la aplicación + WebSocket si está en línea; de lo contrario, push móvil" utilizando el Registro de Conexiones, y programa resúmenes de correo electrónico en lugar de envíos instantáneos cuando las preferencias lo indican.

Puerta de Enlace en Tiempo Real (capa WebSocket)

  • Nivel con estado que mantiene conexiones WebSocket persistentes (fallback: Server-Sent Events, luego long polling).
  • Al conectar: autenticar, registrar (user_id, device_id) -> gateway_node_id en el Registro de Conexiones (Redis Cluster, TTL + actualización de heartbeat), luego enviar cualquier historial pendiente.
  • Al entregar: el distribuidor busca el nodo, envía a través de un flujo gRPC interno o un canal Kafka/Redis Pub/Sub por nodo; la puerta de enlace escribe en el socket y espera la confirmación del cliente.
  • Heartbeats cada 30 s; los heartbeats perdidos eliminan la entrada del registro y las notificaciones futuras vuelven automáticamente al push móvil.

Trabajadores de Canal

  • Trabajador de Push Móvil: lotes a APNs (HTTP/2 multiplexado, autenticación basada en tokens) y FCM. Maneja límites de concurrencia por proveedor, retroceso exponencial con jitter, y elimina tokens de dispositivo no válidos/no registrados del Registro de Dispositivos.
  • Trabajador de Push Web: protocolo Web Push con claves VAPID y cifrado de carga útil.
  • Trabajador de Correo Electrónico: renderiza plantillas, admite resúmenes instantáneos, horarios y diarios; maneja rebotes/quejas a través de webhooks del proveedor y mantiene una lista de supresión.
  • Todos los trabajadores son consumidores idempotentes con clave notification_id y escriben el estado terminal de vuelta a un tópico delivery.status.

Escritor de Historial y Ruta de Lectura

  • Consumidor que persiste notificaciones y mantiene contadores de no leídos en Redis (contador autoritativo reconciliado periódicamente desde la tienda).
  • La API de lectura sirve las últimas 100 notificaciones de la tienda de historial, con una caché de Redis de la primera página por usuario para lecturas típicas de menos de 10 ms.

Servicios de Soporte

  • Servicio de Plantillas: plantillas localizadas y versionadas con interpolación de variables; desacopla los cambios de copia de los despliegues de código.
  • Registro de Dispositivos: token_dispositivo, plataforma, version_app, locale, timezone, last_seen.
  • Tienda de Deduplicación: Redis con un TTL de 24 h en (producer_id, idempotency_key) para que al menos una vez se comporte como efectivamente una vez.
  • Programador: para notificaciones retrasadas/programadas y ventanas de resumen (colas agrupadas por tiempo en conjuntos ordenados de Redis o un programador dedicado como una escalera de tópicos de retraso de Kafka).
  • DLQ + Replayer: mensajes venenosos estacionados y reproducibles después de las correcciones.
  1. MODELO DE DATOS Y ELECCIONES DE BASE DE DATOS

a) Historial de Notificaciones — Cassandra (o ScyllaDB / DynamoDB)
Tabla: notifications_by_user

  • Clave de partición: user_id
  • Clave de agrupación: created_at DESC, notification_id
  • Columnas: type, actor_id(s), target_type, target_id, aggregated_count, preview_text, image_url, deep_link, read_at, channels_sent, created_at
  • TTL: 90 días; la aplicación limita las lecturas a 100 filas.
    Justificación: el patrón de acceso es una clave de partición única y bien conocida con una rebanada ordenada por tiempo — exactamente el punto fuerte de Cassandra. Ofrece escalabilidad lineal de escritura (necesitamos 60–100K escrituras/segundo sostenidas), replicación maestra sin maestro multiregión para disponibilidad, consistencia ajustable (escribir QUORUM/LOCAL_QUORUM, leer LOCAL_ONE para el feed), y TTL nativo para la retención. No necesitamos uniones ni transacciones de varias filas aquí, por lo que una tienda relacional solo agregaría dolor de fragmentación y riesgo de amplificación de escritura.

b) Contadores de no leídos y primera página activa — Redis Cluster

  • Contador entero unread:{user_id}; lista JSON en caché notif:page0:{user_id}.
    Justificación: los contadores se leen en cada apertura de aplicación (QPS extremadamente alto, bajo valor por lectura) y deben ser de milisegundos de un solo dígito. Redis absorbe esto de manera económica; los contadores de Cassandra son comparativamente costosos y propensos a errores. Los contadores se reconcilian asincrónicamente para que la deriva se autocorrija.

c) Preferencias de usuario y tokens de dispositivo — PostgreSQL (fragmentado por user_id) con caché de lectura anticipada de Redis
Tablas: user_preferences(user_id, category, channel, enabled, quiet_hours_start, quiet_hours_end, timezone, updated_at), devices(device_id, user_id, platform, push_token, locale, last_seen, active), suppression_list(email, reason, created_at).
Justificación: estos datos son de bajo volumen, con muchas lecturas, relacionales (usuarios -> dispositivos -> configuraciones por categoría), y se benefician de transacciones y restricciones para la corrección y la auditoría (los registros de consentimiento tienen peso de cumplimiento). El volumen es lo suficientemente pequeño (~100M de filas) como para fragmentarlo trivialmente y almacenarlo en caché casi por completo.

d) Registro de Conexiones — Redis Cluster

  • conn:{user_id} -> conjunto de {device_id, gateway_node_id, connected_at}, TTL 90s refrescado por heartbeat.
    Justificación: efímero, rotación extremadamente alta, debe ser rápido; la durabilidad no es necesaria porque una entrada perdida se degrada con gracia a fallback de push.

e) Deduplicación / idempotencia — Redis con TTL, respaldado por nada (la pérdida solo arriesga un duplicado raro).

f) Plantillas y configuración — PostgreSQL + almacenamiento de objetos para activos, almacenado en caché en el borde.

g) Analítica — eventos transmitidos desde Kafka a un data lake (S3/Parquet) y data warehouse (Snowflake/BigQuery) para informes de tasas de entrega, tasas de apertura y latencia; ClickHouse para dashboards operativos casi en tiempo real.

  1. RECOMENDACIONES DE STACK TECNOLÓGICO
  • Lenguaje/runtime: Go para la puerta de enlace, la puerta de enlace en tiempo real y los trabajadores (goroutines y baja memoria por conexión se adaptan a millones de sockets); Java/Kotlin aceptable para agregación intensiva de Kafka Streams.
  • Mensajería: Apache Kafka (gestionado: MSK/Confluent) como la columna vertebral; tópicos separados por canal y por clase de prioridad. Kafka Streams o Flink para agregación/coalescencia con ventanas.
  • Transporte en tiempo real: WebSocket sobre TLS con SSE y fallbacks de long-poll; balanceo de carga NLB/L4 con vaciado de conexión; el enrutamiento pegajoso no es necesario ya que el registro almacena la identidad del nodo.
  • Almacenamiento en caché: Redis Cluster (o Elasticache/MemoryDB) para contadores, preferencias, registro, deduplicación, límites de velocidad.
  • Almacenes de datos: Cassandra/ScyllaDB para historial; PostgreSQL (Aurora) para preferencias/dispositivos; S3 + data warehouse para analítica.
  • Proveedores de push: APNs, FCM, Web Push (VAPID); correo electrónico a través de SES con SendGrid como proveedor secundario detrás de una capa de abstracción de proveedor para failover.
  • Infraestructura: Kubernetes con HPA/KEDA escalando en el lag del consumidor de Kafka (no solo CPU), mesh de servicios Envoy/Istio para mTLS y reintentos, Terraform para IaC.
  • Observabilidad: rastreo OpenTelemetry (id de rastreo propagado desde el evento productor hasta la confirmación del cliente), métricas Prometheus + Grafana, logs estructurados en Loki/ELK, alertas PagerDuty sobre SLOs.
  • Bibliotecas de resiliencia: disyuntores y bulkheads por proveedor externo, limitadores de velocidad de cubo de tokens, retroceso exponencial con jitter.
  1. ESTRATEGIAS DE ESCALABILIDAD, LATENCIA Y DISPONIBILIDAD

Escalabilidad

  • Todos los componentes sin estado (API, fan-out, enrutador, trabajadores) escalan horizontalmente; el número de particiones de Kafka es el límite de paralelismo, por lo que se deben aprovisionar particiones para 5–10 veces el pico actual desde el primer día (reparticionar es operacionalmente doloroso).
  • Autoscale en lag del consumidor con KEDA para que un pico de 5x active el escalado en segundos; mantenga un búfer cálido de 30–40% de margen porque el escalado no es instantáneo.
  • Fragmentar por user_id consistentemente en Cassandra, Postgres y Redis para que los datos de un solo usuario estén co-ubicados y la mitigación de particiones calientes sea uniforme.
  • Carriles de prioridad: las notificaciones interactivas (DM, comentario en tu publicación) usan un tópico de alta prioridad con grupos de consumidores dedicados; el fan-out masivo/marketing/celebridad usa un carril de baja prioridad limitado. Esto garantiza el SLO de 2 segundos para las notificaciones que los usuarios realmente notan.
  • Manejo de celebridades/claves calientes a través del fan-out híbrido push/pull descrito anteriormente, más claves de partición con sal para objetivos extremadamente calientes.

Baja latencia (p99 inferior a 2 s)

  • La ruta crítica es intencionalmente corta: adición de API -> Kafka -> fan-out -> acierto de caché de preferencias -> búsqueda de registro -> escritura WebSocket. Todas las búsquedas son en Redis (menos de 5 ms); ninguna escritura de base de datos síncrona bloquea la entrega.
  • La persistencia del historial y la analítica son asíncronas, fuera de la ruta de entrega.
  • Productores de Kafka ajustados con linger.ms=5 y compresión (lz4) para equilibrar la lotificación con la latencia; los consumidores usan confirmación manual después del procesamiento.
  • Despliegue multiregión con usuarios anclados a la región más cercana para reducir el RTT; las conexiones WebSocket terminan en los bordes regionales.
  • Las ventanas de agregación son configurables por tipo y se deshabilitan para tipos críticos de latencia como los DM.
  • Sondas sintéticas continuas miden la latencia real de extremo a extremo por región y por canal.

Alta disponibilidad (99,9 % +)

  • Sin puntos únicos de fallo: multi-AZ para cada nivel, Kafka RF=3 con min.insync.replicas=2, Cassandra RF=3 con escrituras LOCAL_QUORUM, Postgres con standby síncrono y failover automatizado.
  • Multiregión activa-activa para los niveles en tiempo real y de entrega; Cassandra replica entre regiones de forma asíncrona, Postgres usa réplicas de lectura regionales con una región de escritura designada.
  • Degradación elegante: si la ruta WebSocket no está saludable, recurre al push móvil; si la caché de preferencias está caída, recurre a Postgres y luego a valores predeterminados conservadores; si las escrituras de Cassandra fallan, continúa entregando en tiempo real y reproduce las escrituras de historial desde Kafka después.
  • Reintentos con retroceso exponencial más jitter, intentos limitados, luego DLQ con alertas y una herramienta de reproducción.
  • Disyuntores por proveedor externo para que una interrupción de APNs no agote los hilos de trabajo y detenga el correo electrónico.
  • Entrega al menos una vez más deduplicación de notification_id en el servidor y el cliente; los clientes también se deduplican al reconectarse al reproducir el historial pendiente.
  • Prácticas de confiabilidad: ejercicios de caos/juegos (matar un nodo de puerta de enlace y verificar el fallback de push), pruebas de carga al 5x del pico, despliegues blue-green y canary, flags de funciones para interruptores por canal, descarte de contrapresión de tráfico de baja prioridad antes que de alta prioridad.
  1. CUELLOS DE BOTELLA Y COMPENSACIONES

Posibles cuellos de botella

  • Proveedores de terceros (APNs/FCM/correo electrónico): el techo más difícil, ya que el rendimiento no depende de nosotros. Mitigar con agrupación de conexiones sobre HTTP/2, lotificación, limitadores de velocidad por proveedor, failover multi-proveedor para correo electrónico y suavizado basado en colas de picos.
  • Fan-out de celebridades: una sola publicación puede generar decenas de millones de entregas. Mitigado por push/pull híbrido, carriles masivos limitados y agregación.
  • Nivel de conexión WebSocket: memoria y descriptores de archivo por nodo, más reconexiones de "rebaño thundering" después de un despliegue o un problema de red. Mitigar con límites de kernel ajustados, reconexión escalonada con jitter y retroceso exponencial forzado en el lado del cliente, y vaciado lento de conexiones durante los despliegues.
  • Claves calientes de Redis: la clave de agregación de una publicación viral o un contador compartido. Mitigar con salting de claves, cachés locales en memoria con TTL cortos y fragmentación en el lado del cliente.
  • Amplificación de escritura de Cassandra y presión de compactación a 100K escrituras/segundo. Mitigar con compactación de ventana de tiempo (TWCS) adecuada para datos TTL de series temporales, y al no almacenar tipos de notificación de bajo valor en el historial en absoluto.
  • Desviación de particiones de Kafka si se particiona por una clave de baja cardinalidad; siempre particionar por recipient_user_id en el tópico de entrega.

Compensaciones explícitas

  • Al menos una vez sobre exactamente una vez: exactamente una vez a través de proveedores externos heterogéneos es impráctico y costoso. Aceptamos duplicados raros y los resolvemos con claves de idempotencia y deduplicación en el lado del cliente — más barato y mucho más disponible.
  • Consistencia eventual para contadores e historial sobre consistencia fuerte: una insignia de no leído que está momentáneamente desfasada es aceptable; la latencia de varios segundos para garantizarla no lo es. Los trabajos de reconciliación limitan la deriva.
  • Persistencia políglota sobre una sola base de datos: esto aumenta la superficie operativa (tres almacenes de datos más Redis) pero cada carga de trabajo obtiene el motor correcto. Un solo clúster de Postgres se convertiría en el cuello de botella con 1000 millones de escrituras/día; un solo clúster de Cassandra haría que las auditorías de preferencias y consentimiento fueran incómodas.
  • Fan-out basado en push para la mayoría de los usuarios, basado en pull para celebridades: complejidad de código añadida, pero es la única forma de evitar tormentas de escritura ilimitadas.
  • La agregación mejora la experiencia del usuario y reduce drásticamente el volumen de entrega, pero agrega hasta una ventana de latencia para los tipos agregables. Mantenemos las ventanas cortas y eximimos los DM.
  • Multiregión activa-activa aumenta el costo e introduce sutilezas de consistencia entre regiones, justificado por los objetivos de disponibilidad y latencia. Si el presupuesto fuera limitado, una postura de región única con standby cálido aún cumpliría el 99,9% pero con un RTO más largo.
  • Kafka sobre una cola gestionada más simple (SQS): más carga operativa, pero necesitamos reproducción, particiones ordenadas por clave, grupos de consumidores independientes múltiples y retención de 7 días para recuperación de incidentes.
  • Almacenar solo las últimas ~100 notificaciones con un TTL de 90 días intercambia la completitud del archivo por costo y rendimiento de lectura; los datos a largo plazo viven en el data lake de analítica si alguna vez se necesitan.
  1. PLAN DE DESPLIEGUE (POR FASES)

Fase 1: API de Ingesta + Kafka + escritor de historial + API de lectura (solo notificaciones en la aplicación). Establece la columna vertebral duradera.
Fase 2: Puerta de enlace en tiempo real, registro de conexiones, contadores de no leídos, entrega WebSocket con fallback de push.
Fase 3: Trabajadores de push móvil y push web, registro de dispositivos, servicio de preferencias y horas de silencio.
Fase 4: Instantáneo de correo electrónico + resúmenes, servicio de plantillas, manejo de supresión.
Fase 5: Agregación/coalescencia, fan-out híbrido de celebridades, limitación de frecuencia.
Fase 6: Multiregión activa-activa, pruebas de caos, validación de carga 5x, dashboards de SLO y presupuestos de error.

  1. MÉTRICAS CLAVE Y SLOs
  • Latencia p50/p95/p99 de extremo a extremo por canal (SLO: p99 inferior a 2 s para WebSocket).
  • Tasa de éxito de entrega por canal; tasas de error del proveedor y tasa de invalidación de tokens.
  • Lag del consumidor de Kafka por tópico (señal principal de escalado automático y paginación).
  • Conteo de conexiones WebSocket, tasa de rotación y tasa de confirmación.
  • Deriva del contador de no leídos detectada por reconciliación.
  • Profundidad y antigüedad de la DLQ.
  • Disponibilidad por API medida desde la perspectiva del cliente, rastreada contra un presupuesto de error mensual.

Resultado

#1 | Ganador

Votos ganadores

3 / 3

Puntuación media

92
Modelos evaluadores OpenAI GPT-5.6

Puntuación total

91

Comentario general

La respuesta A es un diseño sobresaliente y muy concreto con estimaciones de capacidad cuantificadas, rutas de ingesta y entrega claramente separadas, modelos de datos detallados, carriles de prioridad, fan-out híbrido, resiliencia específica del canal y medidas accionables de disponibilidad y latencia. Sus características más sólidas son la configuración operativa explícita, la planificación de capacidad de WebSocket, las rutas de degradación por fallos y un análisis inusualmente exhaustivo de cuellos de botella y compensaciones. La principal debilidad es que no utiliza explícitamente un patrón de publicación de eventos transaccional o de outbox en los servicios de origen, dejando una brecha potencial entre la transacción comercial originadora y la ingesta duradera en Kafka. Algunos detalles de consistencia multirregional también se tratan a un nivel alto.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
88

El pipeline duradero basado en eventos, los temas de fan-out y canal separados, el enrutamiento de políticas, el registro de conexiones, la pasarela en tiempo real, el escritor asíncrono de historial y los carriles de prioridad forman una arquitectura lógica con responsabilidades claras. La brecha principal es la falta de un outbox explícito en el servicio de origen, por lo que una transacción comercial podría teóricamente confirmarse sin que su evento de notificación llegue a la API de ingesta. La relación entre un registro de historial lógico y múltiples entregas a canales también podría especificarse con mayor precisión.

Integridad

Peso 20%
92

Aborda todas las áreas solicitadas y va más allá de ellas con estimaciones de capacidad, dimensionamiento de conexiones, esquemas detallados, comportamiento del canal, controles de cumplimiento, observabilidad, fases de implementación y SLOs medibles. Las omisiones menores incluyen la publicación transaccional de origen y una explicación más exacta de cómo el almacén aplica una política estricta de los últimos 100 en lugar de simplemente limitar las lecturas y aplicar TTL.

Análisis de compromisos

Peso 20%
93

La respuesta examina explícita y correctamente la entrega al menos una vez frente a exactamente una vez, la consistencia eventual frente a la fuerte, la persistencia políglota, el fan-out push frente a pull, la latencia de agregación, el costo multirregional, Kafka frente a colas más simples y los límites de retención. Las compensaciones están vinculadas a los requisitos y acompañadas de estrategias de mitigación en lugar de enumerarse de forma abstracta.

Escalabilidad y fiabilidad

Peso 20%
92

El diseño cuantifica el tráfico promedio y pico, estima la capacidad concurrente de WebSocket, escala los consumidores por el lag de Kafka, reserva margen de calentamiento, aísla el tráfico prioritario, maneja el fan-out de celebridades y especifica replicación multizona, configuraciones de quorum, reintentos, DLQs, disyuntores, rutas de respaldo, pruebas de carga y ejercicios de caos. El comportamiento de datos activo-activo regional y la atomicidad de eventos de origen requieren más detalles.

Claridad

Peso 10%
88

A pesar de su extensión, la organización numerada, el flujo explícito, los componentes nombrados, los esquemas y las secciones separadas para escalado, disponibilidad, cuellos de botella, implementación y métricas hacen que el plan sea fácil de navegar. Algunas afirmaciones son demasiado confiadas o comprimidas, como llamar trivial al sharding de 100 millones de filas, y algunas semánticas de canal/historial podrían formularse con más cuidado.

Modelos evaluadores Google Gemini 2.5 Pro

Puntuación total

96

Comentario general

Una respuesta sobresaliente que ejemplifica un diseño de sistemas de nivel senior. Es integral, está bien estructurada, se basa en datos cuantitativos y demuestra una profunda comprensión de las compensaciones y las realidades operativas. El diseño es muy detallado, con elecciones tecnológicas específicas y estrategias concretas para la escalabilidad y la fiabilidad. La inclusión de un plan de implementación por fases y una sección dedicada a métricas/SLOs lo eleva más allá de un diseño puramente teórico, haciéndolo parecer un documento listo para producción.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
95

La arquitectura es excepcionalmente sólida, detallada y está bien articulada. El flujo impulsado por eventos es claro y la separación de responsabilidades entre componentes como la API, el servicio Fan-out y los trabajadores específicos del canal es excelente. La inclusión de una estrategia híbrida de fan-out push/pull para cuentas de celebridades demuestra una comprensión sofisticada del espacio del problema.

Integridad

Peso 20%
100

Esta respuesta es excepcionalmente completa. Aborda cada parte de la pregunta con gran detalle y va más allá al incluir una estimación detallada de la capacidad, un plan de implementación por fases y una sección dedicada a métricas clave y SLOs. Este nivel de detalle es lo que se esperaría del documento de diseño de un ingeniero senior.

Análisis de compromisos

Peso 20%
95

La discusión de los cuellos de botella y las compensaciones es excelente. No solo identifica problemas potenciales, sino que también enumera explícitamente las concesiones de diseño realizadas, como elegir la entrega 'al menos una vez' sobre 'exactamente una vez' y usar persistencia políglota. El razonamiento es agudo, conciso y demuestra una perspectiva de ingeniería madura.

Escalabilidad y fiabilidad

Peso 20%
95

Las estrategias de escalabilidad y fiabilidad son detalladas y concretas. Menciona enfoques específicos como el escalado automático basado en el retraso de los consumidores de Kafka con KEDA, el uso de carriles de prioridad para diferentes tipos de tráfico y la implementación de una escalera de degradación elegante. La inclusión de prácticas como la ingeniería del caos muestra un enfoque proactivo hacia la fiabilidad.

Claridad

Peso 10%
95

La respuesta es excepcionalmente clara y está bien estructurada. El uso de secciones numeradas, un diagrama de flujo basado en texto al principio y puntos concisos hace que la gran cantidad de información técnica sea muy fácil de seguir y digerir. El flujo lógico desde los requisitos hasta las métricas es impecable.

Modelos evaluadores Anthropic Claude Fable 5

Puntuación total

89

Comentario general

La respuesta A es un documento de diseño de nivel de personal casi completo. Comienza con cálculos concretos de capacidad (eventos/segundo, dimensionamiento de almacenamiento, recuentos de conexiones WebSocket y estimaciones de nodos), luego recorre una división clara entre ingesta y entrega con detalles de configuración específicos (recuentos de particiones de Kafka, configuraciones de replicación, confirmaciones, retención), un fan-out híbrido push/pull para cuentas de celebridades, carriles de prioridad para proteger el SLO de 2 segundos, modelos de datos por tienda con justificaciones explícitas, una escalera de degradación elegante, prácticas de caos/juegos de guerra, un plan de implementación por fases y métricas de SLO. La sección de compensaciones es excepcional: cada elección (al menos una vez frente a exactamente una vez, persistencia políglota, Kafka frente a SQS, costo de latencia de agregación, costo multirregional) se presenta con la alternativa y por qué fue rechazada. Debilidades menores: la densidad puede hacer que la lectura sea pesada y no discute el patrón outbox para la durabilidad de eventos en el lado del productor.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
90

Arquitectura sobresaliente: división clara de ingesta/entrega, fan-out híbrido push/pull con un umbral concreto de seguidores, carriles de prioridad que garantizan el SLO de 2 segundos para eventos interactivos, nivel de conexión dimensionado (20-25M sockets, ~100K por nodo) y topología específica de Kafka (256 particiones, RF=3, min.insync.replicas=2, retención de 7 días). Las responsabilidades de los componentes son precisas y la ruta crítica se mantiene deliberadamente libre de escrituras síncronas en la base de datos.

Integridad

Peso 20%
90

Cubre todos los requisitos del prompt más extras: estimación de capacidad con cálculos de almacenamiento, modelos de datos completos para seis tiendas con justificaciones, los cuatro canales, resúmenes, cumplimiento (GDPR/CAN-SPAM, listas de supresión), observabilidad con SLOs, un plan de implementación por fases y una sección dedicada a cuellos de botella/compensaciones. Nada del prompt falta.

Análisis de compromisos

Peso 20%
90

Sección de compensaciones excepcional: cada decisión nombra la alternativa y por qué fue rechazada (al menos una vez vs exactamente una vez, persistencia políglota vs base de datos única, Kafka vs SQS, fan-out push vs pull, costo activo-activo vs standby en caliente, latencia de agregación vs volumen). Las compensaciones se integran en las justificaciones a lo largo del documento, no se limitan a una sola sección.

Escalabilidad y fiabilidad

Peso 20%
90

Concreto y cuantificado: justificación de la sobreaprovisionamiento de particiones, KEDA autoscaling por lag del consumidor con un 30-40% de margen en caliente, claves 'hot keys' saladas, compactación TWCS para la tasa de escritura, configuraciones explícitas de replicación y quorum de Cassandra/Postgres/Kafka, escalera de degradación elegante, disyuntores por proveedor, pruebas de caos y validación de carga 5x, y herramientas de repetición de DLQ. Vincula directamente los mecanismos a los objetivos de 100M DAU / 5x pico / 99.9%.

Claridad

Peso 10%
83

Excelente estructura numerada desde los requisitos hasta la implementación y las métricas; el diagrama de flujo en forma de texto facilita el seguimiento del pipeline. La densidad de detalles ocasionalmente hace que las secciones sean pesadas, pero los encabezados y el formato consistente las mantienen navegables.

Respuesta B: OpenAI GPT-5.5

Arquitectura de alto nivel:

El sistema está impulsado por eventos. Servicios de productos como Servicio de Seguimiento, Servicio de Publicaciones, Servicio de Comentarios, Servicio de Reacciones y Servicio de Mensajería Directa publican eventos que activan notificaciones en un bus de mensajes duradero. Un Pipeline de Notificaciones consume estos eventos, los enriquece, aplica preferencias de usuario y reglas de deduplicación, persiste los registros de notificaciones y dirige los trabajos de entrega a trabajadores de entrega específicos del canal para notificaciones en tiempo real por websocket/web push, notifica...

Mostrar respuesta completa

Arquitectura de alto nivel:

El sistema está impulsado por eventos. Servicios de productos como Servicio de Seguimiento, Servicio de Publicaciones, Servicio de Comentarios, Servicio de Reacciones y Servicio de Mensajería Directa publican eventos que activan notificaciones en un bus de mensajes duradero. Un Pipeline de Notificaciones consume estos eventos, los enriquece, aplica preferencias de usuario y reglas de deduplicación, persiste los registros de notificaciones y dirige los trabajos de entrega a trabajadores de entrega específicos del canal para notificaciones en tiempo real por websocket/web push, notificaciones móviles y correo electrónico.

Flujo principal:

  1. Ocurre una acción del usuario, por ejemplo, el usuario A da "me gusta" a la publicación del usuario B.
  2. El servicio de origen escribe su propia transacción comercial y luego publica un evento de notificación en un bróker de mensajes utilizando un patrón outbox o un registro de eventos transaccional.
  3. La Ingesta de Notificaciones valida el evento, lo normaliza a un esquema común y le asigna una clave de idempotencia.
  4. La distribución y el enrutamiento determinan los destinatarios, el tipo de notificación, la prioridad, la elegibilidad del canal y si el destinatario está en línea.
  5. El Almacenamiento de Notificaciones escribe la notificación en el historial de notificaciones del destinatario.
  6. Se intenta la entrega en tiempo real a través de conexiones websocket para usuarios web/app en línea y notificaciones push móviles para dispositivos móviles, cuando corresponda.
  7. La entrega de correo electrónico se pone en cola por separado, generalmente con procesamiento por lotes y menor prioridad para evitar el envío de spam a los usuarios.
  8. El estado de entrega, los reintentos, los fallos y las métricas se rastrean de forma asíncrona.

Estimación de escala:

100 millones de DAU por 10 eventos por día equivalen a 1000 millones de eventos que activan notificaciones por día. La tasa promedio de eventos es de aproximadamente 11.600 eventos por segundo. La carga máxima a 5x es de aproximadamente 58.000 eventos por segundo. El diseño debe prever una distribución interna mayor porque un evento puede notificar a varios destinatarios, especialmente en comentarios, menciones, conversaciones grupales o interacciones en vivo. Un objetivo inicial seguro podría ser de 100.000 a 300.000 entregas de notificaciones por segundo en el pico, dependiendo del comportamiento del producto.

Componentes clave y responsabilidades:

  1. Pasarela de API (API Gateway)
    Acepta solicitudes de API externas para leer el historial de notificaciones, marcar notificaciones como leídas, actualizar preferencias de notificación, registrar dispositivos y abrir conexiones websocket. Maneja la autenticación, la limitación de velocidad, el enrutamiento de solicitudes y la protección básica contra abusos.

  2. Productores de eventos
    Los servicios de productos existentes generan eventos de dominio como UserFollowed, PostLiked, CommentCreated, UserMentioned, DirectMessageCreated y MessageReactionAdded. Los productores no deben llamar de forma síncrona a los servicios de entrega de notificaciones porque eso acoplaría la latencia del producto a la infraestructura de notificaciones. Publican en un bus de eventos duradero.

  3. Bus de eventos o cola de mensajes
    Se recomienda un registro distribuido como Apache Kafka o Apache Pulsar. Proporciona alto rendimiento, almacenamiento duradero, capacidad de reproducción, partición, grupos de consumidores y manejo de contrapresión. Los temas pueden separarse por familia de eventos o prioridad, por ejemplo, interacciones sociales, mensajes directos, entrega de notificaciones-alta, entrega de notificaciones-normal, entrega de notificaciones-correo electrónico.

  4. Servicio de Ingesta de Notificaciones
    Consume eventos de producto sin procesar, valida esquemas, filtra notificaciones inválidas/propias cuando corresponda, normaliza las cargas útiles de eventos, genera IDs de notificación y realiza comprobaciones de idempotencia. También enriquece los eventos con metadatos ligeros como el nombre del actor, la referencia del avatar del actor, el ID de la publicación y el tipo de objeto de destino. El enriquecimiento pesado debe minimizarse o realizarse de forma asíncrona para proteger la latencia.

  5. Servicio de Distribución (Fan-out Service)
    Determina los destinatarios y crea tareas de notificación por destinatario. Para eventos uno a uno como un "me gusta", un seguimiento o un mensaje directo, la distribución es simple. Para eventos que involucran a varios destinatarios, como menciones, mensajes grupales o hilos de comentarios, la distribución puede generar muchos registros de entrega. Debe admitir tanto la distribución en escritura (fan-out-on-write) como la distribución en lectura (fan-out-on-read) según la escala.

Enfoque recomendado:
Para notificaciones normales, utilice la distribución en escritura y almacene registros de notificación por destinatario. Esto hace que la recuperación del historial sea rápida y habilita los recuentos de no leídos.
Para entidades de distribución muy alta, como transmisiones de celebridades o grupos masivos, utilice la distribución híbrida: almacene un objeto de notificación compartido y materialícelo solo para usuarios activos o bajo demanda.

  1. Servicio de Preferencias y Políticas
    Almacena y evalúa las preferencias de notificación del usuario, la configuración de privacidad, las relaciones de silencio/bloqueo, las horas de tranquilidad, los permisos del canal, la configuración regional, el estado de opt-in por correo electrónico y la configuración específica de la plataforma. Devuelve la elegibilidad y la prioridad del canal. Las preferencias deben almacenarse en caché de forma agresiva.

  2. Servicio de Almacenamiento de Notificaciones
    Persiste el historial y el estado de las notificaciones. Almacena las últimas N notificaciones, el estado no leído/leído, las marcas de tiempo, el tipo, el actor, las referencias de la entidad y los metadatos de renderizado. Admite consultas como las últimas 100 notificaciones para un usuario, el recuento de no leídos, marcar una como leída, marcar todas como leídas y eliminar/ocultar.

  3. Pasarela de Conexión en Tiempo Real (Realtime Connection Gateway)
    Mantiene conexiones websocket o server-sent event para usuarios web y de aplicaciones móviles en línea. Almacena la presencia de la conexión en un almacén de presencia distribuido. Los trabajadores de entrega dirigen las notificaciones en tiempo real al nodo de la pasarela que tiene la conexión activa del destinatario. Para aplicaciones móviles en segundo plano, la entrega recurre a APNs/FCM.

  4. Servicio de Presencia
    Rastrea si un usuario está en línea, qué dispositivos están conectados y qué nodo de pasarela posee cada conexión. Los datos de presencia son efímeros y deben almacenarse en Redis Cluster u otra caché distribuida de baja latencia con latidos de TTL cortos.

  5. Servicios de Entrega por Canal
    Trabajadores separados entregan notificaciones por canal:
    Trabajador de Notificaciones Push Móviles: Envía a APNs para iOS y FCM para Android. Maneja la invalidación de tokens, los errores del proveedor, los fallos reintentables y las claves de colapso.
    Trabajador de Notificaciones Push Web: Envía notificaciones push web a través del protocolo Web Push para usuarios con suscripciones de navegador registradas.
    Trabajador de Websocket: Envía notificaciones dentro de la aplicación de baja latencia a usuarios en línea a través de la Pasarela en Tiempo Real.
    Trabajador de Correo Electrónico: Envía correos electrónicos a través de un proveedor como SES, SendGrid o un MTA interno. Debe admitir procesamiento por lotes, plantillas, reglas de cancelación de suscripción y colas de menor prioridad.

  6. Servicio de Tokens de Dispositivo
    Almacena tokens de dispositivos móviles, suscripciones de notificaciones push web, metadatos del dispositivo, versión de la aplicación, plataforma, idioma y marca de tiempo de la última vez visto. Maneja la rotación de tokens y la limpieza de tokens inválidos.

  7. Servicio de Plantillas y Localización
    Renderiza el texto de la notificación y las plantillas de correo electrónico según el tipo de notificación, el idioma, el actor, los metadatos del objeto y las capacidades del cliente. Prefiere almacenar datos de notificación estructurados y renderizar en el momento de la lectura para el historial dentro de la aplicación, mientras que renderiza las cargas útiles finales en el momento de la entrega para notificaciones push/correo electrónico.

  8. Servicio de Deduplicación y Agregación
    Evita el spam y las notificaciones duplicadas. Ejemplos: agregar "Alices y otras 12 personas dieron me gusta a tu publicación" en lugar de enviar 13 notificaciones push independientes. Utilice claves de idempotencia como event_type + actor_id + recipient_id + object_id + event_time_bucket. La agregación se puede realizar con conjuntos/contadores ordenados de Redis y luego persistir.

  9. Métricas, Registro y Alertas
    Recopila latencia de extremo a extremo, retraso de la cola, tasa de éxito de entrega, tasa de errores del proveedor, recuento de conexiones websocket, tasa de creación de notificaciones, factor de distribución, latencia de la base de datos, precisión del recuento de no leídos y volumen de la cola de reintentos/mensajes fallidos.

Modelo de datos:

  1. Esquema de evento de notificación
    notification_event_id: ID único global
    source_event_id: ID del servicio de origen
    event_type: follow, like, comment, direct_message, mention
    actor_user_id: usuario que causó el evento
    recipient_user_ids o referencia del resolvedor de destinatarios
    target_type: post, comment, user, message, conversation
    target_id: ID del objeto de destino
    created_at: hora del evento
    metadata: JSON compacto para contexto adicional
    idempotency_key: clave estable para prevención de duplicados
    priority: high, normal, low

  2. Registro de historial de notificaciones
    user_id: clave de partición del destinatario
    notification_id: ID único ordenable por tiempo, por ejemplo, Snowflake/UUIDv7
    notification_type
    actor_user_id o resumen del actor
    target_type
    target_id
    aggregation_key
    summary_text o parámetros de renderizado
    created_at
    read_at (puede ser nulo)
    seen_at (puede ser nulo)
    status: created, delivered, failed, hidden
    channels_attempted
    metadata

Para el almacenamiento del historial, utilice una base de datos de columnas anchas como Apache Cassandra, ScyllaDB o DynamoDB. Particione por user_id y agrupe por created_at descendente o notification_id descendente. Esto coincide con el patrón de consulta principal: obtener las últimas 100 notificaciones para un usuario. Escala horizontalmente, admite un alto rendimiento de escritura y tiene lecturas predecibles de baja latencia. Utilice TTL o compactación en segundo plano para retener el historial reciente según los requisitos del producto, manteniendo al menos las últimas 100. Si se requiere estrictamente "solo las últimas 100", mantenga un trabajo de recorte por usuario o utilice TTL más compactación periódica.

Tabla lógica de ejemplo:
UserNotifications
clave de partición: user_id
clave de agrupación: created_at descendente, notification_id
columnas: type, actor_user_id, target_type, target_id, metadata, read_at, aggregation_key, status

  1. Modelo de recuento de no leídos
    Utilice Redis para lecturas y escrituras rápidas del recuento de no leídos, respaldado por almacenamiento duradero en Cassandra/DynamoDB. Incremente en la creación de notificaciones, decremente o restablezca al leer/marcar todo como leído. Dado que los contadores pueden desviarse, reconcilie periódicamente desde el almacenamiento duradero o utilice un modelo de marcador de lectura.

Enfoque alternativo de marcador de lectura:
Almacene last_read_timestamp por usuario y trate las notificaciones más nuevas que esa marca de tiempo como no leídas. Esto hace que "marcar todo como leído" sea barato. Para el estado de lectura por notificación, almacene read_at en registros individuales. A menudo, un híbrido es lo mejor.

  1. Preferencias del usuario
    Utilice una base de datos relacional como PostgreSQL o MySQL para registros de preferencias duraderos, ya que las preferencias requieren consistencia, actualizaciones estructuradas y uniones/operaciones administrativas ocasionales. Almacene en caché las preferencias activas en Redis o Memcached. Para una escala muy grande, particione por user_id o utilice DynamoDB si la organización prefiere la escala de clave-valor administrada.
    Esquema de preferencias:
    user_id
    notification_type
    channel: push, web, email, in_app
    enabled: booleano
    quiet_hours
    frequency: immediate, digest, never
    updated_at

  2. Tokens de dispositivo y suscripciones push
    Utilice DynamoDB, Cassandra o un almacén relacional particionado con clave user_id y device_id. Las búsquedas de tokens deben ser rápidas y altamente disponibles. Almacene token_hash/token, plataforma, app_version, idioma, enabled, last_seen_at e invalidated_at.

  3. Datos de presencia
    Utilice Redis Cluster con TTL:
    user_id -> IDs de conexión activa, IDs de dispositivo, IDs de nodo de pasarela, último latido
    connection_id -> user_id, nodo de pasarela, caducidad
    La presencia puede ser eventualmente consistente, ya que es solo una optimización para la entrega en tiempo real.

  4. Estado de entrega y registros de auditoría
    Utilice temas de Kafka más un almacén analítico de menor costo como S3/almacenamiento de objetos, ClickHouse, BigQuery o Elasticsearch/OpenSearch para depuración operativa, análisis e informes de entrega. No coloque registros de entrega de alto volumen en el almacén transaccional principal a menos que sea necesario.

Recomendaciones de pila tecnológica:

Bróker de mensajes: Kafka o Pulsar para streaming de eventos duradero, particionado por recipient_user_id donde el orden por destinatario sea importante. Utilice temas separados para ingesta, distribución, entrega por canal, reintentos y colas de mensajes fallidos.

Bases de datos:
Cassandra/ScyllaDB/DynamoDB para el historial de notificaciones.
PostgreSQL/MySQL o DynamoDB para las preferencias del usuario.
Redis Cluster para presencia y caché activa, caché a corto plazo de idempotencia, límites de velocidad y ventanas de agregación.
Almacenamiento de objetos más base de datos analítica para registros y análisis históricos.

Transporte en tiempo real:
WebSocket para notificaciones en tiempo real dentro de la aplicación y web. Server-Sent Events se puede usar para entrega unidireccional solo web, pero WebSocket es más flexible para acuses de recibo y latidos.

Proveedores de push:
APNs para iOS, FCM para Android, Web Push para navegadores. Abstraiga los proveedores detrás de un Servicio de Entrega de Push para aislar el comportamiento específico del proveedor.

Correo electrónico:
Amazon SES, SendGrid, Mailgun o infraestructura de correo electrónico interna. Utilice colas dedicadas, plantillas, listas de supresión y digestos.

Computación:
Servicios sin estado en Kubernetes o un orquestador similar. Escala automática horizontal de consumidores basada en el retraso de la cola, la CPU y la latencia de entrega. Utilice despliegue regional con balanceadores de carga y descubrimiento de servicios.

IDs:
Utilice UUIDv7, ULID o IDs de Snowflake para IDs de notificación ordenables. Asegure la idempotencia a través de source_event_id y claves de idempotencia específicas de la notificación.

Estrategia de escalabilidad:

  1. Particionamiento
    Particione los temas de Kafka por recipient_user_id para el orden por usuario cuando sea necesario. Para eventos de origen con destinatario desconocido, particione por entidad de origen hasta la distribución, luego re-particione por destinatario. Particione el historial de notificaciones por user_id para optimizar las consultas de notificaciones recientes.

  2. Escalado horizontal
    Todos los servicios de pipeline deben ser sin estado, excepto las pasarelas y el almacenamiento. Los consumidores se pueden escalar aumentando las particiones de temas y las réplicas de trabajadores. Las pasarelas en tiempo real escalan por recuento de conexiones y ancho de banda.

  3. Contrapresión (Backpressure)
    Si los proveedores descendentes se ralentizan, las colas absorben los picos. Utilice colas separadas por canal y prioridad para que los retrasos del correo electrónico no afecten a los mensajes directos o las notificaciones dentro de la aplicación. Aplique límites de velocidad por usuario, por actor, por tipo de notificación y por proveedor.

  4. Almacenamiento en caché (Caching)
    Almacene en caché preferencias, tokens de dispositivo, presencia, plantillas y recuentos de no leídos. Utilice TTL cortos para datos que cambian con frecuencia. Las fallas en la caché no deben bloquear toda la entrega; si las preferencias no están disponibles temporalmente, falle de forma segura según las reglas del producto, a menudo enviando solo los registros obligatorios dentro de la aplicación y posponiendo los canales externos.

  5. Agregación
    Reduzca la distribución y el volumen de notificaciones push agregando "me gusta" e interacciones similares. Por ejemplo, almacene cada evento de "me gusta" si es necesario para análisis, pero envíe una notificación por publicación por ventana de tiempo: "Alice, Bob y otras 10 personas dieron me gusta a tu publicación".

  6. Distribución híbrida (Hybrid fan-out)
    Para escenarios de alta distribución, evite escribir millones de filas inmediatamente. Almacene un evento compartido y materialice las notificaciones para los usuarios activos primero, y luego perezosamente para los usuarios inactivos cuando abran la aplicación.

  7. Despliegue multiregión
    Despliegue activo-activo o activo-pasivo entre regiones. Para un tiempo de actividad del 99,9%, se recomienda activo-activo para las pasarelas en tiempo real y los servicios sin estado, mientras que los almacenes de datos deben usar como mínimo replicación multi-AZ. El enrutamiento global de usuarios puede dirigir a los usuarios a la región saludable más cercana. Utilice clústeres de Kafka regionales con replicación o un sistema de streaming multiregión administrado.

Estrategia de baja latencia:

  1. Mantenga los servicios de producto desacoplados de la entrega de notificaciones. La publicación de eventos debe ser rápida y confiable.
  2. Utilice Kafka/Pulsar con suficientes particiones y consumidores para mantener bajo el retraso de la cola.
  3. Utilice Redis para la búsqueda de presencia y las decisiones de enrutamiento.
  4. Utilice la entrega por websocket para usuarios en línea, ya que evita la latencia de los proveedores de push de terceros.
  5. Persista los registros de notificaciones antes o en paralelo con la entrega, según las necesidades de confiabilidad. Un enfoque común es escribir primero el historial y luego entregar; para una latencia ultrabaja, la entrega y el almacenamiento pueden ocurrir concurrentemente con reintentos idempotentes.
  6. Evite uniones síncronas costosas. Los eventos deben incluir suficientes metadatos para el renderizado, o utilizar resúmenes de usuario/objeto almacenados en caché.
  7. Priorice los mensajes directos y las notificaciones sensibles a la seguridad sobre las notificaciones sociales de bajo valor.

Confiabilidad y alta disponibilidad:

  1. Mensajería duradera
    Utilice replicación de Kafka/Pulsar entre zonas de disponibilidad. Los productores utilizan acuses de recibo y reintentos. Los consumidores confirman los offsets solo después de un procesamiento duradero o después de escribir una salida idempotente.

  2. Patrón Outbox
    Los servicios de origen escriben cambios de dominio y eventos salientes transaccionalmente en una tabla outbox. Un relé publica el outbox en Kafka. Esto evita la pérdida de eventos cuando un servicio tiene éxito en la escritura de su base de datos pero falla antes de publicar.

  3. Idempotencia
    Cada etapa debe ser idempotente. Se esperan eventos duplicados debido a reintentos. Utilice source_event_id, notification_id e idempotency_key para evitar filas de historial duplicadas y intentos de push duplicados siempre que sea posible.

  4. Política de reintentos
    Los fallos transitorios van a temas de reintento con retroceso exponencial y jitter. Los fallos permanentes, como tokens de push inválidos, se manejan marcando los tokens como inválidos. Los mensajes venenosos van a colas de mensajes fallidos para su inspección.

  5. Degradación elegante (Graceful degradation)
    Si el proveedor de correo electrónico está caído, ponga en cola el correo electrónico y continúe con las notificaciones dentro de la aplicación. Si los proveedores de push son lentos, entregue por websocket/dentro de la aplicación y reintente el push más tarde. Si la caché de preferencias no está disponible, recurra a lecturas de preferencias duraderas o valores predeterminados conservadores. Si la presencia no está disponible, omita el websocket y confíe en el push/historial.

  6. Replicación y copias de seguridad
    Utilice bases de datos multi-AZ, copias de seguridad regulares, recuperación a un punto en el tiempo para almacenes relacionales y procedimientos de restauración probados. Para Cassandra/ScyllaDB, utilice un factor de replicación de 3 entre AZ y configuraciones de quorum apropiadas para las compensaciones de latencia/confiabilidad.

  7. Monitoreo y SLOs
    Rastree la latencia de extremo a extremo p50/p95/p99 desde la creación del evento de origen hasta la recepción del cliente. Alerte sobre el retraso de la cola, los picos de fallos de entrega, la limitación del proveedor, las particiones activas de la base de datos, la tasa de desconexión de websocket, la presión de memoria de Redis y las tormentas de reequilibrio de consumidores.

API de historial de notificaciones:

GET últimas notificaciones:
El cliente solicita las últimas 100 notificaciones. La Pasarela de API autentica al usuario, la API de Notificaciones consulta UserNotifications por user_id ordenado por created_at descendente, enriquece los campos de visualización faltantes desde la caché y devuelve registros estructurados.

Marcar notificación como leída:
La API actualiza read_at para esa notificación y ajusta el recuento de no leídos de forma idempotente.

Marcar todo como leído:
Almacena last_read_timestamp para el usuario y opcionalmente actualiza asíncronamente las filas más antiguas no leídas. Esto evita escrituras síncronas grandes.

Posibles cuellos de botella y compensaciones:

  1. Explosión de distribución (Fan-out explosion)
    Problema: Algunos eventos pueden notificar a muchos usuarios, abrumando las colas y el almacenamiento.
    Mitigación: Distribución híbrida, colas de prioridad, agregación, límites de velocidad y materialización perezosa.
    Compensación: La distribución en lectura reduce la carga de escritura pero hace que las lecturas sean más complejas y puede aumentar la latencia de lectura.

  2. Usuarios activos y publicaciones virales (Hot users and hot posts)
    Problema: Las celebridades o las publicaciones virales pueden generar un gran volumen de notificaciones para un destinatario o un objeto.
    Mitigación: Agregar notificaciones por objeto y ventana de tiempo, particionar claves de agregación y suprimir notificaciones repetidas de bajo valor.
    Compensación: Los usuarios pueden recibir notificaciones menos granulares.

  3. Límites de los proveedores de push
    Problema: APNs/FCM/proveedores de correo electrónico pueden limitar o fallar.
    Mitigación: Trabajadores de proveedor dedicados, limitación de velocidad adaptativa, reintentos, limpieza de tokens y retroceso específico del proveedor.
    Compensación: La entrega de push externa no siempre puede cumplir el objetivo de menos de 2 segundos; la entrega por websocket para usuarios en línea es la ruta confiable de baja latencia.

  4. Volumen de escritura de la base de datos
    Problema: Las escrituras de notificaciones por destinatario a gran escala pueden ser costosas.
    Mitigación: Utilizar almacenes de columnas anchas optimizados para escritura, lotes de escritura, TTL, agregación y distribución híbrida.
    Compensación: Los almacenes de columnas anchas tienen una flexibilidad de consulta limitada; el diseño debe coincidir con los patrones de acceso.

  5. Corrección del recuento de no leídos
    Problema: Los contadores almacenados en caché pueden desviarse bajo reintentos y actualizaciones de lectura concurrentes.
    Mitigación: Actualizaciones idempotentes, marcadores de lectura, reconciliación periódica.
    Compensación: El recuento exacto de no leídos es más costoso que el recuento de no leídos eventualmente consistente.

  6. Ordenación
    Problema: Las notificaciones pueden llegar desordenadas debido al procesamiento distribuido.
    Mitigación: Utilizar IDs ordenables y ordenar por hora del evento/ID de notificación al leer. Particionar por destinatario para un ordenamiento más fuerte por usuario cuando sea necesario.
    Compensación: El ordenamiento global estricto no es práctico ni necesario.

  7. Latencia versus durabilidad
    Problema: Escribir el historial antes de la entrega mejora la confiabilidad pero aumenta la latencia.
    Mitigación: Utilizar almacenamiento rápido en la región local y paralelizar el almacenamiento/entrega después de la asignación de idempotencia.
    Compensación: La entrega paralela puede mostrar brevemente una notificación enviada antes de que aparezca en el historial si el almacenamiento se retrasa.

  8. Complejidad de la evaluación de preferencias
    Problema: Las comprobaciones de preferencias por evento pueden ser costosas en el pico.
    Mitigación: Almacenar en caché las preferencias, precalcular la configuración efectiva e invalidar la caché en los cambios de preferencias.
    Compensación: Los cambios de preferencias pueden tardar unos segundos en propagarse a menos que se requiera una fuerte consistencia.

Resumen del diseño final recomendado:

Utilice una arquitectura impulsada por eventos con Kafka/Pulsar como columna vertebral, servicios de ingesta/distribución/enrutamiento sin estado, Cassandra/ScyllaDB/DynamoDB para el historial de notificaciones por usuario, Redis para presencia y cachés activas, pasarelas websocket para entrega en línea inferior a 2 segundos, APNs/FCM/Web Push para notificaciones de plataforma y un pipeline de entrega de correo electrónico separado. El sistema debe ser escalable horizontalmente, particionado principalmente por user_id, resiliente a través de colas duraderas y procesamiento idempotente, y optimizado para baja latencia a través de almacenamiento en caché, enrutamiento de presencia en línea, colas de prioridad y agregación. Este diseño cumple con los requisitos funcionales, admite los 1000 millones de eventos diarios esperados con picos de 5x y proporciona un camino práctico hacia una disponibilidad del 99,9% con degradación elegante bajo fallos parciales.

Resultado

#2

Votos ganadores

0 / 3

Puntuación media

86
Modelos evaluadores OpenAI GPT-5.6

Puntuación total

90

Comentario general

La respuesta B es también un diseño excelente y completo. Proporciona un pipeline coherente impulsado por eventos, introduce correctamente el patrón outbox, modela cuidadosamente las alternativas de historial y estado no leído, y ofrece un tratamiento sólido a la idempotencia, la degradación elegante, el fan-out híbrido y las compensaciones entre latencia y durabilidad. Su principal debilidad relativa es que varias opciones de infraestructura y estrategias regionales siguen siendo alternativas en lugar de un único plan de implementación concreto. También proporciona una planificación de capacidad menos específica para conexiones persistentes, recuentos de particiones, margen y comportamiento de conmutación de errores que la Respuesta A.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
89

La arquitectura es coherente y está bien descompuesta, y el outbox transaccional explícito cierra una ventana importante de pérdida de eventos. El fan-out, la evaluación de políticas, el almacenamiento, la presencia, las pasarelas en tiempo real, los trabajadores de canal, las plantillas y la deduplicación se colocan de manera apropiada. Pierde una pequeña cantidad de precisión porque el ordenamiento del almacenamiento frente a la entrega y la arquitectura regional activa-activa frente a activa-pasiva se presentan como opciones en lugar de decisiones de diseño resueltas.

Integridad

Peso 20%
91

Cubre el alcance funcional y no funcional completo, incluidas todas las plataformas de entrega, API de historial, modelos de datos, semántica de no leído, registro de dispositivos, presencia, localización, manejo de proveedores, monitoreo, cuellos de botella y compensaciones. Es ligeramente menos completa operativamente porque carece de dimensionamiento detallado de conexiones persistentes, aprovisionamiento concreto de particiones y una topología multirregional completamente seleccionada.

Análisis de compromisos

Peso 20%
92

Ofrece un excelente análisis del fan-out en escritura frente a fan-out en lectura, las limitaciones de las consultas de columnas anchas, la precisión del recuento de no leídos, el ordenamiento, la consistencia de la caché de preferencias, la latencia del proveedor y la latencia de durabilidad frente a entrega. El razonamiento es técnicamente maduro, aunque algunas alternativas quedan abiertas sin una selección o umbral final.

Escalabilidad y fiabilidad

Peso 20%
90

Calcula correctamente las tasas de referencia y pico y utiliza particionamiento, escalado horizontal, backpressure de colas, aislamiento de prioridades, fan-out híbrido, replicación, idempotencia, reintentos, DLQ, copias de seguridad y degradación elegante. El outbox es una fortaleza importante en cuanto a fiabilidad. En comparación con A, es menos concreta sobre la capacidad de flotas de conexiones, el margen de escalado en caliente, los recuentos de particiones, los objetivos de recuperación y el diseño exacto de la conmutación de errores regional.

Claridad

Peso 10%
86

La respuesta está organizada lógicamente y explica de manera consistente cada componente y decisión. Es algo más repetitiva y presenta frecuentemente menús de tecnologías o enfoques de implementación equivalentes, lo que debilita la decisión y hace que la arquitectura final sea ligeramente más difícil de extraer.

Modelos evaluadores Google Gemini 2.5 Pro

Puntuación total

87

Comentario general

Una respuesta muy sólida y técnicamente bien fundamentada que presenta una arquitectura correcta y robusta para el sistema de notificaciones. Cubre todos los aspectos requeridos del diseño con buen detalle, particularmente en sus descripciones de componentes y modelado de datos. Las soluciones propuestas son estándares de la industria y están bien justificadas. Su principal debilidad, en comparación con la Respuesta A, es que es ligeramente menos pulida en su estructura, menos detallada en su análisis cuantitativo inicial y carece del contexto operativo adicional proporcionado por un plan de implementación.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
90

La arquitectura propuesta también es muy sólida y sigue las mejores prácticas para un sistema basado en eventos. Los componentes son lógicos y sus responsabilidades están bien definidas. Identifica correctamente la necesidad de un modelo híbrido de fan-out. El diseño general es robusto y adecuado para la tarea, aunque ligeramente menos detallado en las interacciones de los componentes que la Respuesta A.

Integridad

Peso 20%
85

La respuesta es muy completa y aborda todos los requisitos centrales de la indicación, incluida la arquitectura, los modelos de datos y la escalabilidad. Sin embargo, carece de las secciones adicionales y muy relevantes sobre una implementación por fases y una lista estructurada de métricas/SLO que proporciona la Respuesta A, lo que la hace ligeramente menos completa en un sentido práctico.

Análisis de compromisos

Peso 20%
90

La respuesta proporciona una discusión sólida de los posibles cuellos de botella y las compensaciones involucradas. Identifica correctamente problemas como la explosión de fan-out y el volumen de escritura de la base de datos. El razonamiento es sólido y cubre las compensaciones clave, como fan-out-on-read frente a fan-out-on-write, lo que la convierte en una sección muy sólida.

Escalabilidad y fiabilidad

Peso 20%
85

La respuesta presenta un conjunto sólido de estrategias para escalabilidad y confiabilidad, que incluyen particionamiento, escalado horizontal, contrapresión y el patrón outbox. Todas estas son correctas y apropiadas para el sistema. Sin embargo, las estrategias se describen en términos ligeramente más generales en comparación con los planes específicos y accionables de la Respuesta A.

Claridad

Peso 10%
80

La respuesta está bien escrita y estructurada, lo que la hace generalmente fácil de entender. Sin embargo, la prosa es más densa que en la Respuesta A, y algunos conceptos se repiten en diferentes secciones. El formato superior y la concisión de la Respuesta A le dan una clara ventaja en legibilidad.

Modelos evaluadores Anthropic Claude Fable 5

Puntuación total

80

Comentario general

La respuesta B es un diseño exhaustivo y técnicamente sólido que cubre todos los requisitos del prompt: pipeline basado en eventos, fan-out-on-write vs. fan-out híbrido, almacén de historial de columnas anchas con justificación clara, presencia de Redis, workers de canal y una lista bien organizada de ocho cuellos de botella/compensaciones. Incluye de forma única el patrón outbox transaccional para la fiabilidad del productor y una alternativa reflexiva de marcador de lectura para las cuentas no leídas. Sin embargo, está menos fundamentada cuantitativamente que A (sin dimensionamiento de almacenamiento, sin dimensionamiento del nivel de conexión, sin orientación para el aprovisionamiento de particiones), duda frecuentemente entre opciones (Kafka o Pulsar, Postgres o MySQL o DynamoDB) en lugar de comprometerse con razonamientos, y carece de profundidad operativa como señales de escalado automático, estrategia de despliegue/lanzamiento y configuraciones de consistencia concretas ligadas al objetivo de disponibilidad.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
80

Arquitectura basada en eventos muy sólida con componentes bien definidos, fan-out híbrido, enrutamiento basado en presencia y el patrón outbox transaccional, que A no tiene. Sin embargo, se compromete menos firmemente (Kafka o Pulsar, se ofrecen múltiples opciones de bases de datos sin una elección final), no proporciona dimensionamiento del nivel de conexión ni aprovisionamiento de particiones, y la ruta de entrega crítica está menos explícitamente diseñada para el presupuesto de latencia.

Integridad

Peso 20%
85

Aborda todos los aspectos requeridos: arquitectura, componentes, modelo de datos con esquemas de tablas de ejemplo, pila tecnológica, escalabilidad, fiabilidad, flujos de API de historial y ocho elementos de cuello de botella/compensación. Incluye el patrón outbox y el modelo de marcador de lectura como extras. Ligeramente menos completo que A en dimensionamiento de capacidad/almacenamiento, consideraciones de cumplimiento, estrategia de lanzamiento y objetivos SLO definidos.

Análisis de compromisos

Peso 20%
78

Un formato bien estructurado de problema/mitigación/compensación a lo largo de ocho cuellos de botella, que cubren fan-out, ordenación, latencia frente a durabilidad y deriva de contadores. Buena amplitud, pero las compensaciones son más cortas y descriptivas; rara vez sopesa alternativas explícitas (por ejemplo, por qué Kafka en lugar de una cola más simple, o por qué persistencia políglota) con la profundidad que demuestra A.

Escalabilidad y fiabilidad

Peso 20%
78

Cubre los mecanismos correctos: partición por destinatario, escalado horizontal, contrapresión a través de colas, aislamiento de prioridad por canal, opciones multiregión, reintentos con retroceso, DLQ y degradación elegante. Sin embargo, la orientación es más genérica; no hay señales de escalado automático, cifras de margen, especificidades de particiones activas ni prácticas de validación (pruebas de carga, caos) que vinculen el diseño con los objetivos declarados.

Claridad

Peso 10%
80

Secciones claras con componentes numerados y un resumen final útil. Legible en general, aunque las dudas frecuentes entre opciones tecnológicas y cierta repetición entre las secciones de escalabilidad, latencia y fiabilidad diluyen ligeramente el mensaje.

Resumen comparativo

Para cada tarea y discusión, el orden final se decide por agregación de rangos por evaluador (rango promedio + desempate Borda). La puntuación media se muestra como referencia.

Evaluadores: 3

Votos ganadores

3 / 3

Puntuación media

92
Ver esta respuesta

Votos ganadores

0 / 3

Puntuación media

86
Ver esta respuesta

Resultados de evaluación

Modelos evaluadores Anthropic Claude Fable 5

Motivo del ganador

La respuesta A gana en los criterios ponderados. En el criterio más pesado, Calidad de Arquitectura (30%), A proporciona decisiones de diseño más concretas y comprometidas: nivel de WebSocket dimensionado, particiones de Kafka aprovisionadas con configuraciones de replicación, carriles de prioridad para el SLO de latencia y una ruta de entrega completamente especificada con escalera de respaldo. En Razonamiento de Compensaciones (20%), las alternativas y rechazos explícitos de A (Kafka vs SQS, exactamente una vez vs al menos una vez, políglota vs tienda única, región única vs activa-activa) superan la lista de compensaciones de estilo de mitigación de B. En Escalabilidad/Fiabilidad (20%), A proporciona mecanismos accionables (escalado KEDA por desfase del consumidor, compactación TWCS, claves 'hot' saladas, pruebas de caos, validación de carga 5x) donde B se mantiene más genérico. El patrón outbox y el modelo de marcador de lectura de B son ventajas genuinas, pero no compensan la superioridad de A en los criterios de mayor peso. El resultado ponderado favorece claramente a A.

Modelos evaluadores Google Gemini 2.5 Pro

Motivo del ganador

La respuesta A gana porque proporciona un diseño más detallado, pulido y completo. Si bien ambas respuestas proponen una arquitectura similar y sólida, la respuesta A sobresale en varias áreas clave. Comienza con una estimación exhaustiva de la capacidad cuantitativa, lo que fundamenta todo el diseño en números concretos. Su discusión sobre escalabilidad y confiabilidad es más específica, mencionando herramientas y prácticas avanzadas como KEDA para el escalado automático y la ingeniería del caos. Es excepcionalmente clara y está bien estructurada, lo que facilita la asimilación de información compleja. Finalmente, va más allá de los requisitos de la indicación al incluir un plan de implementación por fases y una sección dedicada a métricas/SLO, lo que demuestra una mentalidad más completa y preparada para la producción.

Modelos evaluadores OpenAI GPT-5.6

Motivo del ganador

La Respuesta A gana por un estrecho margen ponderado. Aunque la Respuesta B tiene una historia de fiabilidad de eventos de origen más sólida a través de su patrón explícito de outbox, la Respuesta A es más completa y operacionalmente concreta en cuanto a planificación de capacidad, aislamiento de prioridades, escalado de WebSockets, configuración del almacén de datos, controles de latencia, mecanismos de alta disponibilidad, mitigación de cuellos de botella, despliegue y SLOs. Esas ventajas son especialmente significativas en cuanto a completitud y escalabilidad/fiabilidad, mientras que su arquitectura sigue siendo muy sólida a pesar de la falta de detalle de publicación transaccional.

X f L