Orivel Orivel
Abrir menú

Diseñar un sistema de notificaciones en tiempo real para una aplicación de redes sociales

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 sénior encargado de diseñar un sistema de notificaciones en tiempo real para una aplicación de redes sociales en rápido crecimiento. El sistema debe ser escalable, fiable y entregar notificaciones con baja latencia. Proporciona una propuesta detallada de diseño del sistema.

Información complementaria

La aplicación de redes sociales tiene las siguientes características y requisitos:

Escala:

  • 10 millones de usuarios activos diarios (DAU).
  • Cada usuario recibe un promedio de 20 notificaciones al día.
  • El tráfico pico puede ser hasta 5 veces el tráfico promedio.

Requisitos funcionales:

  • Tipos de notificación: Me gusta, comentarios, nuevos seguidores, mensajes directos.
  • Entrega: Las notificaciones deben entregarse casi en tiempo real (con una latencia inferior a 2 segundos).
  • **C...
Mostrar más

La aplicación de redes sociales tiene las siguientes características y requisitos:

Escala:

  • 10 millones de usuarios activos diarios (DAU).
  • Cada usuario recibe un promedio de 20 notificaciones al día.
  • El tráfico pico puede ser hasta 5 veces el tráfico promedio.

Requisitos funcionales:

  • Tipos de notificación: Me gusta, comentarios, nuevos seguidores, mensajes directos.
  • Entrega: Las notificaciones deben entregarse casi en tiempo real (con una latencia inferior a 2 segundos).
  • Canales: Compatibilidad tanto con notificaciones push dentro de la aplicación (a dispositivos móviles) como con notificaciones por correo electrónico.
  • Historial: Los usuarios deben poder ver sus últimas 100 notificaciones.
  • Preferencias: Los usuarios pueden habilitar/deshabilitar tipos específicos de notificaciones.

Requisitos no funcionales:

  • Alta disponibilidad: El sistema debe tener alta disponibilidad con un tiempo de inactividad mínimo.
  • Fiabilidad: No debe perderse ninguna notificación.
  • Escalabilidad: La arquitectura debe poder escalar para admitir 100 millones de DAU en el futuro.
  • Rentabilidad: El diseño debe tener en cuenta los costos operativos.

Tu propuesta debe cubrir la arquitectura de alto nivel, los componentes clave, las elecciones tecnológicas, el modelo de datos y las estrategias para garantizar la escalabilidad y la fiabilidad. Asegúrate de explicar las compensaciones que consideraste en tu diseño.

Política de evaluación

Una respuesta de alta calidad presentará un diseño de sistema coherente y bien razonado. Evalúa la respuesta según los siguientes criterios:

  1. Arquitectura: ¿La arquitectura de alto nivel propuesta es lógica y completa? ¿Identifica claramente componentes principales como puertas de enlace de API, servicios de notificaciones, colas de mensajes, bases de datos y servicios push de terceros?
  2. Elecciones tecnológicas: ¿Las elecciones tecnológicas (p. ej., Kafka frente a RabbitMQ, NoSQL frente a SQL, eleccio...
Mostrar más

Una respuesta de alta calidad presentará un diseño de sistema coherente y bien razonado. Evalúa la respuesta según los siguientes criterios:

  1. Arquitectura: ¿La arquitectura de alto nivel propuesta es lógica y completa? ¿Identifica claramente componentes principales como puertas de enlace de API, servicios de notificaciones, colas de mensajes, bases de datos y servicios push de terceros?
  2. Elecciones tecnológicas: ¿Las elecciones tecnológicas (p. ej., Kafka frente a RabbitMQ, NoSQL frente a SQL, elecciones específicas de bases de datos como Cassandra o Redis) son adecuadas para los requisitos y las justificaciones de estas elecciones son sólidas?
  3. Escalabilidad y fiabilidad: ¿El diseño aborda eficazmente cómo escalará el sistema para manejar cargas pico y crecimiento futuro? ¿Se explican claramente los mecanismos de fiabilidad y tolerancia a fallos, como reintentos, colas de mensajes fallidos y replicación de bases de datos?
  4. Compensaciones: ¿La respuesta demuestra una comprensión profunda de los principios de diseño de sistemas al discutir explícitamente las compensaciones realizadas (p. ej., consistencia frente a disponibilidad, costo frente a rendimiento, mecanismos push frente a pull)?
  5. Completitud: ¿El diseño aborda todos los requisitos funcionales y no funcionales especificados, incluido el historial de notificaciones, las preferencias de usuario y múltiples canales de entrega?

Respuestas

Diseño de un Sistema de Notificaciones en Tiempo Real para una Aplicación de Redes Sociales

1. Repaso de Requisitos y Estimación Preliminar

Estimación de Tráfico:

  • 10M Usuarios Activos Diarios (DAU) × 20 notificaciones/día = 200M notificaciones/día
  • Tasa promedio = 200M / 86.400s ≈ 2.315 notificaciones/segundo
  • Tasa pico (5x) ≈ 11.500 notificaciones/segundo
  • Con 100M DAU (futuro): promedio ~23.000/s, pico ~115.000/s

Estimación de Almacenamiento:

  • Cada registro de notificación ~500 bytes (metadatos + carga útil)
  • Almacenamiento diario: 200M × 500B = 100 GB/día → ~36 TB/año (antes de compres...
Mostrar respuesta completa

Diseño de un Sistema de Notificaciones en Tiempo Real para una Aplicación de Redes Sociales

1. Repaso de Requisitos y Estimación Preliminar

Estimación de Tráfico:

  • 10M Usuarios Activos Diarios (DAU) × 20 notificaciones/día = 200M notificaciones/día
  • Tasa promedio = 200M / 86.400s ≈ 2.315 notificaciones/segundo
  • Tasa pico (5x) ≈ 11.500 notificaciones/segundo
  • Con 100M DAU (futuro): promedio ~23.000/s, pico ~115.000/s

Estimación de Almacenamiento:

  • Cada registro de notificación ~500 bytes (metadatos + carga útil)
  • Almacenamiento diario: 200M × 500B = 100 GB/día → ~36 TB/año (antes de compresión/archivo)
  • El requisito de historial (últimas 100 por usuario) es un patrón de acceso "en caliente" con muchas lecturas, lo que favorece un diseño donde las notificaciones recientes sean baratas de obtener (por ejemplo, lista limitada por usuario) mientras que el historial completo va a almacenamiento frío.

Esto confirma que estamos ante un sistema con muchas escrituras, con mucho fan-out, sensible a la latencia que debe desacoplar la ingesta de la entrega.


2. Arquitectura de Alto Nivel

[Productores de Eventos] → [Bus de Eventos / Kafka] → [Servicio de Notificaciones (Consumidores)]
                                                    │
                        ┌───────────────────────────┼───────────────────────────┐
                        ▼                            ▼                           ▼
                 [Servicio de Preferencias]     [Renderizado/Plantillas]     [Limitador de Tasa/Deduplicación]
                        │                            │                           │
                        └───────────────┬────────────┴───────────────────────────┘
                                        ▼
                          [Distribuidor / Enrutador de Entrega]
                       ┌─────────────┬─────────────┬─────────────┐
                       ▼             ▼             ▼             ▼
                 [Servicio Push]  [Gateway WebSocket/  [Servicio de Email]  [Escritura en Tienda In-App - DynamoDB/Cassandra]
                 (FCM/APNs)       SSE]
                       │             │
                  [Dispositivos Móviles][Clientes Conectados]

Flujo:

  1. Un sistema de origen (por ejemplo, Servicio de "Me gusta", Servicio de Comentarios, Servicio de Seguimiento, Servicio de Mensajería) emite un evento (por ejemplo, user_liked_post) a un bus de mensajes duradero (Kafka).
  2. El Orquestador de Notificaciones consume estos eventos, verifica las preferencias del usuario, aplica lógica de deduplicación/limitación de tasa/agrupación (por ejemplo, "A John y otras 5 personas les gustó tu publicación") y genera un objeto de notificación.
  3. El orquestador persiste la notificación (para el historial) y la envía a un Distribuidor de Entrega, que realiza el fan-out a los canales apropiados según la preferencia del usuario y el estado del dispositivo (en línea vs. fuera de línea).
  4. Los trabajadores de entrega manejan la transmisión real: proveedores de notificaciones push (FCM para Android, APNs para iOS), WebSocket/SSE para actualizaciones de insignias en tiempo real dentro de la aplicación y correo electrónico a través de un proveedor de correo electrónico transaccional.

3. Componentes Clave

3.1 Capa de Ingesta de Eventos — Apache Kafka

  • Todos los servicios de origen publican eventos en temas de Kafka (particionados por user_id para preservar el orden por usuario).
  • Kafka proporciona durabilidad (factor de replicación 3), alto rendimiento y almacenamiento en búfer natural durante picos de tráfico — crítico ya que el tráfico pico es 5 veces el promedio.
  • Temas: notification.likes, notification.comments, notification.followers, notification.messages (o un solo tema con campo de tipo de evento, dependiendo de las necesidades de evolución del esquema).

¿Por qué Kafka en lugar de SQS/RabbitMQ? Kafka maneja un rendimiento muy alto con una sobrecarga baja por mensaje y admite la repetición (útil para reprocesar lotes fallidos o rellenar datos). SQS es más simple operacionalmente pero más difícil de escalar a >100k msg/s de manera rentable y no admite semánticas de repetición de grupos de consumidores de forma tan limpia.

3.2 Servicio Orquestador de Notificaciones

  • Consumidor sin estado que lee de Kafka.
  • Responsabilidades:
    • Verificación de preferencias: Consulta una base de datos clave-valor rápida (Redis o DynamoDB) para obtener la configuración de notificaciones del usuario antes de procesar más.
    • Deduplicación/Agrupación: Utiliza una ventana de agregación de corta duración (por ejemplo, conjuntos ordenados de Redis con TTL) para agrupar eventos similares (por ejemplo, varios "me gusta" en la misma publicación en 60 segundos se convierten en una notificación).
    • Fan-out para seguidores: Para eventos como "nueva publicación de alguien a quien sigues", esto podría requerir un fan-out a millones de seguidores (problema de celebridades). Utiliza un modelo de fan-out híbrido:
      • Fan-out en escritura para usuarios normales (envía a la fuente de notificaciones de cada seguidor inmediatamente).
      • Fan-out en lectura para celebridades/cuentas con muchos seguidores (calcula en el momento de la lectura para evitar una tormenta de escrituras).
  • Escalable horizontalmente — escala las instancias de consumidor según el número de particiones de Kafka y el rezago.

3.3 Almacén de Notificaciones (Capa de Persistencia)

  • Almacén principal: Una base de datos NoSQL de columnas anchas como Apache Cassandra o DynamoDB, particionada por user_id, agrupada/ordenada por timestamp (descendente).
    • Este modelo es ideal porque el patrón de acceso dominante es "obtener las últimas 100 notificaciones para el usuario X", lo cual es una consulta de rango simple en una partición — sin necesidad de uniones.
    • Cassandra ofrece consistencia ajustable y escalabilidad horizontal mucho más allá de 100 millones de usuarios; DynamoDB ofrece una alternativa totalmente administrada con menos sobrecarga operativa (contrapartida: mayor costo a escala muy grande y riesgo de partición caliente para usuarios extremadamente activos a menos que las claves de partición estén saladas).
  • TTL/Archivo: Conserva solo notificaciones recientes (por ejemplo, 30-90 días) en el almacén caliente; datos más antiguos archivados en almacenamiento más barato (S3 + Glacier) para cumplimiento/auditoría, con el límite "últimas 100" aplicado en el momento de la escritura (una lista limitada por usuario, o recortada mediante compactación periódica).

3.4 Distribuidor de Entrega

  • Lee el objeto de notificación finalizado y determina los canales a usar según:
    • Preferencias de canal del usuario (push/email/ambos/ninguno)
    • Estado en línea del usuario (rastreado a través de un servicio de presencia respaldado por Redis, actualizado por WebSocket/heartbeat)
  • Dirige a:
    • Servicio de Notificaciones Push: Se integra con FCM (Android) y APNs (iOS). Se envuelve en una capa de abstracción interna para normalizar reintentos, formatos de carga útil y gestión de tokens de dispositivo (tokens almacenados en una tabla user_devices, actualizados al iniciar la aplicación).
    • Entrega en Tiempo Real Dentro de la Aplicación: Para usuarios conectados activamente a través de WebSocket/SSE, envía directamente a una gateway de conexión (por ejemplo, un conjunto de servidores WebSocket detrás de un balanceador de carga, usando algo como Socket.IO o un servicio administrado como AWS API Gateway WebSockets). El mapeo conexión-servidor se rastrea en Redis para que cualquier nodo distribuidor pueda encontrar qué instancia de gateway tiene la conexión de un usuario.
    • Servicio de Email: Para notificaciones menos sensibles al tiempo (por ejemplo, resumen semanal) o como respaldo para usuarios fuera de línea en ciertos tipos de notificaciones, se integra con un proveedor como Amazon SES o SendGrid, utilizando una cola separada de menor prioridad ya que los SLAs de correo electrónico son más relajados (segundos a minutos está bien).

3.5 Servicio de Preferencias

  • Servicio simple respaldado por una base de datos relacional (Postgres) o DynamoDB, almacenado en caché agresivamente en Redis (las preferencias cambian con poca frecuencia, se leen con mucha frecuencia — candidato perfecto para caché).
  • Esquema: user_id, notification_type, channel, enabled.

4. Modelo de Datos

Tabla de Notificaciones (Cassandra/DynamoDB)

Clave de Partición: user_id
Clave de Agrupación: notification_id (UUID basado en tiempo, ordenado descendentemente)
Atributos:
  - type (like, comment, follow, message)
  - actor_id (quién lo activó)
  - actor_ids (array, para notificaciones agrupadas)
  - target_object_id (post_id, comment_id, etc.)
  - message_preview
  - created_at
  - read_status (booleano)
  - delivered_channels (array: push, email, in-app)

Tabla de Preferencias de Usuario

Clave de Partición: user_id
Atributos: { likes: {push: true, email: false}, comments: {...}, follows: {...}, messages: {...} }

Tabla de Tokens de Dispositivo

Clave de Partición: user_id
Clave de Agrupación: device_id
Atributos: platform (ios/android), token, last_active

5. Garantía de Fiabilidad ("No se pierde ninguna notificación")

  1. Mensajería duradera: Kafka con factor de replicación ≥3 y acks=all en los productores garantiza que los eventos no se pierdan antes de su procesamiento.
  2. Procesamiento al menos una vez con idempotencia: Los consumidores pueden reprocesar en caso de fallo/reinicio, por lo que los IDs de notificación se generan de forma determinista (por ejemplo, hash del ID del evento de origen + tipo) para permitir escrituras idempotentes — evita notificaciones duplicadas en reintentos.
  3. Colas de mensajes fallidos (DLQ): Las entregas fallidas (por ejemplo, tiempo de espera del proveedor push) van a un tema DLQ con reintento de retroceso exponencial (por ejemplo, 3 reintentos con fluctuación), luego a revisión manual/alerta si aún fallan.
  4. Escribir la notificación en el almacén ANTES de intentar la entrega: Esto desacopla "la notificación existe" (durabilidad/historial) de "la notificación se entregó" (mejor esfuerzo en tiempo real). Incluso si la entrega push falla, el usuario la verá la próxima vez que abra la aplicación y consulte la API de notificaciones.
  5. Patrón Outbox en servicios de origen: Para evitar problemas de doble escritura (escritura en DB + publicación de eventos), utiliza el patrón outbox transaccional para que, cuando se registre un "me gusta" en la DB del servicio de origen, el evento se publique garantizado en Kafka a través de una herramienta de captura de datos de cambios (CDC) como Debezium.

6. Estrategia de Escalabilidad (10M → 100M DAU)

  • Kafka: Aumentar el número de particiones (particionadas por hash del user_id) — escala linealmente con más brokers/consumidores.
  • Orquestador y Distribuidor de Notificaciones: Sin estado, escalable horizontalmente detrás de grupos de consumidores; escala a través de HPA de Kubernetes según el rezago del consumidor de Kafka.
  • Cassandra: Agregar nodos al anillo; el hashing consistente distribuye la carga automáticamente. Vigilar las particiones calientes por contenido viral/cuentas de celebridades — mitigar mediante agrupamiento (por ejemplo, dividir el fan-out de una celebridad en varias claves de partición).
  • Gateway WebSocket: Escalar horizontalmente; usar sesiones pegajosas a través de un registro de conexiones en Redis para que los distribuidores sepan qué nodo de gateway posee qué conexión, independientemente de cuántos nodos de gateway existan.
  • Proveedores Push/Email: Estos son servicios administrados por terceros (FCM, APNs, SES) que escalan independientemente; nuestra responsabilidad es la agrupación y la limitación de tasa para mantenernos dentro de las cuotas del proveedor.
  • Caché: El almacenamiento en caché agresivo de Redis de preferencias y datos de presencia reduce la carga de la DB a medida que el número de usuarios crece 10 veces.

7. Compromisos Clave

| Decisión | Compromiso |
|---|---|
| Kafka vs. cola más simple (SQS) | Kafka agrega complejidad operativa (necesita experiencia dedicada en operaciones, gestión de ZooKeeper/KRaft) pero proporciona un rendimiento muy superior y capacidad de repetición necesarios a esta escala. |
| Cassandra vs. DynamoDB | Cassandra ofrece más control y potencialmente menor costo a escala muy grande pero requiere operaciones internas; DynamoDB está totalmente administrado (más rápido de construir, menos carga operativa) pero puede resultar caro a escala extrema y tiene restricciones más estrictas de tamaño de elemento/partición de rendimiento. |
| Fan-out en escritura vs. fan-out en lectura | El fan-out en el momento de la escritura proporciona menor latencia de lectura (ideal para el SLA de 2 segundos) pero corre el riesgo de una tormenta de escrituras "rebaño" para celebridades; el fan-out en lectura evita eso pero agrega latencia y cómputo en el momento de la lectura. El enfoque híbrido equilibra ambos pero agrega complejidad de diseño/código (dos rutas de código). |
| Almacenar historial completo vs. 100 notificaciones recientes en caliente + archivo | Reduce los costos de almacenamiento en caliente y mantiene las consultas rápidas, pero requiere una ruta de archivo/recuperación para cumplimiento o funciones de "cargar más", lo que agrega complejidad. |
| Entrega al menos una vez + idempotencia vs. exactamente una vez | Las semánticas de "exactamente una vez" en sistemas distribuidos son costosas/complejas (requiere consumidores transaccionales); "al menos una vez" + escrituras idempotentes logran la misma garantía práctica (sin notificaciones visibles duplicadas) a un costo operativo mucho menor. |
| Push en tiempo real para todo vs. agrupación/agregación | Agrupar notificaciones similares (por ejemplo, "10 personas le dieron me gusta a tu foto") reduce la fatiga de notificaciones y el volumen de entrega, mejorando tanto la experiencia del usuario como el costo, a expensas de una lógica de orquestación ligeramente más compleja y un pequeño retraso de almacenamiento en búfer (aún dentro del SLA de 2 segundos si la ventana es corta, por ejemplo, retención máxima de 5-10 segundos antes de vaciar). |


8. Monitoreo y Alertas

  • Rastrea el rezago del consumidor de Kafka, la tasa de éxito/fallo de entrega por canal, la latencia de extremo a extremo P50/P95/P99 (ingesta de eventos → entrega al dispositivo) y la profundidad de la DLQ.
  • Los paneles de SLA alertan al personal de guardia si la latencia P95 excede los 2 segundos o si el crecimiento de la DLQ indica un fallo de entrega sistémico (por ejemplo, interrupción de FCM), lo que activa la lógica de failover automático (por ejemplo, cola de espera + reintento con retroceso en lugar de descartar).

Resumen

El diseño desacopla la generación de notificaciones (basada en eventos, basada en Kafka, idempotente) de la entrega (distribuidor multicanal con reintento/retroceso por canal), respaldado por un almacén de columnas anchas optimizado para el patrón de acceso "historial reciente por usuario". Esta separación es lo que permite que el sistema cumpla con el SLA de latencia de 2 segundos garantizando la no pérdida de datos, y escala horizontalmente en cada nivel (ingesta, procesamiento, almacenamiento, entrega) para soportar 10 veces el crecimiento futuro con una sobrecarga operativa y de costos manejable.

Resultado

#2

Votos ganadores

0 / 3

Puntuación media

83
Modelos evaluadores OpenAI GPT-5.5

Puntuación total

85

Comentario general

La Respuesta A es una propuesta de diseño de sistema sólida con estimaciones de capacidad precisas, una arquitectura lógica basada en eventos, el uso apropiado de Kafka, Cassandra/DynamoDB, Redis, WebSockets, APNs/FCM y proveedores de correo electrónico, y una buena cobertura de persistencia, preferencias, reintentos, DLQs, idempotencia, monitoreo y compensaciones. Sus principales debilidades son que algunas áreas son menos precisas de lo que podrían ser, como el límite exacto de latencia, la estrategia de HA/DR, los detalles de la ruta de lectura/API, la priorización de sobrecarga y los matices de las semánticas de entrega en torno a los proveedores externos.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
85

La Respuesta A presenta una arquitectura coherente con productores de eventos, Kafka, orquestación de notificaciones, verificación de preferencias, almacenamiento, distribuidores, entrega de WebSocket, proveedores de push y trabajadores de correo electrónico. El flujo es lógico y completo, aunque algunos detalles de la separación de comandos de canal/ruta de lectura/API son menos explícitos.

Integridad

Peso 20%
83

La Respuesta A cubre los requisitos principales: tipos de notificación, entrega casi en tiempo real, canales de push/correo electrónico/en la aplicación, historial de los últimos 100, preferencias, escalabilidad, confiabilidad, costo, monitoreo y modelos de datos. Es algo más ligera en detalles de API, seguridad/privacidad, recuperación ante desastres y comportamiento operativo exacto durante sobrecargas o interrupciones de proveedores.

Análisis de compromisos

Peso 20%
84

La Respuesta A incluye una tabla útil de compensaciones que cubre Kafka vs. SQS, Cassandra vs. DynamoDB, fan-out-on-write vs. fan-out-on-read, almacenamiento en caliente limitado vs. archivo, at-least-once vs. exactly-once, y entrega por lotes vs. en tiempo real. El razonamiento es sólido, aunque algunas compensaciones se resumen en lugar de estar estrechamente ligadas a las consecuencias operativas.

Escalabilidad y fiabilidad

Peso 20%
85

La Respuesta A ofrece sólidos mecanismos de escalabilidad y confiabilidad: replicación y reproducción de Kafka, escrituras idempotentes, DLQs, reintentos, patrón outbox, escalado horizontal, particionamiento de Cassandra/DynamoDB, caché de Redis y escalado de WebSocket. Es menos detallada en la recuperación multirregión, la priorización de sobrecarga, la disciplina de offset del consumidor, los límites de entrega del proveedor y las semánticas exactas de SLO.

Claridad

Peso 10%
88

La Respuesta A está claramente estructurada, es fácil de seguir y utiliza diagramas, viñetas, esquemas y una tabla concisa de compensaciones de manera efectiva. Comunica el diseño de manera eficiente con una ambigüedad mínima.

Modelos evaluadores Anthropic Claude Opus 5

Puntuación total

80

Comentario general

La respuesta A es una propuesta de diseño pulida y bien estructurada que se leería bien en una entrevista. Clava las matemáticas de capacidad, proporciona un diagrama de arquitectura legible, modelos de datos concretos, una tabla de compensaciones clara y cubre el patrón outbox, la idempotencia, las DLQ y la escalabilidad horizontal en todos los niveles. Sus debilidades son la profundidad y la amplitud en algunas áreas: no hay diseño de API/ruta de lectura, no hay discusión sobre seguridad o privacidad, no hay topología de alta disponibilidad o recuperación ante desastres, no hay aislamiento de prioridad entre las clases de notificación y acepta sin críticas el SLA de extremo a extremo de 2 segundos sin notar que los proveedores de terceros lo hacen inaplicable. La sugerencia de fan-out-on-read también es un ajuste un tanto incómodo para una bandeja de entrada de notificaciones.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
82

Presenta una arquitectura en capas clara con un diagrama ASCII, bus de eventos (Kafka), orquestador, servicio de preferencias, despachador, puerta de enlace WebSocket, trabajadores push/email y un almacén de columnas anchas. El flujo es fácil de seguir y los componentes están bien delimitados. Pequeñas debilidades: la discusión de fan-out-on-read se aplica de forma algo incorrecta a las notificaciones (es un concepto de feed), y la ruta de API/lectura más la capa de API gateway apenas se abordan a pesar de ser señaladas en la política de evaluación.

Integridad

Peso 20%
76

Cubre la estimación, los cuatro tipos de notificación, los canales push/email/in-app, el historial a través de listas limitadas más archivo, preferencias con esquema, tokens de dispositivo, fiabilidad, escalabilidad y monitorización. Ausente o escaso: diseño de API/ruta de lectura, seguridad y privacidad, recuperación ante desastres y estrategia multirregión, recuentos de no leídos y topología explícita de alta disponibilidad (distribución de AZ).

Análisis de compromisos

Peso 20%
80

Una tabla de compensaciones dedicada cubre Kafka vs SQS, Cassandra vs DynamoDB, fan-out en escritura vs lectura, almacenamiento en caliente vs archivo, at-least-once vs exactly-once, y batching vs inmediatez. Cada entrada nombra tanto el beneficio como el costo, lo cual es claro y legible. Sin embargo, las compensaciones son en su mayoría convencionales y se exponen brevemente, con menos profundidad en los límites de consistencia, las garantías de ordenación o los matices de la definición de SLO.

Escalabilidad y fiabilidad

Peso 20%
80

Sólido: particionamiento y replicación de Kafka, acks=all, at-least-once con IDs idempotentes deterministas, DLQ con retroceso exponencial y jitter, write-before-deliver, outbox transaccional con Debezium, HPA en lag del consumidor, expansión del anillo de Cassandra, salting de particiones calientes y registro de conexiones Redis. Carece de alta disponibilidad explícita multiaz/multirregión, procedimientos de DR/failover, aislamiento de contrapresión o prioridad entre clases de notificación, y semántica de commit de offset.

Claridad

Peso 10%
85

Excelente legibilidad: secciones numeradas, un diagrama de arquitectura ASCII, bloques de código para el modelo de datos, una tabla de compensaciones y un resumen conciso al final. Fácil de hojear y rápido de comprender el diseño de un vistazo.

Modelos evaluadores Google Gemini 2.5 Pro

Puntuación total

85

Comentario general

La Respuesta A proporciona un diseño de sistema muy sólido y bien estructurado. Sus puntos fuertes clave son la claridad y la organización, utilizando un diagrama y una tabla para que los conceptos complejos sean fáciles de entender. Cubre todos los requisitos principales de la indicación, proponiendo una arquitectura lógica con opciones tecnológicas apropiadas y estrategias sólidas de escalabilidad y fiabilidad. Sin embargo, carece de la profundidad y amplitud de la Respuesta B, particularmente en áreas como el diseño de API, la seguridad y la planificación detallada de la recuperación ante desastres.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
85

La arquitectura propuesta es lógica, completa y muy adecuada para la tarea. Identifica claramente todos los componentes principales y sus interacciones, y la inclusión de un diagrama facilita enormemente la comprensión. El flujo desde los productores de eventos hasta los canales de entrega está bien definido.

Integridad

Peso 20%
80

La respuesta aborda todos los requisitos funcionales y no funcionales especificados en la indicación. Cubre los aspectos principales del diseño, incluidas las estimaciones, los componentes, los modelos de datos y las estrategias de escalabilidad y fiabilidad.

Análisis de compromisos

Peso 20%
85

La respuesta analiza claramente las compensaciones clave en una tabla dedicada, lo cual es muy efectivo. Proporciona un razonamiento sólido para opciones como Kafka sobre SQS y Cassandra sobre DynamoDB, lo que demuestra una buena comprensión de los principios involucrados.

Escalabilidad y fiabilidad

Peso 20%
85

El diseño aborda eficazmente la escalabilidad y la fiabilidad. Propone técnicas estándar y efectivas como el escalado horizontal para servicios, la partición en Kafka y Cassandra, y el uso de DLQ y la idempotencia para la fiabilidad. Las estrategias son sólidas y están bien explicadas.

Claridad

Peso 10%
90

La respuesta es excepcionalmente clara y está bien organizada. El uso de encabezados, un diagrama de flujo y una tabla de compensaciones hace que el diseño complejo sea fácil de seguir y asimilar. La redacción es directa y va al grano.

Respuesta B: OpenAI GPT-5.6

VISIÓN GENERAL

El sistema debe tratar cada notificación como un registro duradero y específico del destinatario y entregarlo de forma asíncrona a través de uno o más canales. La bandeja de entrada duradera en la aplicación es la fuente de verdad; las notificaciones push móviles y el correo electrónico son intentos de entrega derivados de ese registro. Esta separación proporciona baja latencia sin hacer que las acciones sociales visibles para el usuario esperen a proveedores externos como APNs, FCM o un servicio de correo electrónico.

ESTIMACIONES DE CAPACIDAD

Con 10 millones de DAU y 20 notificaciones por usua...

Mostrar respuesta completa

VISIÓN GENERAL

El sistema debe tratar cada notificación como un registro duradero y específico del destinatario y entregarlo de forma asíncrona a través de uno o más canales. La bandeja de entrada duradera en la aplicación es la fuente de verdad; las notificaciones push móviles y el correo electrónico son intentos de entrega derivados de ese registro. Esta separación proporciona baja latencia sin hacer que las acciones sociales visibles para el usuario esperen a proveedores externos como APNs, FCM o un servicio de correo electrónico.

ESTIMACIONES DE CAPACIDAD

Con 10 millones de DAU y 20 notificaciones por usuario por día, el sistema crea aproximadamente 200 millones de notificaciones por día. Esto es aproximadamente 2.315 notificaciones por segundo en promedio y 11.600 por segundo en el pico declarado de 5x. Con 100 millones de DAU, las tasas correspondientes son de aproximadamente 23.000 por segundo en promedio y 116.000 por segundo en pico.

Estas son tasas de destinatario-notificación, no meramente tasas de eventos de origen. Una publicación de celebridad puede producir un pico de clave caliente o de distribución masiva, por lo que las capas de ingesta y encolado deben aprovisionarse por encima del pico calculado, inicialmente para aproximadamente 25.000 notificaciones por segundo y eventualmente para al menos 200.000 por segundo. Las cargas útiles deben seguir siendo pequeñas, con medios y contenido completo de la publicación referenciados por ID en lugar de incrustados.

ARQUITECTURA DE ALTO NIVEL

Los servicios sociales como Me gusta, Comentar, Seguir y Mensaje Directo escriben su propio estado y un evento de notificación en una outbox transaccional en la misma transacción de base de datos. Los publicadores de outbox transfieren continuamente estos eventos a un registro de eventos duradero como Apache Kafka. Esto evita el fallo de doble escritura en el que una acción social tiene éxito pero su evento de notificación se pierde.

Un Procesador de Notificaciones consume los eventos de origen, los valida, identifica a los destinatarios, genera un ID de notificación determinista, carga las preferencias de notificación, realiza un enriquecimiento ligero y escribe la notificación del destinatario en el almacén de la bandeja de entrada. Luego publica un comando de entrega duradero por canal habilitado en temas de Kafka específicos del canal.

Los Trabajadores de Notificaciones Push consumen comandos push e invocan APNs o FCM. Los Trabajadores de Correo Electrónico renderizan plantillas e invocan a un proveedor como Amazon SES, SendGrid o un servicio de transferencia de correo interno. Una Puerta de Enlace WebSocket también puede consumir comandos de entrega en la aplicación y actualizar inmediatamente los clientes conectados; los clientes desconectados aún ven la bandeja de entrada duradera al reconectarse. Los resultados de la entrega y los reintentos se registran de forma asíncrona.

El flujo principal es:

Servicio social y outbox transaccional → Temas de eventos de origen de Kafka → Procesador de Notificaciones → Almacén de bandeja de entrada duradero → Temas de comandos de canal → Trabajadores de WebSocket, APNs/FCM y correo electrónico.

El flujo de lectura es:

Cliente → Puerta de Enlace de API → API de Notificaciones → Almacén de bandeja de entrada y almacén de preferencias.

COMPONENTES CENTRALES

La Puerta de Enlace de API maneja la autenticación, la limitación de velocidad, el enrutamiento de solicitudes y la protección contra abusos. La API de Notificaciones admite la obtención de notificaciones recientes, la paginación basada en cursor, los recuentos de no leídos, el marcado de uno o más elementos como leídos y la gestión de preferencias.

Kafka proporciona almacenamiento en búfer duradero, suavizado de tráfico, repetición, aislamiento del consumidor y escalabilidad horizontal. Los temas se replican en al menos tres zonas de disponibilidad. Los temas de origen se pueden particionar por ID de usuario destinatario después de la expansión del destinatario, preservando el orden por usuario mientras se distribuyen los usuarios entre las particiones. La expansión de alta distribución masiva puede usar un grupo de trabajadores separado para que un evento grande no bloquee el tráfico normal.

El Procesador de Notificaciones debe ser sin estado y escalarse automáticamente utilizando el rezago de la cola, la latencia de procesamiento, la CPU y el rendimiento. Realiza la evaluación de preferencias antes de emitir comandos de canal. Las preferencias se pueden almacenar en caché en Redis, pero el valor autoritativo permanece en un almacén duradero. Los eventos de invalidación de caché se emiten cada vez que cambian las preferencias.

El almacén de la bandeja de entrada debe ser una base de datos de clave-valor o de columna ancha escalable horizontalmente como DynamoDB, Cassandra o ScyllaDB. DynamoDB ofrece una menor carga operativa y opciones multirregión administradas; Cassandra o ScyllaDB pueden ser más baratos a gran escala sostenida pero requieren más experiencia operativa. Una base de datos relacional es menos adecuada para la bandeja de entrada principal porque el volumen de escritura, el crecimiento de las particiones y la escalabilidad entre fragmentos serían costosos.

Redis puede almacenar en caché los recuentos de no leídos y la primera página de la bandeja de entrada, pero no debe ser el sistema de registro. Las puertas de enlace WebSocket no tienen estado, aparte del estado de conexión activa. Un directorio de presencia en Redis o un almacén efímero similar mapea usuarios a instancias de puerta de enlace.

MODELO DE DATOS

Un registro de notificación contiene notification_id, recipient_user_id, type, actor_user_id, object_type, object_id, creation_time, template_version, datos de renderizado compactos, read_time e información de agrupación opcional. El estado del canal debe contener los canales solicitados y el estado de entrega, como pendiente, enviado, fallido o suprimido. Los cuerpos grandes y el contenido social mutable no deben copiarse en el registro a menos que se requiera una instantánea inmutable.

Una clave de bandeja de entrada adecuada es partition_key = recipient_user_id más un cubo de tiempo opcional, y sort_key = reverse_timestamp más notification_id. La clasificación cronológica inversa hace que la página más reciente sea eficiente. Con un volumen normal, una partición por usuario es suficiente; las cuentas excepcionalmente activas pueden usar cubos mensuales. La API consulta primero el cubo más nuevo y sigue un cursor opaco hacia cubos más antiguos.

El requisito solo expone las últimas 100 notificaciones. El servicio puede retener algo más, como de 30 a 90 días, y aplicar la expiración TTL, mientras que la API de lectura devuelve como máximo 100. Recortar o expirar registros de forma asíncrona es más seguro y económico que realizar una eliminación síncrona en cada inserción. Si se requiere el almacenamiento físico estricto de exactamente 100 registros, un compactador en segundo plano puede eliminar las entradas más antiguas.

Las preferencias se indexan por ID de usuario y contienen configuraciones por tipo y por canal, por ejemplo, likes.push, likes.email, comments.push y comments.email, además de silenciar globalmente, idioma, zona horaria y una versión que aumenta monótonamente. Los tokens de dispositivo se almacenan por separado por ID de usuario y ID de dispositivo, con plataforma, token, hora de última vista y estado de validez. Los tokens deben cifrarse e invalidarse después de errores permanentes de APNs o FCM.

Un ID de notificación determinista se puede derivar de source_event_id, recipient_user_id, tipo de notificación y versión semántica. La escritura en la bandeja de entrada es condicional a ese ID, lo que hace que la repetición y el consumo duplicado sean seguros. Un comando de entrega tiene un ID determinista similar basado en el ID de notificación y el canal.

SEMÁNTICA DE ENTREGA Y FIABILIDAD

La garantía práctica es un procesamiento duradero de al menos una vez con efectos idempotentes. La entrega exactamente una vez a través de bases de datos, Kafka, APNs, FCM y correo electrónico no es factible de extremo a extremo. Las outboxes transaccionales garantizan que las acciones de origen aceptadas se publiquen eventualmente. La replicación de Kafka y las escrituras confirmadas evitan la pérdida de colas. Las escrituras condicionales en la bandeja de entrada suprimen registros duplicados. Los trabajadores de canal almacenan o deduplican de otra manera los ID de intentos de entrega, lo que reduce los envíos duplicados durante los reintentos.

Una notificación se considera aceptada solo después de que la transacción de origen que contiene su fila de outbox se confirme. Se considera creada de forma duradera después de que la escritura en la bandeja de entrada tenga éxito. Los offsets de Kafka solo se confirman después de que se haya completado la escritura duradera o la entrega al proveedor correspondiente. Los fallos transitorios utilizan retroceso exponencial con fluctuación. Después de un número limitado de intentos, los comandos se mueven a un tema de mensajes fallidos con el error, la referencia de la carga útil y el historial de reintentos.

Los proveedores móviles y la infraestructura de correo electrónico no pueden garantizar que un dispositivo o buzón presente una notificación en menos de dos segundos. Por lo tanto, el servicio debe definir el objetivo de latencia como el tiempo desde el evento de origen confirmado hasta la visibilidad en la bandeja de entrada duradera y el primer envío al proveedor. Un SLO razonable es el 99 % en menos de dos segundos bajo carga admitida. Las confirmaciones de APNs y FCM significan la aceptación del proveedor, no la visualización por parte del usuario. La bandeja de entrada duradera garantiza que las interrupciones del proveedor o los dispositivos sin conexión no pierdan la notificación del historial del usuario.

Para los clientes actualmente conectados, la ruta WebSocket normalmente proporciona la entrega más rápida. Los mensajes WebSocket transportan ID de notificación, y los clientes los deduplican contra los registros de la bandeja de entrada recuperados. Al reconectarse, los clientes recuperan notificaciones después de su último cursor, por lo que los mensajes de socket perdidos no crean brechas.

ESCALABILIDAD

Los temas de Kafka deben comenzar con suficientes particiones para el paralelismo esperado y expandirse antes de alcanzar los límites de rendimiento de las particiones. La partición por ID de destinatario distribuye a los usuarios normales de manera uniforme. Los eventos de celebridades no deben usar el ID del actor como clave de partición porque eso crea una partición caliente. La expansión de destinatarios puede dividir una audiencia grande en fragmentos y publicar cada fragmento de forma independiente.

Los procesadores, las puertas de enlace WebSocket y los trabajadores de canal no tienen estado y son escalables horizontalmente. La escalabilidad automática debe considerar el rezago de Kafka y la antigüedad del mensaje más antiguo en lugar de solo la CPU. Grupos de consumidores y cuotas separados aíslan los mensajes directos de los me gusta y correos electrónicos de menor prioridad. Bajo sobrecarga, se reserva capacidad para mensajes directos y comentarios, mientras que los correos electrónicos y los me gusta de baja prioridad pueden encolarse sin ser descartados.

La capacidad de la bandeja de entrada crece linealmente con los usuarios, pero se mantiene limitada por el TTL y el requisito de historial limitado. Con 100 millones de DAU y 20 notificaciones por día, el diseño debe manejar aproximadamente dos mil millones de escrituras diarias. Las particiones de usuario con cubos de tiempo, la capacidad de base de datos bajo demanda o aprovisionada, los registros compactos comprimidos y la ausencia de distribución síncrona de índices secundarios lo mantienen manejable. Las consultas globales costosas deben atenderse desde un pipeline de análisis, no desde la bandeja de entrada transaccional.

ALTA DISPONIBILIDAD Y RECUPERACIÓN ANTE DESASTRES

Cada componente síncrono se ejecuta en al menos tres zonas de disponibilidad detrás de balanceadores de carga con comprobación de estado. Kafka utiliza un factor de replicación de tres con configuraciones de confirmación sólidas y un recuento mínimo apropiado de réplicas en sincronización. Los almacenes de bandeja de entrada y preferencias utilizan replicación multizona y copias de seguridad puntuales. Los despliegues utilizan estrategias canary o de rodadura, esquemas de eventos compatibles con versiones anteriores y versionado de esquemas a través de un registro.

Un diseño inicial rentable utiliza una región activa con redundancia multizona y una región de espera en caliente replicada asíncronamente. Los procedimientos de recuperación promueven la espera, restauran los consumidores a partir de offsets replicados o eventos retenidos y reproducen de forma segura porque el procesamiento es idempotente. Para una disponibilidad regional más estricta, el sistema puede evolucionar a ingesta regional activa-activa, con usuarios asignados a una región de origen y IDs de eventos globalmente únicos. Activo-activo mejora el tiempo de recuperación pero aumenta el costo de la base de datos, el manejo de duplicados, la complejidad del orden y los desafíos de consistencia de preferencias.

Los cambios de preferencias deben utilizar escrituras fuertemente consistentes en la región de origen del usuario. Una notificación ya creada de forma duradera antes de un cambio de preferencia aún puede entregarse; este límite debe documentarse. Para la supresión o eliminación de cuentas legalmente requeridas, los trabajadores deben realizar una verificación autoritativa adicional inmediatamente antes de la entrega externa.

OPTIMIZACIONES DE LATENCIA

La ruta crítica no contiene llamadas síncronas a los proveedores de APNs, FCM o correo electrónico. Las cargas útiles de eventos incluyen metadatos de actor y objeto suficientes para la renderización básica, evitando múltiples llamadas a servicios posteriores. La falta de enriquecimiento opcional debe producir una notificación genérica en lugar de bloquear la entrega. Los registros de preferencias y las plantillas se almacenan en caché localmente o en Redis, y las conexiones a Kafka, bases de datos y proveedores se agrupan.

La renderización y el envío de correo electrónico utilizan un tema separado porque el correo electrónico es más lento y costoso que la entrega en la aplicación. Si los requisitos del producto lo permiten, los

Resultado

#1 | Ganador

Votos ganadores

3 / 3

Puntuación media

90
Modelos evaluadores OpenAI GPT-5.5

Puntuación total

93

Comentario general

La respuesta B es un diseño excepcionalmente completo y bien razonado. Separa claramente la creación de la bandeja de entrada duradera de los intentos de entrega externos, incluye el manejo transaccional de la bandeja de salida, colas específicas para el destinatario, procesamiento idempotente de al menos una vez, trabajadores específicos del canal, diseño de almacenamiento escalable, comportamiento de la API, HA/DR, observabilidad, seguridad, consideraciones de costos y análisis de compensaciones matizadas. Es un poco largo, pero la estructura sigue siendo clara y el detalle añadido es directamente relevante para los requisitos de diseño del sistema.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
92

La respuesta B proporciona una arquitectura muy sólida con outbox transaccional, temas de origen de Kafka, procesadores sin estado, almacén de bandeja de entrada duradero, temas de comandos específicos del canal, trabajadores WebSocket/APNs/FCM/email, API gateway y APIs de lectura. La separación entre la creación de notificaciones duraderas y los intentos de entrega está especialmente bien diseñada.

Integridad

Peso 20%
94

La respuesta B aborda casi todos los requisitos especificados e implícitos en profundidad, incluyendo historial, preferencias, múltiples canales, recuentos de no leídos, tokens de dispositivo, reintentos, DLQs, puntos finales de API, observabilidad, seguridad, retención, HA/DR y escalado futuro a 100 millones de DAU. También maneja casos matizados como preferencias obsoletas, limitaciones del proveedor y comportamiento de reconexión.

Análisis de compromisos

Peso 20%
93

La respuesta B demuestra un razonamiento profundo sobre las compensaciones en toda la propuesta, incluyendo infraestructura administrada vs. autogestionada, durabilidad primero en la bandeja de entrada vs. latencia, al menos una vez vs. exactamente una vez, regiones activo-pasivo vs. activo-activo, obsolescencia de la caché de preferencias, partición de destinatarios vs. ordenamiento global, y costo vs. rendimiento.

Escalabilidad y fiabilidad

Peso 20%
95

La respuesta B es excelente en escalabilidad y confiabilidad. Cubre la planificación de la capacidad de tasa de destinatarios, la mitigación de hot fan-out, la estrategia de partición, el escalado automático por rezago y antigüedad del mensaje más antiguo, IDs deterministas idempotentes, escrituras condicionales, reglas de confirmación de offset, DLQs, repetición, despliegue multi-AZ, standby en caliente, evolución activo-activo y límites de falla del proveedor externo.

Claridad

Peso 10%
89

La respuesta B es muy clara y organizada, con secciones bien etiquetadas y una redacción precisa. Es más larga y densa que la respuesta A, pero el detalle es relevante y el diseño principal sigue siendo fácil de entender.

Modelos evaluadores Anthropic Claude Opus 5

Puntuación total

86

Comentario general

La respuesta B es un diseño más profundo y operativamente maduro. Establece la bandeja de entrada duradera como el sistema de registro y deriva las entregas de canales de ella, utiliza outboxes transaccionales y temas de comandos por canal con identificadores deterministas y escrituras condicionales, y define límites precisos de aceptación/durabilidad con ordenación de confirmación de desplazamiento. Va mucho más allá de A en el diseño de API, consistencia de recuento no leído, partición por intervalos de tiempo, alta disponibilidad entre zonas, recuperación ante desastres y conmutación por error regional, aislamiento de prioridad bajo sobrecarga, observabilidad con sondas sintéticas e inyección de fallos, y seguridad/privacidad. También reformula críticamente el objetivo de latencia de 2 segundos como un SLO en la visibilidad de la bandeja de entrada y el despacho del proveedor, una visión genuinamente senior. Su principal debilidad es la presentación: prosa densa e ininterrumpida sin diagramas, tablas ni esquemas formateados, lo que la hace más difícil de hojear que A.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
87

Arquitectura muy sólida: outbox transaccional con publicadores estilo CDC, temas de origen de Kafka, procesador de notificaciones sin estado que escribe la bandeja de entrada duradera como fuente de verdad, luego temas de comandos duraderos por canal consumidos por trabajadores de push/email/WebSocket. Separa explícitamente las rutas de escritura y lectura, incluye una puerta de enlace API y una API de notificaciones con puntos finales concretos, directorio de presencia y grupos de trabajadores separados para alta dispersión. El diseño del tema de comandos de canal y el marco de 'bandeja de entrada como fuente de verdad' son más rigurosos que el modelo de despachador de A. El único inconveniente es la ausencia de un diagrama visual, aunque el flujo textual es explícito.

Integridad

Peso 20%
88

Cubre esencialmente todos los requisitos y más: estimaciones de capacidad tanto para el uso actual como para 100 millones de DAU, modelo de datos con claves de partición/ordenación y agrupación por tiempo, versionado de preferencias y invalidación de caché, ciclo de vida del token del dispositivo y cifrado, API REST explícita con cursores y claves de idempotencia, consistencia de recuento no leído, alta disponibilidad en tres zonas, recuperación ante desastres con standby en caliente y procedimiento de conmutación por error, observabilidad con canarios sintéticos, y seguridad/privacidad incluyendo previsualizaciones en pantalla de bloqueo y residencia de datos. Muy pocas lagunas.

Análisis de compromisos

Peso 20%
85

Las compensaciones están integradas en todo el documento y consolidadas en una sección de costos: Kafka frente a llamadas síncronas, administrado frente a autoalojado, DynamoDB frente a Cassandra/ScyllaDB, costo de latencia de escritura-antes-del-despacho de la bandeja de entrada, al menos una vez con identificadores deterministas, ordenación por usuario frente a global, estado obsoleto de la caché frente a corrección con una verificación autorizada previa al envío para supresión legal, activo-activo frente a standby en caliente, y agrupación de resúmenes como una decisión de producto explícita. Notablemente, también desafía la premisa de la SLA de 2 segundos, redefiniendo la latencia como la confirmación de origen a la bandeja de entrada duradera y el primer despacho del proveedor, una visión de nivel genuinamente senior. El formato es menos escaneable que la tabla de A.

Escalabilidad y fiabilidad

Peso 20%
89

Excepcionalmente exhaustivo: objetivos de sobreaprovisionamiento por encima del pico calculado, partición por clave de destinatario con advertencia explícita contra particiones calientes por clave de actor, expansión de destinatarios en fragmentos, escalado automático por retraso y antigüedad del mensaje más antiguo en lugar de CPU, grupos de consumidores y cuotas separados para priorizar los mensajes directos sobre los 'me gusta' bajo sobrecarga, confirmación de desplazamiento solo después de escritura duradera, escrituras condicionales para deduplicación, DLQ con repetición, RF=3 con min-ISR, multi-AZ, DR con standby en caliente y repetición idempotente, almacenamiento limitado por TTL y análisis de 2 mil millones de escrituras diarias a 100 millones de DAU. La inyección de fallos y los ejercicios de runbook añaden credibilidad operativa.

Claridad

Peso 10%
74

Bien organizado con encabezados de sección claros y prosa técnica precisa y densa, pero son párrafos uniformemente largos sin diagramas, sin tablas y sin esquemas formateados en código. Mayor carga cognitiva y más difícil de hojear, aunque el contenido en sí es inequívoco y está lógicamente ordenado.

Modelos evaluadores Google Gemini 2.5 Pro

Puntuación total

92

Comentario general

La Respuesta B es una propuesta de diseño de sistemas excepcional e integral que demuestra un profundo nivel de experiencia. No solo cumple con todos los requisitos, sino que va significativamente más allá, discutiendo aspectos críticos como el diseño de API, la seguridad, estrategias detalladas de alta disponibilidad/recuperación ante desastres y la observabilidad con rigor profesional. Las elecciones arquitectónicas son matizadas y están bien justificadas, y la discusión sobre escalabilidad y confiabilidad es particularmente detallada y práctica. Si bien su prosa densa la hace un poco menos accesible que la Respuesta A, su profundidad técnica y su integridad son sobresalientes.

Ver detalle de evaluación

Calidad de la arquitectura

Peso 30%
90

La arquitectura está excepcionalmente bien concebida, mostrando una comprensión madura de los sistemas distribuidos. Enfatiza correctamente el patrón outbox transaccional desde el principio y propone un flujo refinado con temas separados para eventos de origen y comandos de canal. La inclusión de la puerta de enlace API y las consideraciones de diseño de API hacen que la arquitectura sea más completa.

Integridad

Peso 20%
95

Esta respuesta es excepcionalmente completa. No solo cubre todos los requisitos del prompt, sino que también profundiza en áreas relacionadas cruciales como el diseño de API, la seguridad y la privacidad, estrategias detalladas de alta disponibilidad y recuperación ante desastres, y la observabilidad. Este enfoque integral refleja una mentalidad holística y lista para producción.

Análisis de compromisos

Peso 20%
90

La discusión de los compromisos es sofisticada y está integrada en todo el diseño, con un resumen conciso al final. Cubre una amplia gama de decisiones, desde las elecciones tecnológicas hasta patrones arquitectónicos como modelos de disponibilidad regional y semánticas de entrega, mostrando una profunda experiencia.

Escalabilidad y fiabilidad

Peso 20%
95

El tratamiento de la escalabilidad y la confiabilidad es sobresaliente. Proporciona estrategias muy específicas y prácticas, como la partición por ID de destinatario para evitar puntos calientes inducidos por celebridades, el uso de colas de prioridad y la definición de SLO de latencia realistas. La sección detallada sobre alta disponibilidad/recuperación ante desastres es una fortaleza significativa.

Claridad

Peso 10%
85

La respuesta está bien estructurada y escrita con precisión técnica. Sin embargo, su prosa es bastante densa y la falta de ayudas visuales como diagramas o tablas la hace un poco menos accesible de inmediato que la Respuesta A, requiriendo una lectura más enfocada para comprender completamente todos los detalles.

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

0 / 3

Puntuación media

83
Ver esta respuesta

Votos ganadores

3 / 3

Puntuación media

90
Ver esta respuesta

Resultados de evaluación

Modelos evaluadores Google Gemini 2.5 Pro

Motivo del ganador

La Respuesta B es la clara ganadora debido a su profundidad, exhaustividad y matices técnicos superiores. Si bien la Respuesta A proporciona un diseño muy bueno y estándar, la Respuesta B opera a un nivel superior de detalle y previsión, característico de un ingeniero senior. Aborda consideraciones críticas del mundo real que A pasa por alto, como el diseño de API, la seguridad y planes detallados de recuperación ante desastres. Las discusiones de B sobre escalabilidad (por ejemplo, manejo de la distribución de fans de celebridades) y confiabilidad (por ejemplo, definición de SLOs realistas) son más avanzadas y prácticas. Estas fortalezas en los criterios más ponderados —arquitectura, exhaustividad y escalabilidad/confiabilidad— la convierten en la mejor respuesta.

Modelos evaluadores Anthropic Claude Opus 5

Motivo del ganador

La respuesta B gana en el resultado ponderado. Supera a la A en calidad de arquitectura (30%) a través del modelo de bandeja de entrada como fuente de verdad, la separación explícita de rutas de lectura/escritura y los temas de comandos por canal, y gana de manera decisiva en completitud (20%), escalabilidad y confiabilidad (20%), y razonamiento de compensación (20%) al agregar diseño de API, HA/DR, aislamiento de prioridad, semántica de confirmación de desplazamiento, seguridad, observabilidad y un reencuadre crítico del SLO de latencia. La respuesta A es claramente mejor en claridad (10%) gracias a su diagrama, tablas y estructura, pero esa única ventaja ligeramente ponderada no puede compensar la superioridad de B en los cuatro criterios más pesados.

Modelos evaluadores OpenAI GPT-5.5

Motivo del ganador

La respuesta B gana porque proporciona un diseño más completo y técnicamente preciso en los criterios fuertemente ponderados. Ambas respuestas proponen arquitecturas sólidas basadas en eventos, pero B define de manera más explícita las semánticas de entrega, los límites de fallos, el comportamiento de repetición, la alta disponibilidad y la recuperación ante desastres, el manejo de sobrecargas, el comportamiento de la API, las consideraciones de seguridad/privacidad y las compensaciones de costos. Su discusión sobre confiabilidad y escalabilidad es más profunda y está más fundamentada operativamente, al tiempo que aborda todos los requisitos funcionales.

X f L