Volver al Blog
Tiempo Real WebSockets Backend FastAPI

WebSockets Escalables: Sistemas en Tiempo Real

Escrito por Marlon

La Ineficiencia del Polling: Por Qué las Peticiones HTTP Agotan el Rendimiento de tu Plataforma

En el desarrollo de productos digitales modernos, la respuesta en tiempo real ya no es una característica opcional: es una expectativa del usuario. Quienes interactúan con chats corporativos, dashboards financieros o sistemas de geolocalización esperan ver cambios al instante. Sin embargo, muchos equipos de desarrollo aún dependen del polling tradicional (consultas periódicas HTTP de corta o larga duración) para simular esta interactividad.

El polling consiste en hacer que el cliente (el navegador o la app móvil) realice peticiones HTTP repetitivas al servidor cada pocos segundos para verificar si hay datos nuevos. Esta práctica genera una sobrecarga crítica en la infraestructura:

  • Cabeceras HTTP pesadas: Cada petición HTTP transmite cookies, tokens de autorización y metadatos de red, consumiendo ancho de banda innecesario para actualizaciones minúsculas.
  • Saturación en la Base de Datos: Cientos de usuarios concurrentes generan miles de consultas de lectura por minuto, incluso cuando no ha ocurrido ningún cambio en el sistema.
  • Cómputo Desperdiciado: Los hilos del servidor web se mantienen ocupados procesando conexiones efímeras, elevando drásticamente los costos de hosting en la nube (AWS, GCP).

Para soportar miles de conexiones simultáneas optimizando los costos de infraestructura, debemos abandonar el modelo tradicional de petición-respuesta y migrar a canales bidireccionales persistentes utilizando WebSockets.


Conexiones Persistentes y Bidireccionales: El Poder de los WebSockets

A diferencia del protocolo HTTP, que abre y cierra una conexión TCP para cada transacción, el protocolo WebSocket inicia con un apretón de manos (handshake) HTTP y actualiza la conexión a un canal TCP de larga duración.

Esta conexión persistente se mantiene abierta durante toda la sesión del usuario, lo que permite:

  1. Comunicación de Ultra Baja Latencia: Los datos se transmiten en tramas (frames) extremadamente ligeras con una sobrecarga de cabecera de apenas 2 a 10 bytes.
  2. Push del Servidor: El backend puede enviar datos al cliente en el milisegundo exacto en que ocurren, sin esperar a que el cliente los solicite.
  3. Comunicación Full-Duplex: Tanto el cliente como el servidor pueden enviar y recibir datos de manera simultánea en el mismo canal, minimizando el consumo de sockets en el sistema operativo.

El Desafío de Escalar: Orquestación Distribuida con Redis Pub/Sub

Los WebSockets son conexiones con estado (stateful). Cuando un cliente se conecta, la sesión física se vincula a una instancia específica del servidor de backend. Al escalar horizontalmente la aplicación (añadir más nodos de servidor tras un balanceador de carga), surge un reto arquitectónico:

                    +------------------------+
                    |  Balanceador de Carga  |
                    +------------+-----------+
                                 |
                 +---------------+---------------+
                 |                               |
                 v                               v
         +-------+-------+               +-------+-------+
         | Nodo ServidorA|               | Nodo ServidorB|
         +-------+-------+               +-------+-------+
                 |                               |
           Cliente 1 (WS)                  Cliente 2 (WS)

Si el Cliente 1 está conectado al Servidor A y el Cliente 2 al Servidor B, el Servidor A no puede enviar un mensaje directamente al Cliente 2 porque la conexión de socket de este último vive únicamente en la memoria del Servidor B.

Para resolver esto y propagar eventos entre todos los nodos sin perder mensajes, implementamos una capa intermedia de mensajería utilizando Redis Pub/Sub.

Cuando el Servidor A necesita emitir un evento, lo publica en un canal centralizado de Redis. Todas las instancias del servidor backend están suscritas a este canal, de modo que reciben la notificación al instante y la reenvían a los clientes locales correspondientes.


Código en Acción: Un Router WebSocket Escalable en FastAPI

El siguiente ejemplo muestra cómo estructurar esta arquitectura de manera eficiente en Python utilizando FastAPI y el cliente asíncrono de Redis:

import asyncio
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from redis.asyncio import Redis

app = FastAPI()
# Conexión asíncrona a Redis
redis = Redis(host="localhost", port=6379, decode_responses=True)

class ConnectionManager:
    def __init__(self):
        self.active_connections: list[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            try:
                await connection.send_text(message)
            except Exception:
                # Limpieza silenciosa de conexiones huérfanas
                pass

manager = ConnectionManager()

async def redis_listener():
    """Tarea en segundo plano para escuchar eventos en Redis y retransmitirlos."""
    pubsub = redis.pubsub()
    await pubsub.subscribe("websocket_events")
    async for message in pubsub.listen():
        if message["type"] == "message":
            await manager.broadcast(message["data"])

@app.on_event("startup")
async def startup_event():
    # Iniciar el oyente de Redis al arrancar la aplicación
    asyncio.create_task(redis_listener())

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        while True:
            # Escucha mensajes del cliente y los publica en Redis Pub/Sub
            data = await websocket.receive_text()
            await redis.publish("websocket_events", data)
    except WebSocketDisconnect:
        manager.disconnect(websocket)

Mitigación de Fallos de Red y Reconexiones

En producción, las conexiones móviles o de oficina sufren microcortes de red. Para evitar la pérdida de interactividad, es crucial implementar estrategias de reconexión con retraso exponencial en el frontend (por ejemplo, reintentar la conexión tras 1s, 2s, 4s, 8s, hasta un límite) y mantener un buffer temporal de mensajes en el cliente.


Impacto Comercial: Experiencia Premium y Optimización de Costos en la Nube

Para las startups y medianas empresas de la región (Perú y Latinoamérica), el desarrollo de sistemas en tiempo real tiene un impacto directo en el negocio:

  • Ahorro Directo de Recursos Cloud: Al reducir miles de consultas HTTP redundantes a unas pocas conexiones de sockets abiertas, el uso de CPU y transferencia de datos disminuye drásticamente, optimizando tu gasto en infraestructura.
  • Retención de Usuarios: Una aplicación que responde al milisegundo (por ejemplo, notificaciones instantáneas de pedidos o cambios en un panel operativo) incrementa el valor percibido del producto digital y la satisfacción del cliente.
  • Operaciones Eficientes: Automatizar flujos internos en tiempo real reduce los tiempos de espera y optimiza la productividad del equipo de trabajo.

Construye Sistemas en Tiempo Real con el Factor Senior + IA

Implementar sistemas distribuidos con alta concurrencia requiere dominar la programación asíncrona, la administración de sockets en Linux y el comportamiento de capas middleware de mensajería.

Bajo la fórmula del Factor Senior + IA, unimos más de una década de experiencia en diseño de sistemas distribuidos y Clean Architecture con el uso preciso de herramientas de Inteligencia Artificial. Esto nos permite diseñar, probar y desplegar arquitecturas de WebSockets estables y de alta densidad hasta 3 veces más rápido, ofreciendo robustez de nivel empresarial a costos sumamente competitivos.


Impulsa tu Plataforma hacia el Tiempo Real

No permitas que las consultas HTTP lentas frenen la experiencia de tus clientes y aumenten innecesariamente tus facturas en la nube. Diseñar una arquitectura basada en WebSockets y Redis es una de las decisiones técnicas con mayor retorno para empresas que buscan crecer.

¿Listo para escalar tu arquitectura de software?

  • Agenda una Reunión: Book a Call para conversar sobre tus retos de latencia, concurrencia y backend en una llamada de descubrimiento de 15 minutos.
  • Cotiza por WhatsApp: Escríbeme directamente por WhatsApp para conversar sobre los requerimientos, costos y tiempos de entrega para tu plataforma.