# Escalar es ensanchar el cuello de botella

Curso exprés sobre diseño de sistemas y escalado. 21 conceptos — Scalability, Bottleneck, Horizontal Scaling, Stateless Server, Load Balancer, Cache, CDN, Read Replica, Sharding, colas y Design for Failure — cada uno con su nombre en inglés, un diagrama y una ficha con un ejemplo. Al final: la escalera de escalado y una chuleta con todos los términos. Solo la esencia: medir antes que adivinar.

- **Author:** Fedor Chishchin
- **Level:** intro
- **Reading time:** ~35 minutos de lectura
- **Published:** 2026-06-02
- **Source:** https://fedorthinks.com/es/learn/system-design-express

---

## 1. Qué significa escalar

Escalar no es un único interruptor que activás — es el trabajo continuo de manejar más carga sin caerte. Empieza con una sola idea: encontrar la parte que se rompe primero.

### Scalability — manejar más sin romperse

> Un café chico funciona bien hasta que llega un micro de turistas — de golpe el único barista, la única caja, las pocas mesas no dan abasto. Escalar es prepararse para el micro.

La **Scalability** (escalabilidad) es la capacidad de un sistema de manejar el crecimiento — más usuarios, más requests, más datos — manteniéndose rápido y arriba. No se trata de máxima inteligencia; se trata de que el sistema no ceda cuando la carga se multiplica.

_Diagram: La carga crece. Un sistema escalable sigue rápido; el que no escala se rompe de golpe en algún punto._

#### Scalability (manejar el crecimiento)

- **Qué es:** La capacidad de aguantar más carga sin volverse lento ni caerse.
- **Cómo funciona:** Casi todo problema de escalado se reduce a una cosa: **algo se convierte en la parte que no da abasto.**
- **Ejemplo:** El café al que acaba de llegar un micro de turistas.
- **Relaciones:** Crece con el **Vertical Scaling** y el **Horizontal Scaling**; choca con un **Bottleneck**.

### Vertical vs Horizontal — arriba o a los lados

> Para cargar más, podés comprar un camión más grande — solo hasta cierto tamaño — o comprar más camiones: casi sin límite, pero ahora necesitás un despachador.

Hay exactamente dos formas de agregar capacidad. El **Vertical scaling (scale up)** es una máquina más grande — más CPU, más RAM. Fácil, pero tiene un techo duro y sigue siendo un único punto de falla. El **Horizontal scaling (scale out)** son más máquinas trabajando juntas — casi ilimitado, pero necesita coordinación (balanceo de carga, estado compartido). El vertical te compra tiempo; **el horizontal es donde vive la escala de verdad.** Los detalles, en el capítulo 2.

_Diagram: Izquierda — una caja se hace más grande y choca con el techo. Derecha — hay más cajas, con un load balancer delante._

### Bottleneck — el punto más angosto

> Una autopista es tan rápida como su tramo más angosto — ensanchar cada otro carril no hace nada hasta que arreglás el embudo.

Un **bottleneck** (cuello de botella) es la parte más lenta del sistema, la que limita todo lo demás. Un sistema es tan rápido como esa parte. Tirar recursos en el lugar equivocado es plata desperdiciada; el trabajo es **encontrar el cuello de botella real** — la base de datos, un servicio lento, la red — ensancharlo, y después encontrar el siguiente.

_Diagram: Una cadena aguanta solo lo que aguanta su eslabón más débil. Acá, es la base de datos._

#### Bottleneck (el embudo)

- **Qué es:** La única parte que no da abasto y frena todo el flujo.
- **Cómo funciona:** Ensanchás un cuello de botella y aparece el siguiente. **Escalar es una secuencia de cuellos de botella, no un único arreglo.**
- **Ejemplo:** El CDN y los servidores de la app manejan miles de requests por segundo, la base de datos ochocientos. Agregar servidores no sirve de nada.
- **Trampa:** Es fácil "arreglar" lo que solo parecía lento en lugar de lo que realmente lo era.
- **Relaciones:** Se encuentra con **Measure First**; se trata con peldaños de la **Scaling Ladder**.

### Premature Scaling — construir para una carga que no tenés

> No construís una autopista de seis carriles hacia una cabaña en el bosque. Un buen camino lleva a todos los que la van a visitar.

El **Premature scaling** (escalado prematuro) es construir para una carga que no tenés. Un solo servidor decente más una base de datos atiende a una cantidad sorprendente de usuarios. Sharding, microservicios, cacheo elaborado antes de tener la carga — eso es costo y complejidad que no necesitás.

_Diagram: Tu carga real, lo que aguanta un servidor más una base de datos, y lo que se construyó 'para el futuro'._

#### Premature Scaling (escalar demasiado pronto)

- **Problema:** Complejidad y plata gastadas en una carga que no existe y quizás nunca llegue.
- **Ejemplo:** Una base de datos con sharding y microservicios para una app con cien usuarios.
- **Remedio:** **Medí primero; escalá lo que de verdad duele, cuando de verdad duele.**
- **Relaciones:** El antídoto es **Measure First** y la **Scaling Ladder**.

### El mapa: 21 conceptos en siete grupos

> Un mapa de metro: primero ves las líneas enteras, después viajás estación por estación.

Cada capítulo del curso es un grupo de conceptos. Vienen más o menos en el orden en que un sistema en crecimiento se los encuentra: lo básico, después más servidores, repartir el tráfico, cachés, la base de datos, colas — y al final las reglas para aplicar todo con la cabeza fría.

_Diagram: Siete grupos de conceptos — los capítulos 1–7 los siguen._

### Cómo leer cada concepto

> Un pasaporte: los mismos campos para todos, así es fácil compararlos.

Cada concepto de acá en adelante tiene las mismas partes: el **nombre en inglés** (memorizalo — es el término que vas a encontrar en la documentación y en las entrevistas), una imagen de la vida real, un **diagrama** y una **ficha**: _problema_, _idea_, _ejemplo_, _coste_, _cuándo usarlo_ y cómo se _relaciona_ con otros conceptos. Al final hay una **chuleta** con todos los términos en una página.

> **Antes de escalar:** "¿Cuál es la única parte que se rompe primero bajo carga — y ya tengo de verdad esa carga?"

> Escalar no es hacer que todo vaya más rápido. Es encontrar el cuello de botella, ensancharlo y repetir.

## 2. Vertical, después horizontal

Los primeros pasos reales por la escalera: superar una sola caja grande, y después lograr que la app pueda correr en tantas cajas idénticas como quieras.

### Vertical Scaling — primero, la caja más grande

> Cuando la cocina está desbordada, el primer arreglo es una cocina más grande y más mesada — no un segundo restaurante.

El **Vertical scaling (scale up)** es la jugada más simple: **una máquina más grande.** No requiere cambios de código y te da margen real rápido — a menudo suficiente por mucho tiempo. Pero tiene un techo duro (no se puede comprar un servidor infinito), y esa única caja sigue siendo un **punto único de falla**.

_Diagram: Cada escalón es una máquina más potente. Pero el techo está cerca, y sigue siendo una sola máquina._

#### Vertical Scaling (scale up)

- **Problema:** El servidor no aguanta la carga: falta CPU o memoria.
- **Idea:** Pasar a una máquina con más CPU y RAM.
- **Ejemplo:** La base de datos pasa de un servidor de 8 núcleos a uno de 64.
- **Coste:** Un techo duro; una caja = un punto único de falla.
- **Cuándo usarlo:** Primero. **Usalo para ganar tiempo, no como destino.**
- **Relaciones:** El primer peldaño de la **Scaling Ladder**; el siguiente paso es el **Horizontal Scaling**.

### Horizontal Scaling — muchas cajas, un solo trabajo

> Una caja se convierte en diez — ahora se atiende a diez clientes a la vez, y si una se traba, las otras nueve siguen.

El **Horizontal scaling (scale out)** significa **correr muchas copias** de tu app y repartir el trabajo entre ellas. Es casi ilimitado y sobrevive a la pérdida de cualquier máquina. La trampa es la coordinación: algo tiene que repartir los requests (capítulo 3), y las copias no deben guardar cada una su propio estado privado — que es la siguiente idea, crucial.

_Diagram: Cinco copias idénticas detrás de un load balancer. Una se cae — las otras cuatro siguen funcionando._

#### Horizontal Scaling (scale out)

- **Problema:** Una máquina, incluso la más grande, choca con un techo.
- **Idea:** Correr N copias idénticas de la app y repartir los requests entre ellas.
- **Ejemplo:** En el Black Friday una tienda corre 20 copias en vez de las 4 habituales.
- **Coste:** Necesita coordinación: un load balancer y un lugar compartido para el estado.
- **Cuándo usarlo:** Cuando el vertical no alcanza, o necesitás sobrevivir a que se mueran máquinas.
- **Relaciones:** Solo funciona con un **Stateless Server**; necesita un **Load Balancer**.

### Stateless Server — cualquier caja puede atender cualquier request

> Un call center donde cualquier agente puede atender cualquier llamada, porque todos los datos del cliente viven en el sistema compartido — no en la cabeza de un agente.

Para que el escalado horizontal funcione, los servidores de la app deben ser **stateless** (sin estado): no guardan nada de un usuario entre requests en su propia memoria. Los datos de sesión, los uploads, el progreso — todo vive en algún lugar compartido (una base de datos, un caché, un token que lleva el cliente). Entonces cualquier request puede caer en cualquier servidor, y sumar o perder una caja no cambia nada.

_Diagram: Un request puede caer en cualquier servidor: los servidores no recuerdan nada, todo el estado vive en un almacén compartido._

#### Stateless Server (sin estado local)

- **Problema:** El servidor guarda la sesión en su propia memoria — el usuario queda "pegado" a él, y una caída lo pierde todo.
- **Idea:** El servidor no guarda nada entre requests; el estado vive en una base de datos, un caché o el token del cliente.
- **Ejemplo:** El carrito vive en Redis, no en la memoria del proceso; el login es un token.
- **Coste:** Cada request trae su estado desde el almacén compartido.
- **Cuándo usarlo:** Siempre, si pensás tener más de un servidor. **La ausencia de estado es lo que hace que "agregar más servidores" funcione de verdad.**
- **Relaciones:** Un requisito previo del **Horizontal Scaling** y del **Rolling Deploy**.

> **La pregunta horizontal:** "¿Podría un request caer en cualquiera de mis servidores y comportarse igual — o cada uno guarda estado en secreto?"

> El vertical compra tiempo; el horizontal compra escala. Y el horizontal solo funciona si tus servidores no recuerdan nada por su cuenta.

## 3. Repartir el tráfico

Cuando tenés muchos servidores, algo tiene que pararse delante y decidir quién atiende cada request. Ese es el load balancer — el policía de tránsito de un sistema escalado.

### Load Balancer — una puerta de entrada, muchos servidores

> Un encargado de la fila en un banco que manda a cada cliente a la ventanilla que esté libre — así ninguna ventanilla se satura mientras otras están vacías.

Un **load balancer** (balanceador de carga) — Nginx, HAProxy, uno de la nube — es el único punto de entrada que reparte los requests entrantes entre tu pool de servidores con reglas simples: **round-robin**, o enviarlo al menos ocupado (**least connections**). Los clientes hablan con él, no con los servidores individuales, así que podés sumar o quitar máquinas detrás de él sin que nadie lo note.

_Diagram: Los clientes conocen una sola dirección. El load balancer reparte sus requests entre los servidores._

#### Load Balancer (LB)

- **Problema:** Hay muchos servidores — ¿quién decide a dónde va cada request?
- **Idea:** Un punto de entrada reparte los requests entre un pool de servidores.
- **Ejemplo:** Nginx delante de cuatro copias de una API, repartiendo los requests en round-robin.
- **Coste:** Un componente más, que no debe convertirse él mismo en un punto único de falla.
- **Cuándo usarlo:** Apenas tengas más de un servidor.
- **Relaciones:** **Es lo que convierte un montón de servidores en un solo sistema.** Usa **Health Checks**.

### Health Check — dejar de enviar a los muertos

> El encargado de la fila nota que una ventanilla se quedó sin cajero y simplemente deja de mandar gente ahí — nadie espera frente a un escritorio vacío.

Con los **health checks** (chequeos de salud), un load balancer **verifica constantemente qué servidores están sanos** y rodea a los que no. Una caja caída o sobrecargada se saca de la rotación automáticamente, y el tráfico fluye hacia el resto. Así es como un sistema escalado sobrevive a que se muera una máquina sin que los usuarios se enteren.

_Diagram: El servidor B no respondió al chequeo — el load balancer deja de enviarle tráfico._

#### Health Check (liveness probe)

- **Problema:** El load balancer sigue enviando requests a un servidor que ya está muerto.
- **Idea:** Consultar a cada servidor con regularidad; no responde — se saca de la rotación; vuelve — se reincorpora.
- **Ejemplo:** `GET /health` cada pocos segundos; sin un `200` — el servidor se retira.
- **Coste:** Un chequeo mal escrito miente: "sano" mientras la base de datos es inalcanzable.
- **Relaciones:** Parte del **Load Balancer**; la base del failover y de **Design for Failure**.

### Rolling Deploy y Failover — ganancias gratis

> Podés renovar una caja a la vez mientras las demás siguen atendiendo — la tienda nunca cierra.

Una vez que el tráfico pasa por un balanceador hacia servidores intercambiables, cosas poderosas llegan casi gratis: un **deploy sin downtime (rolling)** — actualizás los servidores de a pocos; el **failover** — cuando uno se muere, el tráfico pasa al resto; y un **rollback** rápido. El balanceador más los servidores stateless es la columna vertebral que hace a un sistema escalable y resiliente a la vez.

_Diagram: Los servidores se actualizan de a uno mientras el resto sigue atendiendo a los usuarios._

#### Rolling Deploy (deploy sin downtime + failover)

- **Problema:** Publicar una versión nueva significa "sitio caído".
- **Idea:** Actualizar los servidores de a pocos mientras el resto lleva el tráfico.
- **Ejemplo:** De cuatro servidores, dos están en v2, uno se está actualizando, uno sigue en v1 — los usuarios no notan nada.
- **Coste:** Durante un rato corren dos versiones a la vez — tienen que llevarse bien.
- **Relaciones:** Necesita un **Stateless Server**, un **Load Balancer** y **Health Checks**.

> **La pregunta del balanceo:** "Cuando un servidor se muere, o despliego una versión nueva, ¿los usuarios sienten algo?"

> Un load balancer convierte muchos servidores en una sola dirección — y una máquina que se muere en un no-evento.

## 4. Hacer menos trabajo

El trabajo más rápido es el que no hacés. Antes de escalar las máquinas que hacen el trabajo, reducí cuánto trabajo hay — con cachés y un CDN.

### Cache — no calcules dos veces la misma respuesta

> Un cocinero que prepara la salsa popular una vez por la mañana, en lugar de hacerla desde cero para cada pedido.

Un **cache** (caché) guarda el resultado de un trabajo costoso — una consulta a la base de datos, una página calculada, una llamada a una API — para que el siguiente request lo reciba al instante en lugar de rehacerlo. Un almacén rápido en memoria (**Redis**, **Memcached**) delante de la base de datos puede absorber la mayor parte de las lecturas. El esquema más común es **cache-aside**: mirás primero el caché; si no está (miss), vas a la base de datos y guardás la respuesta en el caché.

_Diagram: Cache-aside: mirar el caché → si no está, preguntarle a la base de datos → guardar la respuesta para la próxima vez._

#### Cache (cache-aside)

- **Problema:** La base de datos calcula las mismas respuestas una y otra vez.
- **Idea:** Recordar el resultado en memoria rápida y servirlo de nuevo.
- **Ejemplo:** Una página de producto se cachea en Redis — la base de datos deja de recalcularla.
- **Coste:** Una segunda copia de la verdad, que puede quedar desactualizada.
- **Cuándo usarlo:** **A menudo lo que tu base de datos sobrecargada necesita es un caché, no más servidores.**
- **Relaciones:** Exige una **Cache Invalidation** cuidadosa; su pariente en el borde de la red es el **CDN**.

### CDN — servir a los usuarios desde cerca

> Una cadena global que tiene los mismos productos en depósitos locales de todas partes — así los clientes los reciben de la vuelta de la esquina, no enviados desde el otro lado del océano.

Un **CDN (Content Delivery Network)** guarda copias de tu contenido estático — imágenes, scripts, video, cada vez más páginas enteras — en centros de datos de todo el mundo (el **edge**), y sirve a cada usuario desde el más cercano. Reduce muchísimo la latencia y le saca una enorme carga a tu **origin** — tus propios servidores.

_Diagram: El origin le pasa copias a nodos del edge en distintas regiones; a cada usuario le responde el más cercano._

#### CDN (Content Delivery Network)

- **Problema:** Un usuario del otro lado del mundo espera a que los bytes crucen un océano.
- **Idea:** Guardar copias del contenido estático en nodos cercanos a los usuarios.
- **Ejemplo:** Las imágenes del sitio se sirven desde un nodo en Fráncfort, no desde un servidor en EE. UU.
- **Coste:** El mismo problema del caché: hay que refrescar las copias cuando algo cambia.
- **Cuándo usarlo:** Para todo lo global y estático — el CDN hace el trabajo pesado antes de que tus servidores vean siquiera el request.
- **Relaciones:** Un **Cache** en el edge; sufre la misma **Cache Invalidation**.

### Cache Invalidation — la parte difícil

> El calendario en la heladera es más rápido que mirar el celular — hasta que alguien cambia el plan en el celular, y ahora la heladera miente.

Un caché es una segunda copia de la verdad, y una copia puede quedar vieja (**stale data**, datos desactualizados). La pregunta realmente difícil no es agregar un caché — es **saber cuándo tirarlo**; eso es la **cache invalidation**. Cacheá lo que se lee mucho más de lo que se escribe, poné vencimientos razonables (**TTL**), y sabé siempre qué pasa cuando el caché se equivoca.

_Diagram: El precio cambió en la base de datos, pero el caché no lo sabe y sigue sirviendo el viejo._

#### Cache Invalidation (vencer las copias viejas)

- **Problema:** Los usuarios ven datos desactualizados que vienen del caché.
- **Idea:** Borrar la entrada del caché cuando cambian los datos, y/o darle una vida útil (TTL).
- **Ejemplo:** Cuando cambia el precio, se borra la clave `product:42` de Redis; más un TTL de 5 minutos por las dudas.
- **Trampa:** Un camino de escritura olvidado que no limpia el caché — y los datos mienten en silencio durante horas.
- **Relaciones:** El otro lado de todo **Cache** y de todo **CDN**.

> **La pregunta del cacheo:** "¿Qué estoy recalculando o volviendo a pedir una y otra vez que podría simplemente recordar — y cómo voy a saber cuándo quedó viejo?"

> El request más barato es el que nunca servís. Cacheá lo caliente, serví lo estático desde el edge, y poné toda tu atención en la invalidación.

## 5. Escalar los datos

Tarde o temprano la base de datos se vuelve el cuello de botella — es la única parte realmente difícil de escalar, porque guarda la verdad que todos comparten.

### Database Bottleneck — la base de datos suele ser el muro

> Diez cajas que meten la mano en el mismo único depósito — los cajeros escalan, pero la única puerta del depósito se vuelve el atasco.

Podés correr cien servidores de app stateless, pero normalmente comparten **una sola base de datos** — y esa se vuelve el límite. A diferencia de los servidores de la app, no la podés simplemente clonar, porque todas las copias tienen que estar de acuerdo con los datos. Por eso escalar la base de datos es la parte más difícil y delicada de escalar un sistema.

_Diagram: Los servidores de la app se multiplican fácil, pero todos chocan con una única base de datos compartida._

#### Database Bottleneck (el muro)

- **Qué es:** Una base de datos compartida contra la que choca cada servidor de la app.
- **Por qué:** Las copias de una base de datos tienen que coincidir en los datos — no se puede simplemente clonar.
- **Qué hacer:** Posponelo con caché todo lo que puedas; después réplicas; sharding, lo último de todo.
- **Relaciones:** Se trata con **Cache**, **Read Replica**, **Sharding**.

### Read Replica — una copia para las lecturas

> Repartir fotocopias del libro de consulta para que mucha gente lea a la vez, mientras la única copia maestra es la única en la que alguien escribe.

La mayoría de las apps leen mucho más de lo que escriben. Las **read replicas** (réplicas de lectura) son copias de la base de datos que atienden consultas de lectura, repartiendo esa carga entre máquinas mientras las escrituras siguen yendo a un solo **primary**. Es la primera y más fácil jugada para escalar la base de datos — pero las copias se atrasan un poco (**replication lag**), así que un valor recién escrito puede no aparecer al instante en una réplica.

_Diagram: Las escrituras van solo al primary; las lecturas se reparten entre las réplicas. Las réplicas se ponen al día con un pequeño retraso._

#### Read Replica (copia de lectura)

- **Problema:** La base de datos se ahoga en consultas de lectura.
- **Idea:** Copias de la base de datos responden las lecturas; toda escritura va a un solo primary.
- **Ejemplo:** El feed y la búsqueda leen de tres réplicas; los pedidos se escriben en el primary.
- **Coste:** Replication lag: un usuario guarda su perfil, recarga la página — y ve el viejo.
- **Cuándo usarlo:** Cuando la carga es sobre todo de lectura y el caché ya no alcanza.
- **Relaciones:** El siguiente peldaño después del **Cache**; si el problema son las escrituras — **Sharding**.

### Sharding — repartir las escrituras

> Un libro de registro que se desborda se convierte en varios — A–M en uno, N–Z en otro — para que dos empleados escriban a la vez sin pelearse por una sola página.

Cuando incluso las escrituras superan a una sola máquina, hacés **sharding**: partís los datos entre varias bases de datos según alguna clave — la **shard key** — para que cada una maneje una porción. Habilita una escala enorme pero es realmente difícil — las consultas entre shards se vuelven dolorosas, y la shard key es una decisión casi permanente.

_Diagram: El router mira la clave y manda los datos al shard correcto. Cada shard guarda su propia porción._

#### Sharding (partición horizontal)

- **Problema:** Hay tantas escrituras que un solo primary no da abasto.
- **Idea:** Cortar los datos por clave en varias bases de datos independientes.
- **Ejemplo:** Clientes A–H en el shard 1, I–P en el shard 2, Q–Z en el shard 3.
- **Coste:** Las consultas entre shards son dolorosas; la clave es casi imposible de cambiar.
- **Cuándo usarlo:** **Es la parte honda de la pileta; llegá último, cuando las réplicas y el caché de verdad no alcanzan.**
- **Relaciones:** El último peldaño de la **Scaling Ladder**; viene después de la **Read Replica**.

> **La pregunta de los datos:** "¿Mi carga es sobre todo de lecturas (sumar réplicas, cachear más) — o son escrituras que superan a una sola máquina (el camino difícil del sharding)?"

> Los servidores de la app se clonan fácil; la base de datos no. Cacheá y replicá por mucho tiempo antes de hacer sharding.

## 6. Suavizar y desacoplar

No todo el trabajo tiene que ocurrir mientras el usuario espera. Sacar el trabajo lento del request, y poner buffers entre las partes, es como un sistema se mantiene rápido y absorbe los picos.

### Background Job — sacar el trabajo lento del camino del request

> En un restaurante te toman el pedido y te sentás — no te hacen quedar parado en el mostrador hasta que la comida esté cocinada.

Cuando un request dispara algo lento — enviar un email, generar un reporte, procesar un upload — no hagas esperar al usuario. **Pasalo a una cola en segundo plano** y respondé de inmediato; un **worker** hace la parte lenta más tarde. Eso es un **background job**. La página se mantiene ágil, y el trabajo pesado ocurre aparte. (La idea de mensajería de los cursos de protocolos y de arquitectura.)

_Diagram: La app pone la tarea en una cola y responde al instante. Un worker envía el email — más tarde, aparte._

#### Background Job (procesamiento asíncrono)

- **Problema:** El usuario espera segundos mientras el servidor hace un trabajo lento.
- **Idea:** Poner la tarea en una cola, responder de inmediato, y que un worker haga el trabajo.
- **Ejemplo:** Después del registro, el email de bienvenida se envía en segundo plano — la página abre al instante.
- **Coste:** El resultado no es instantáneo; necesitás una cola y manejo de los errores del worker.
- **Cuándo usarlo:** Para todo lo que el usuario no necesita ver ahora mismo.
- **Relaciones:** La misma cola te da **Load Leveling** y **Decoupling**.

### Load Leveling — las colas absorben los picos

> Un embalse entre un río crecido y el pueblo — la crecida llena el embalse en lugar de ahogar las calles, y se vacía a un ritmo constante.

Una cola también es un **buffer.** Este truco se llama **queue-based load leveling**. Cuando el tráfico tiene un pico repentino — un lanzamiento, un momento viral — el trabajo se acumula en la cola y los workers la vacían a su propio ritmo, en lugar de que una inundación se lleve puesto al sistema. Sin ese buffer, un pico que llega más rápido de lo que podés procesar tira todo abajo.

_Diagram: Izquierda — tráfico entrante con picos; centro — la cola retiene el trabajo; derecha — los workers corren a un ritmo constante._

#### Load Leveling (queue-based load leveling)

- **Problema:** Un pico de tráfico llega más rápido de lo que el sistema puede procesar.
- **Idea:** Una cola retiene el trabajo; los workers la vacían a un ritmo constante.
- **Ejemplo:** En el lanzamiento llegan diez veces los pedidos habituales — esperan en la cola en vez de tirar el servicio abajo.
- **Coste:** Durante un pico el trabajo se hace tarde; la cola necesita monitoreo.
- **Relaciones:** **La cola convierte un pico mortal en un backlog manejable.** Pariente del **Background Job**.

### Decoupling — una parte lenta no hunde al resto

> Compartimentos estancos en un barco — si uno se inunda, los mamparos mantienen secos a los otros y el barco a flote.

Con el **decoupling** (desacoplamiento), los servicios hablan a través de colas y eventos en lugar de llamadas directas y bloqueantes, así que un componente lento o caído **no congela a todos los que lo esperan.** El pedido igual se toma aunque el servicio de email esté caído; simplemente se pone al día después. El desacoplamiento es lo que permite a un sistema grande degradarse con elegancia bajo estrés en lugar de fallar todo de una vez.

_Diagram: Arriba — una llamada directa: el servicio de email está caído, así que el pedido también falla. Abajo — a través de una cola: el pedido se toma, el email sale más tarde._

#### Decoupling (hablar a través de colas y eventos)

- **Problema:** Un servicio caído arrastra a todos los que lo llaman.
- **Idea:** Comunicarse a través de una cola o de eventos en lugar de esperar una respuesta directa.
- **Ejemplo:** El servicio de pedidos publica "pedido creado"; el servicio de email lo recoge cuando vuelve.
- **Coste:** Más difícil rastrear qué pasó; los datos coinciden solo con el tiempo, no al instante.
- **Relaciones:** La base de **Design for Failure**; construido sobre las mismas colas que el **Background Job**.

> **La pregunta de lo asíncrono:** "¿De verdad el usuario necesita esperar esto — o puede pasar detrás de una cola mientras la respuesta vuelve ya?"

> Hacé esperar al usuario solo por lo que necesita ahora. Todo lo demás va detrás de una cola — que además te salva cuando llega el pico.

## 7. Escalar con cordura

Escalar bien es sobre todo contención y orden: medí el cuello de botella real, subí primero los peldaños baratos, y prepará los fallos que traen más máquinas.

### Measure First — medí antes de escalar

> Un médico hace estudios antes de operar — cortar el órgano equivocado porque adivinaste no ayuda a nadie.

Antes de agregar nada, **encontrá el cuello de botella real** con métricas y **profiling** — ¿es la base de datos, una consulta lenta, la red, la CPU? Los ingenieros optimizan rutinariamente lo equivocado porque solo parecía lento. Los datos te dicen dónde le duele de verdad al sistema; **escalá eso, y nada más.** (Acá es donde la **observability** se gana el sueldo.)

_Diagram: Un request desglosado: casi todo el tiempo se va en una consulta a la base de datos. Eso es lo que hay que arreglar._

#### Measure First (profiling)

- **Problema:** La gente optimiza lo que "parece" lento mientras el cuello de botella está en otro lado.
- **Idea:** Las métricas y el profiling muestran dónde se va realmente el tiempo.
- **Ejemplo:** Un request tarda 400 ms, y 280 ms son una sola consulta a la base de datos. Entonces necesitás un índice o un caché, no más servidores.
- **Coste:** Necesitás observability: métricas, trazas, logs.
- **Relaciones:** Encuentra el **Bottleneck**; protege contra el **Premature Scaling**.

### Scaling Ladder — subí los peldaños baratos en orden

> Primero ponés aislación y sellás las ventanas, y recién después comprás una segunda caldera — los arreglos baratos primero.

Hay un orden, de lo más barato y fácil a lo más caro: **una caja más grande**, después **caché y CDN**, después **servidores stateless detrás de un load balancer** que escalan horizontalmente, después **read replicas**, después **colas** para el trabajo lento — y solo al final, **sharding**. Cada peldaño es más trabajo y más complejidad.

_Diagram: Seis peldaños: cuanto más arriba, más caro y complejo. Subí solo cuando la carga te obligue._

#### Scaling Ladder (primero el arreglo más barato)

- **Problema:** La gente agarra enseguida la herramienta más potente y más compleja.
- **Idea:** Ir peldaño por peldaño: caja más grande → caché y CDN → stateless + load balancer → réplicas → colas → sharding.
- **Ejemplo:** El sitio está lento — primero más RAM y un caché; quizás nunca se llegue al sharding.
- **Cuándo usarlo:** Siempre. **Subí solo hasta donde tu carga te obligue.**
- **Relaciones:** Une todos los conceptos de los capítulos 2–6.

### Design for Failure — más máquinas, más fallos

> Una bombilla rara vez falla en una noche dada; en un estadio con diez mil, siempre hay varias apagadas. A escala, siempre hay algo roto.

A medida que sumás máquinas, la probabilidad de que _algo_ esté fallando en cada momento tiende a ser segura. Por eso escalado y confiabilidad son el mismo proyecto: **redundancia** — ningún **single point of failure (SPOF)**; **health checks y failover**; y **graceful degradation**, para que una parte rota pierda calidad en lugar de matar al sistema.

_Diagram: Cada componente tiene un repuesto: un segundo load balancer, varios servidores, una base de datos en espera con failover._

#### Design for Failure (redundancia, graceful degradation)

- **Problema:** A escala, siempre hay alguna máquina rota.
- **Idea:** Redundancia, health checks, failover y graceful degradation — una parte caída no tira abajo el todo.
- **Ejemplo:** El servicio de recomendaciones está caído — la tienda muestra la página sin el bloque "quizás te guste", pero sigue vendiendo.
- **Coste:** Las máquinas de repuesto cuestan plata; hay que probar los failovers con regularidad.
- **Relaciones:** Reúne **Health Check**, **Rolling Deploy** (failover) y **Decoupling**.

### Cómo se conecta todo

> El mapa después del viaje: ahora ves qué estaciones están en la misma línea.

Los conceptos de este curso no son trucos sueltos sino una sola cadena. **Medí** → encontrá el **bottleneck** → subí hasta el peldaño de la **ladder** que necesites. El escalado horizontal **necesita** servidores stateless y un load balancer; el load balancer necesita health checks; un caché necesita invalidación; las colas te dan leveling y decoupling. Y todo sirve a un solo objetivo: **que una parte que falla no mate al sistema.**

_Diagram: Los vínculos principales entre los conceptos del curso._

#### Antes de escalar algo

- **¿Medí** dónde está el cuello de botella real — o solo adiviné?
- **¿Hay un peldaño más barato** — una caja más grande, un caché, un CDN — antes que este?
- **¿Mis servidores de la app son stateless**, para _poder_ sumar más?
- **¿La carga de la base de datos son lecturas** (réplicas, caché) o escrituras (el camino difícil)?
- **¿Se puede mover el trabajo lento** detrás de una cola?
- **¿Tengo de verdad esta carga** — o estoy construyendo para un futuro que quizás no llegue?

#### Señales de que sobreingenierizaste

- **Sharding** de una base de datos que una sola caja aguantaría de sobra.
- **Microservicios y colas** para una app con cien usuarios.
- Escalar la **parte que no era el cuello de botella**, porque parecía lenta.
- Una **capa de caché** tan enredada que nadie está seguro de cuándo está vieja.
- Construir para **millones de usuarios** que no tenés, y un lanzamiento que no ocurrió.

#### Señales de que escalaste bien

- **Escalaste el cuello de botella medido**, y ahora se ve el siguiente.
- Los servidores son **stateless**; sumar o perder uno es un no-evento.
- Las lecturas están **cacheadas y replicadas**; la base de datos respira.
- El trabajo lento corre **detrás de colas**, y un pico se vuelve un backlog, no una caída.
- **No hay un single point of failure** — cualquier máquina puede morir en silencio.
- Subiste **solo hasta donde la carga lo exigió** en la escalera.

## Chuleta: los 21 conceptos

### Fundamentos

- **Scalability** (manejar el crecimiento): Aguantar más carga sin dejar de ser rápido y estar arriba.
- **Bottleneck** (el embudo): La parte más lenta; limita a todo el sistema.
- **Premature Scaling** (escalar demasiado pronto): Construir para una carga que no tenés. Costo sin beneficio.

### Vertical y horizontal

- **Vertical Scaling** (scale up): Una máquina más grande. Fácil, pero con techo y un punto único de falla.
- **Horizontal Scaling** (scale out): Muchas copias idénticas. Casi ilimitado, necesita coordinación.
- **Stateless Server** (sin estado local): No recuerda nada entre requests — cualquier servidor puede atender cualquier request.

### Repartir el tráfico

- **Load Balancer** (LB): Una puerta de entrada que reparte los requests entre servidores.
- **Health Check** (liveness probe): Los servidores muertos se sacan de la rotación automáticamente.
- **Rolling Deploy** (deploy sin downtime, failover): Actualizar unos pocos servidores a la vez; cuando uno muere, el tráfico pasa al resto.

### Hacer menos trabajo

- **Cache** (cache-aside): Recordar una respuesta costosa y servirla de nuevo desde memoria.
- **CDN** (Content Delivery Network): Copias del contenido estático cerca de los usuarios de todo el mundo.
- **Cache Invalidation** (vencer las copias viejas): Saber cuándo tirar una copia: borrar al escribir y TTL.

### Escalar los datos

- **Database Bottleneck** (el muro): Una base de datos compartida que no se puede simplemente clonar.
- **Read Replica** (copia de lectura): Copias para las lecturas, escrituras a un solo primary. Un pequeño retraso.
- **Sharding** (partición horizontal): Partir los datos por clave entre varias bases de datos. El último recurso.

### Suavizar y desacoplar

- **Background Job** (procesamiento asíncrono): El trabajo lento va a una cola; el usuario no espera.
- **Load Leveling** (la cola como buffer): Una cola convierte un pico en un backlog, no en una caída.
- **Decoupling** (colas y eventos): Hablar a través de colas y eventos — una parte caída no hunde al resto.

### Escalar con cordura

- **Measure First** (profiling): Las métricas y el profiling muestran el cuello de botella real.
- **Scaling Ladder** (primero el arreglo más barato): Caja → caché/CDN → stateless + LB → réplicas → colas → sharding.
- **Design for Failure** (redundancia): Redundancia, failover y graceful degradation: a escala siempre hay algo roto.

> Escalá el cuello de botella que mediste, con la herramienta más barata que lo arregle, y asumí que a escala siempre hay algo roto. Todo lo demás es prematuro.

Fin del curso exprés · 7 capítulos · 21 conceptos · medir antes que adivinar

Lo que sigue es profundidad: _Designing Data-Intensive Applications_ otra vez, los libros de _System Design Interview_, y los blogs de ingeniería de empresas que escalaron de verdad. Pero mantené la idea central por encima de los patrones — un sistema es tan fuerte como su punto más débil bajo carga. Encontrá ese punto, ensanchalo, y no construyas el resto hasta que tengas que hacerlo.
