main content

Cómo escalar una aplicación web a medida cuando crece tu negocio

Llevo años viendo el mismo guion. La aplicación funciona, el equipo la usa, el negocio crece. Un martes a las 11:20 alguien escribe en el canal de soporte que «el listado tarda raro». El backend responde en 800 ms lo que antes resolvía en 50. La CPU del servidor pasa picos del 95 % a media mañana. Y entonces aparece la pregunta inevitable: cómo escalar una aplicación web a medida cuando crece tu negocio sin tirar nada abajo y empezar de cero.

La buena noticia es que casi nunca hay que empezar de cero. La mala es que la gente subestima dos cosas: el coste real de escalar mal, y el coste de no escalar a tiempo. Según Gartner (2024), el 72 % de las aplicaciones empresariales a medida necesitan una intervención significativa de escalabilidad en los primeros tres años de vida productiva. No es un problema de mala ingeniería. Es física: el éxito genera carga, y la carga ilumina cuellos de botella que con diez usuarios eran invisibles.

Lo que viene a continuación es el orden en que yo abordo el problema cuando me siento delante de una aplicación que ya empuja: primero medir, después cachear, después distribuir, después romper en piezas si y solo si toca. Y, por encima de todo, vigilar la factura cloud antes de que la factura cloud te vigile a ti.

Vertical u horizontal: la primera bifurcación

La primera decisión es aburrida pero define todo lo demás: ¿agrandas el servidor que ya tienes o pones más servidores iguales?

Hacer la máquina más grande

Subir tamaño de instancia es lo más rápido. Más CPU, más RAM, discos más rápidos y a otra cosa. No requiere tocar la arquitectura.

  • Ventaja real: en AWS, Google Cloud o Azure redimensionas en minutos. Bien para apagar fuegos.
  • Techo y peaje: las instancias tienen tope. La m7i.48xlarge de AWS llega a 192 vCPUs y 768 GB de RAM, y a partir de cierto punto no hay margen. Y ojo con el coste, que escala feo: duplicar recursos suele costar entre 2,2x y 2,5x, no 2x. Quien venda lo contrario no ha pagado nunca una factura.
  • Cuándo te sirve: como respuesta de emergencia mientras planificas algo serio, o para bases de datos relacionales que se distribuyen mal.

Precios de referencia (AWS eu-west-1, bajo demanda): m7i.xlarge (4 vCPUs, 16 GB) ≈ 175 USD/mes. m7i.2xlarge (8 vCPUs, 32 GB) ≈ 350 USD/mes. m7i.4xlarge (16 vCPUs, 64 GB) ≈ 700 USD/mes. La progresión es lineal hasta que deja de serlo, y deja de serlo justo cuando más necesitas crecer.

Repartir entre más máquinas

Escalado horizontal: varias instancias clónicas detrás de un balanceador. El tráfico se reparte. Si una se cae, las otras absorben.

  • Ventaja real: no hay techo teórico. Los auto-scaling groups suben y bajan instancias según demanda. Pagas lo que usas, si lo configuras bien.
  • Peaje: tu app tiene que ser stateless. Si el servidor guarda sesiones en memoria local, archivos en disco, o cualquier estado en caliente, lo rompes. Las sesiones se van a Redis, los archivos a S3, los datos persistentes a una base compartida. Esto, si tu aplicación no nació pensada para ello, es trabajo serio, no un fin de semana.
  • Cuándo te sirve: cuando la vertical ya no llega o cuando necesitas SLA por encima del 99,9 %. Caer un servidor y que nadie se entere es un lujo que solo da el horizontal.

Precios de referencia: cuatro m7i.xlarge cuestan 700 USD/mes, lo mismo que una m7i.4xlarge, pero ganas tolerancia a fallos y elasticidad. Súmale un Application Load Balancer de AWS: unos 22 USD/mes fijos más 0,008 USD por hora de conexión activa.

Regla práctica del que ha estado allí

Sube vertical hasta 8-16 vCPUs. A partir de ahí, horizontal sale más barato y resiliente. Si tu app aguanta 500 peticiones por segundo sostenidas o el SLA pide más de 99,9 %, el horizontal no es opcional, es la única opción honesta.

Caching: el truco con mejor relación esfuerzo/impacto

Si me obligan a elegir una sola palanca, elijo caché sin pensarlo. Servir desde memoria en lugar de recalcular o reconsultar baja tiempos de respuesta entre un 80 % y un 99 %. No hay refactor de microservicios que iguale esa relación esfuerzo/impacto.

Redis como caché de aplicación

Redis es un almacén en memoria con latencias por debajo de 1 ms para GET/SET. El patrón es viejo y funciona:

  1. Llega la petición.
  2. Pregunto a Redis si tengo la respuesta cacheada.
  3. Si sí (cache hit), devuelvo en 1-5 ms y me voy.
  4. Si no (cache miss), voy a la base de datos, guardo el resultado en Redis con un TTL y respondo.

Un hit ratio del 85-95 % es perfectamente alcanzable en aplicaciones de negocio normales. Eso significa que solo entre el 5 % y el 15 % del tráfico toca tu base de datos. La diferencia en la factura de RDS al mes siguiente la notas.

Aviso para navegantes: invalidar caché bien es uno de los problemas difíciles de verdad de la informática. Que no te cuenten otra cosa. Empieza con TTLs cortos y conservadores, y endurece a medida que entiendes el patrón de cambio de tus datos.

Coste de referencia: una instancia gestionada ElastiCache cache.m7g.large (2 vCPUs, 6,38 GB) ≈ 108 USD/mes en eu-west-1.

Varnish como caché HTTP

Varnish se sitúa delante del servidor web y cachea respuestas HTTP enteras. Brilla en páginas iguales para todos: landings, catálogos, fichas de producto sin personalización.

Un Varnish con 4 GB de RAM puede atender más de 100.000 peticiones por segundo de contenido cacheado. Compáralo con las 500-2.000 que un servidor de aplicación típico puede generar dinámicamente y entiendes por qué la gente con tienda online lo monta el primero.

  • Cuándo sí: ecommerce, portales de contenido, dashboards donde los datos se refrescan cada minuto y no cada segundo.
  • Cuándo no: SaaS hiperpersonalizado donde cada respuesta es única. Ahí Varnish no te aporta y solo añade una pieza más que mantener.

Caché en la propia base de datos

PostgreSQL y MySQL cachean por su cuenta, pero lo hacen bien o mal según cómo los configures. En PostgreSQL, shared_buffers (recomendación clásica: 25 % de la RAM) y effective_cache_size (50-75 % de la RAM) deciden cuánta memoria se dedica a tener índices y datos calientes en RAM.

Una PostgreSQL con 32 GB de RAM y shared_buffers a 8 GB mantiene los índices y tablas más calientes en memoria. Lecturas de 5-15 ms a disco pasan a ser de 0,1 ms en RAM. Ajustar bien estos parámetros es la tarde más rentable que va a invertir tu DBA este trimestre.

CDN: traer el contenido al usuario, no al revés

Una CDN replica tu contenido estático (imágenes, CSS, JS, fuentes, vídeos) en nodos repartidos por el mundo. El usuario lo recibe del más cercano, no del tuyo.

Impacto medible

Para un usuario en Madrid contra una app en Irlanda, el RTT está entre 30 y 40 ms. Con un nodo CDN en Madrid, bajas a 5-10 ms. Multiplica por los 20-80 archivos estáticos que carga una web moderna y entiendes por qué la diferencia se nota en cualquier dispositivo que no esté en fibra.

Cloudflare (2024) publica que una CDN bien configurada baja el tiempo de carga de la primera visita entre un 40 % y un 60 % para usuarios lejanos al origen. No es marketing, es geometría.

Opciones razonables

  • Cloudflare: plan gratuito con CDN ilimitada, plan Pro desde 20 USD/mes con optimización de imagen y reglas avanzadas. Mínima fricción para empezar.
  • AWS CloudFront: se integra de forma natural con S3 y compañía. Pago por consumo: alrededor de 0,085 USD/GB transferido en Europa.
  • Fastly: CDN programable con Varnish dentro. La elige quien necesita purgar caché global en menos de 150 ms. Precio medio superior, orientado a tráfico alto.

Y, ya que estamos, cachea también APIs

Las CDNs modernas cachean respuestas de API si pones bien las cabeceras. Un endpoint cuyos datos cambian cada cinco minutos puede servirse con Cache-Control: max-age=300 y desaparece de la carga de tu origen. Ojo con cachear lo que no debe cachearse (datos por usuario, tokens). El día que un usuario ve el carrito de otro nadie quiere estar de guardia.

De monolito a microservicios: cuándo, y sobre todo cuándo no

Microservicios significa partir la aplicación en servicios pequeños e independientes, cada uno con una responsabilidad clara (auth, facturación, inventario, notificaciones), que se hablan por API o por mensajería asíncrona.

El humor seco aquí es obligado: media industria saltó a microservicios porque lo hacía Netflix, y Netflix no es tu pyme. Si tu equipo son ocho personas, abrir veinte repos no te hace Netflix, te hace una pyme con veinte repos.

Beneficios cuando aplican

  • Escalado selectivo: si el módulo de informes consume mucho y el resto va liviano, escalas solo ese servicio. No duplicas toda la aplicación.
  • Despliegues independientes: el equipo de facturación despliega sin pedir permiso al de inventario.
  • Resiliencia: un servicio caído no tumba el resto si has hecho los deberes con timeouts, reintentos y degradación elegante. En un monolito, un módulo en mal estado se lleva por delante toda la app.

Lo que cuesta de verdad

Microservicios añaden complejidad operativa que no es trivial y la gente la subestima sistemáticamente:

  • Infraestructura: orquestador de contenedores (Kubernetes, ECS), API gateway o service mesh, logging centralizado, tracing distribuido. Un EKS gestionado en AWS son 73 USD/mes solo por el plano de control. Eso es antes de pagar un solo nodo.
  • Red entre servicios: 1-5 ms por llamada, timeouts, reintentos, circuit breakers. Todo lo que en un monolito era una llamada a función ahora puede fallar por red.
  • Equipo: InfoQ (2024) estima que se necesitan al menos 4-5 desarrolladores dedicados a infraestructura para operar un sistema con más de diez servicios. Si no los tienes y los improvisas, esos costes salen igual: en forma de incidentes de producción.

Si tu factura AWS pasó de 800 a 4.000 USD en un mes después de migrar a Kubernetes, probablemente no migraste a microservicios, montaste un monolito distribuido. Es peor que un monolito normal y es lo más caro que puedes hacer.

Regla de decisión

Si el equipo de desarrollo no llega a diez personas y el monolito no supera 200.000 líneas, casi seguro no necesitas microservicios. Puedes capturar buena parte del beneficio con un monolito modular: módulos bien separados, fronteras claras, misma base de datos, mismo proceso. Despliega como uno, razona como varios. Es aburrido y funciona.

Martin Fowler lo dijo claro: «No empieces con microservicios. Empieza con un monolito bien estructurado y extrae servicios solo cuando el dolor de no hacerlo supere el coste de la complejidad operativa añadida». Trece años después sigue siendo el mejor consejo gratis de la industria.

La migración, si hay que hacerla, va gradual. Identifica el módulo que más se beneficia (el que más escala pide o el que cambia más rápido), extráelo, valida en producción y pasa al siguiente. Quien intenta partir todo a la vez acaba con un Big Bang sin presupuesto para terminarlo.

Monitorización: no decidas a ojo

Escalar sin métricas es medicar sin diagnóstico. Antes de comprar más servidores, hay que saber dónde duele.

Métricas de infraestructura

  • CPU, RAM, disco: lo básico. Prometheus + Grafana (open source) o Datadog (Pro desde 23 USD/host/mes) las pintan en dashboards. Lo importante no es el dashboard bonito, es que alguien lo mire.
  • Latencia de red: p95 entre servicios y hacia usuarios. Un p95 por encima de 500 ms es una señal, no una anécdota.
  • Saturación de conexiones: PostgreSQL acepta 100 conexiones por defecto. Si tu app consume 80 en horario normal, no estás cómodo, estás esperando turno.

Métricas de aplicación (APM)

APM rastrea cada petición desde que entra hasta que sale, troceando el tiempo por capas: middleware, lógica, queries, llamadas externas. Aquí es donde aparecen los N+1, los joins horribles y las consultas que alguien añadió «provisionalmente» en 2024.

  • New Relic: detección automática de consultas lentas y errores. Plan estándar desde 0,30 USD por GB ingerido. Vigila la ingesta o te llevas un susto.
  • Elastic APM: open source, integrado con el stack Elastic. Cero en licencias, pagas la infraestructura.
  • Sentry: errores y excepciones con contexto, tracing. Team desde 26 USD/mes.

Alertas con sentido común

Las alertas o avisan de algo real o las acabarás silenciando, que es peor que no tenerlas. Umbrales sensatos:

  • p95 por encima de 2 segundos durante más de 5 minutos.
  • CPU sobre 80 % durante más de 10 minutos.
  • Errores 5xx por encima del 1 % del tráfico total.
  • Disco por debajo del 20 % libre.

Y no alertes en spikes momentáneos. Un pico de CPU al 95 % durante 30 segundos en un despliegue no es una emergencia, es un martes.

Costes cloud: escalar sin que la factura te escale a ti

El miedo a que el cloud se descontrole es legítimo. Hay facturas mensuales que crecen de manera opaca si nadie las mira. Si tu factura AWS pasó de 1.500 a 6.000 USD en un mes y nadie sabe explicarte por qué, probablemente tienes tres problemas: alguien dejó algo encendido, alguien sobredimensionó algo, y nadie ha mirado los precios de transferencia.

Reservas y savings plans

Si tienes una capacidad base que vas a necesitar 12 meses, los planes de ahorro bajan el precio entre un 30 % y un 60 %.

  • AWS Savings Plans: compromiso de gasto por hora a 1 o 3 años. Una m7i.xlarge que cuesta 175 USD/mes bajo demanda baja a unos 110 USD/mes con plan a 1 año (37 % menos).
  • Google Committed Use Discounts: descuentos parecidos, con la ventaja añadida de que Google aplica «sustained use discounts» del 20-30 % de forma automática si usas la instancia más del 25 % del mes.

Right-sizing

Flexera (2024) cuenta que el 35 % de los recursos cloud están sobredimensionados. Un servidor con 32 GB de RAM cuyo consumo máximo real es 12 GB está pagando por 20 GB que nadie pisa. Multiplica por una flota entera y entiendes por qué FinOps existe.

AWS Compute Optimizer, Google Recommender o la propia Prometheus identifican estas instancias y sugieren tamaños sensatos. Conviene revisar trimestralmente, no una vez en la vida.

Apagar lo que no produce

Dev, staging y QA no necesitan funcionar 24/7. Programar apagado de 18:00 a 08:00 y fines de semana baja el coste un 65 %. Tres entornos a 350 USD/mes apagados fuera de horario pasan a ahorrar más de 8.000 USD al año. Eso paga un par de sprints de mejoras de rendimiento al año.

Spot para cargas tolerantes

Las spot de AWS (preemptible en Google) son capacidad sobrante con descuentos del 60-90 %. Buenas para batch, tests automatizados y workers de cola que toleran interrupciones y reintentos. Malas para servir tráfico web crítico, salvo que diseñes específicamente para que la caída de un spot no se note.

Planificar antes de que sea urgencia

La diferencia entre una app que escala con fluidez y una que se convierte en problema recurrente no es tecnológica. Redis, Kubernetes, CloudFront, Prometheus están al alcance de cualquiera. Lo que separa unas de otras es cuándo se decide, y con qué datos.

Escalar reactivo, con la CPU al 95 % y los usuarios viendo errores, es caro, estresante y produce decisiones malas. Escalar planificado, con métricas que avisan semanas antes, sale más barato y deja dormir mejor.

Un plan razonable para una pyme no contempla millones de usuarios el día uno. Contesta tres preguntas:

  • ¿Cuánto tráfico tengo hoy, medido, no intuido?
  • ¿Cuánto espero en 12 meses si el negocio cumple su plan?
  • ¿Qué pieza de mi aplicación se va a saturar primero?

Con esas tres respuestas la hoja de ruta se ordena prácticamente sola: primero caché y CDN (semanas de trabajo, retorno alto), después horizontal en la capa de aplicación (un sprint si ya es stateless), y solo si toca, sacar a microservicios los módulos que de verdad lo justifiquen. No al revés.

Si tu aplicación ya empieza a dar señales de que la infraestructura actual se queda corta, o quieres adelantarte antes de que se convierta en un problema con nombre y apellidos, el equipo de Tangram Consulting puede auditar el rendimiento actual, identificar los puntos de mayor impacto y diseñar un plan de cómo escalar una aplicación web a medida cuando crece tu negocio adaptado a tu volumen real y a tu presupuesto. No todas las aplicaciones necesitan Kubernetes. Saber cuáles sí y cuáles no es la mitad del trabajo. La otra mitad es resistir la tentación de hacerlo igual.