VBET
VBET: analítica sobre un SQL Server que no podíamos cambiar
La base era de otro equipo. El dashboard necesitaba dejar de depender de un schema que no controlábamos.
~7 min → <1 s comisiones, de la carga original a la caché caliente
Cada estágio corresponde a uma decisão incremental documentada no case. Números de outras histórias não entram neste desenho.
Contexto
En VBET, entre octubre de 2023 y febrero de 2025, el producto de analítica servía a influencers y afiliados de iGaming. El dashboard reunía decenas de métricas; la comisión era la lectura más crítica. Los influencers aceptaban un pequeño desfase en los datos del día, siempre que la pantalla respondiera. El pago dependía de datos consolidados del día anterior, no del valor en vivo.
Restricciones
El SQL Server era externo, compartido y no modificable de forma fiable. Los índices temporales podían ser eliminados por el propietario de la base. La API original mezclaba consultas SQL construidas a partir de parámetros, con riesgo de inyección, y agregaba demasiado en memoria.
Problema
El sistema había sido dimensionado para influencers más pequeños. Con bases mayores, el peor pico del dashboard llegó a cerca de siete minutos. Seguridad y mantenibilidad vinieron antes del rendimiento: queries crudas, poca cobertura de pruebas y un camino síncrono que recalculaba demasiado en cada request.
Decisión
La evolución fue incremental, en el orden en que aparecieron las restricciones:
- eliminar SQL inseguro, parametrizar el acceso, documentar y probar;
- optimizar queries e índices temporales, como mitigación y no como invariante;
- paralelizar consultas independientes con Go, goroutines y channels;
- cuando el cuello de botella volvió al SQL Server, crear ETL y PostgreSQL propios, con precálculo, checkpoints y reconciliación;
- separar lectura REALTIME (tendencia, consistencia eventual) de CLOSED (precisión financiera y pago);
- cache-aside con TTL alineado al desfase aceptado de cerca de cinco minutos;
- degradación controlada si fallaba la caché, en lugar de tumbar la pantalla.
Alternativa descartada
Insistir en índices en la base externa como arquitectura, o recalcular años de historial en cada acceso. También se descartó la idea de pagar al afiliado con el dato REALTIME.
Resultado
La línea reconciliada en el dosier de la experiencia, para el camino de comisión/dashboard, es:
- peor pico inicial: cerca de 7 minutos;
- tras queries e índices: cerca de 3 minutos;
- tras paralelización: cerca de 1 minuto;
- tras ETL/PostgreSQL: cerca de 15 segundos en el p99 de la comisión sin caché;
- caché caliente: menos de 1 segundo.
Cada número pertenece a esa etapa. No describe la ganancia de una descomposición posterior en microservicios.
Limitaciones
La investigación, la decisión de ETL + base propia, la separación REALTIME/CLOSED y la política de degradación son el núcleo atribuible aquí. La descomposición del monolito en Kubernetes es otra historia y no mezcla el “500%” ni la latencia por debajo de 60 ms con este caso. Versiones antiguas de currículo que citan 30 segundos en carga fría, 11 segundos o porcentajes de SLA sin escenario quedan fuera. Si el producto pasa a exigir precisión realtime en el pago, la separación CLOSED deja de ser suficiente.