Ir al contenido principal
Arquitectura & Backend · 7 min

Arquitectura de un motor de autopujas en tiempo real: ejecución en los últimos 5 segundos con .NET y Laravel

Cómo construir un sistema que ingesta más de 300.000 subastas públicas y privadas y ejecuta pujas en los últimos 5 segundos sin bloqueos de base de datos ni caídas por concurrencia.

Pablo Fesa
Pablo Fesa Software Architect & Tech Lead

Cuando un inversor programa una puja automática en una subasta judicial de cientos de miles de euros, el margen de error técnico es exactamente cero.

En plataformas como el Portal de Subastas del BOE o la Seguridad Social, las pujas emitidas durante los últimos minutos suelen activar prórrogas automáticas de tiempo. Sin embargo, en subastas privadas y liquidaciones de activos, la ventana crítica de cierre se concentra en los últimos 5 a 10 segundos. Si tu servicio sufre un bloqueo de fila en la base de datos, una pausa del recolector de basura o un pico de latencia en la red, la puja no entra y el cliente pierde la adjudicación.

En este artículo detallo la arquitectura desacoplada que diseñamos para Diario de Subastas, combinando Laravel 11 para la ingesta y gestión del catálogo con un microservicio especializado en .NET para la ejecución en tiempo real.

El problema de acoplar la web al motor de ejecución

En las primeras fases de una plataforma legaltech, la tentación habitual es utilizar el mismo backend web (PHP/Laravel con colas tipo Redis y Horizon) para gestionar tanto la interfaz de usuario como la ejecución de las pujas programadas.

Esto funciona bien con diez subastas al día. Pero cuando monitorizas miles de lotes concurrentes con cierres simultáneos a las 18:00 de la tarde, surgen problemas de saturación:

  1. Retención de conexiones y bloqueos en base de datos: si cientos de procesos intentan leer y actualizar el estado de las mismas tablas transaccionales en el mismo segundo, los bloqueos a nivel de fila (SELECT ... FOR UPDATE) degradan rápidamente el pool de conexiones de MySQL.
  2. Latencia variable en el entorno de ejecución: aunque PHP 8.2 y 8.4 con OPcache ofrecen un rendimiento sobresaliente en la capa web, la ejecución de timers de alta precisión (para disparar exactamente en la ventana de T-5 segundos) requiere un runtime compilado con hilos dedicados y un consumo de memoria plano.

La solución: separación de planos de control y ejecución

Para garantizar que ninguna puja fallara por causas técnicas, desacoplamos la plataforma en dos componentes independientes:

[Ingesta Masiva: 25+ Scrapers] ──► [Laravel 11: Catálogo & API]
                                            │
                                            ▼
                               [Cola Persistente Redis / DB]
                                            │
                                            ▼
                             ┌──────────────────────────────┐
                             │   Motor Autónomo en .NET     │
                             │   - Timers de alta precisión │
                             │   - Pool HTTP precalentado   │
                             │   - Monitor de prórrogas     │
                             └──────────────┬───────────────┘
                                            │
                                            ▼
                             [Portales Oficiales / BOE]

1. Plano de Control en Laravel 11

  • Ingesta en paralelo: 55 comandos Artisan coordinan scrapers distribuidos que procesan 25 fuentes oficiales y privadas en menos de 60 minutos.
  • Normalización de datos: 88 modelos de dominio limpian referencias catastrales, depósitos exigidos y estados procesales.
  • Validación de saldo y mandatos: antes de que una puja se marque como programable, se comprueban fondos y límites de puja máxima configurados por el usuario.

2. Motor de Ejecución en .NET

  • Carga en memoria anticipada: 60 segundos antes del cierre del lote, el servicio en .NET precarga el token de autenticación del portal objetivo, los parámetros de la puja y las credenciales firmadas.
  • Sockets y conexiones HTTP precalentadas: elimina la latencia del handshake TLS en el momento crítico. La conexión con el portal de subastas ya está abierta y lista.
  • Detección de prórrogas dinámicas: si otro postor puja en el segundo 4 y el portal amplía el cierre en dos minutos, el worker detecta la nueva hora de fin de forma reactiva y reprograma su temporizador sin reencolar peticiones pesadas.

Tres decisiones clave que evitaron desastres en producción

  1. Idempotencia estricta en las peticiones: en subastas oficiales, una duplicación accidental de puja puede comprometer el doble del capital del cliente. Cada intento de puja genera una clave de idempotencia única basada en el hash de la subasta, el importe y el timestamp de autorización.
  2. Aislamiento de fallos de red: si el portal de subastas objetivo sufre una caída de servicio o lentitud extrema en sus propios servidores, el motor registra la traza exacta de red con capturas de respuesta para auditar que el fallo fue externo y no del sistema interno.
  3. Métricas en tiempo real sin impacto en la base de datos transaccional: los eventos de telemetría se emiten hacia colas en memoria y almacenamiento en series temporales, evitando escrituras síncronas que compitan con las tablas de pujas activas.

Resultado operativo

Desde la implantación de esta arquitectura desacoplada, el sistema ha procesado más de 300.000 subastas judiciales y privadas, manteniendo un registro de cero fallos técnicos en las pujas programadas por los inversores.

La lección de ingeniería es clara: utiliza la herramienta óptima para cada responsabilidad. Laravel es imbatible para modelar dominios de negocio complejos, APIs y paneles operativos con velocidad y elegancia; los lenguajes compilados como .NET o Rust son el aliado perfecto cuando la estabilidad de ejecución en caliente en los últimos segundos decide el resultado.

Temas: #Laravel #.NET #Sistemas Distribuidos #Rendimiento #MySQL
Sigue leyendo

Artículos Relacionados

¿Necesitas diseñar sistemas resistentes sin sobrecostes de infraestructura?

Hablemos 15 minutos en una sesión de diagnóstico técnico con Pablo para auditar tus cuellos de botella y definir la arquitectura adecuada.