Módulo 2: Estimación de servilleta (back-of-the-envelope)

3. QPS: de peticiones al mes a peticiones por segundo

Descripción

El primero de los cuatro números de capacidad, y el que más vas a usar en toda tu vida de ingeniería de sistemas, es el QPS: queries per second, peticiones por segundo. Es el pulso del sistema: cuántas cosas tiene que atender cada segundo. Casi todo lo demás se dimensiona a partir de él —cuántos servidores, cuánta base de datos, si hace falta caché— porque el QPS es la carga instantánea que el sistema debe sostener sin ahogarse.

En esta lección conviertes el número-ancla de Enlace, "100 millones de URLs nuevas al mes", en QPS. Vas a producir tres cifras: el QPS de escritura (las URLs que se crean, ~40/s), el QPS de lectura (las que se visitan, ~4,000/s, vía el ratio 100:1), y —lo nuevo de esta lección— el QPS pico, que es más alto que el promedio porque el tráfico real no es parejo, y es el que de verdad tienes que aguantar. Al terminar, sabrás por qué la escritura de Enlace no preocupa a nadie, por qué la lectura sí, y por qué un sistema se dimensiona para su peor minuto y no para su minuto promedio.

Conexión con el módulo: esta lección construye la primera fila de la tabla de capacidad —el QPS— usando el kit de la lección 2 (potencias de 10, segundos por mes). Los números de QPS que produzcas aquí alimentan directamente las lecciones siguientes: el ancho de banda (lección 5) es QPS × payload, y la memoria del working set (lección 6) parte de las lecturas por día. La distinción promedio-vs-pico que introduces aquí se usa en las cuatro estimaciones. La decisión de qué hacer con 4,000 lecturas/s —meter caché, añadir réplicas— es de los módulos 4 y 5; aquí solo producimos el número que la justifica.

La caseta de peaje

Imagina una caseta de peaje en una autopista. La pregunta de capacidad es: ¿cuántos autos por segundo tiene que atender? Si le dicen "pasan 3 millones de autos al mes", el operador no puede planear nada útil con ese número: necesita traducirlo a autos por segundo, porque las casetas, las cabinas y el personal se dimensionan por el ritmo instantáneo, no por el total mensual. Divide 3 millones entre los ~2.6 millones de segundos de un mes y le da ~1.2 autos por segundo. Con eso ya sabe cuántas cabinas abrir en un momento normal.

Pero aquí está la trampa que todo operador de peaje conoce y que todo ingeniero novato olvida: el tráfico no es parejo. A las 3 de la mañana pasa un auto cada varios minutos; a las 6 de la tarde, hora pico, pasan diez veces más que el promedio. Si el operador dimensiona la caseta para 1.2 autos/s (el promedio), a las 6 de la tarde se forma una fila de kilómetros, porque en ese momento llegan 12 autos/s y las cabinas abiertas para 1.2 no dan abasto. La caseta hay que dimensionarla para la hora pico, no para el promedio del día, o colapsa justo cuando más se usa.

El QPS de un sistema es exactamente esto. "100 millones de URLs al mes" es el total; el QPS promedio es ese total repartido parejo entre todos los segundos; y el QPS pico es lo que llega en el momento de más tráfico, que es varias veces el promedio. El sistema se dimensiona para el pico, porque un sistema que solo aguanta el promedio se cae en la hora pico —que es, por definición, cuando más gente lo está usando y peor momento para caerse—.

Qué es exactamente el QPS

QPS (queries per second) es el número de peticiones que un sistema recibe por segundo. "Query" aquí no significa solo consultas de base de datos: significa cualquier petición que el sistema atiende —una llamada a la API, una redirección, una escritura—. Verás también RPS (requests per second), que es lo mismo con otro nombre; en esta guía usamos QPS.

Lo crucial es que el QPS se descompone por tipo de operación, porque cada operación cuesta distinto. En Enlace hay dos operaciones y sus costos son abismalmente diferentes:

  • shorten (escritura): recibe una URL larga, genera un short_code, y lo guarda. Es una escritura a la base de datos. Cuesta.
  • resolve (lectura): recibe un short_code, busca la long_url, y redirige. Es una lectura. Cuesta mucho menos, y —como veremos— se puede cachear casi por completo.

Por eso nunca se estima "el QPS de Enlace" como un solo número: se estima el QPS de escritura y el QPS de lectura por separado. Un sistema puede tener un QPS de escritura trivial y uno de lectura brutal (como Enlace), y mezclarlos en un solo número escondería justo la asimetría que define el diseño. La regla: separa lecturas de escrituras desde el primer número.

Ejemplo trabajado 1: el QPS de escritura

El dato de entrada es "100 millones de URLs nuevas por mes". Cada URL nueva es una operación shorten, o sea una escritura. La pregunta: ¿cuántas escrituras por segundo en promedio?

La cuenta es el total entre los segundos de un mes (que amarraste en la lección 2: 30 × 24 × 3,600 = 2,592,000 s):

qps_write = 100,000,000 / 2,592,000 ≈ 38.6 → ~40 escrituras/s

Ejecutémoslo:

# QPS de escritura de Enlace: 100M URLs/mes -> escrituras/s
writes_per_month = 100_000_000
seconds_per_month = 30 * 24 * 3600
qps_write = writes_per_month / seconds_per_month
print(f"seconds_per_month = {seconds_per_month:,}")
print(f"qps_write (crudo) = {qps_write:.2f}/s")
print(f"qps_write (redondeado) = ~{round(qps_write / 10) * 10}/s")

Qué esperar.

seconds_per_month = 2,592,000
qps_write (crudo) = 38.58/s
qps_write (redondeado) = ~40/s

~40 escrituras por segundo. Y con ese número ya tienes una conclusión de arquitectura, sin dibujar nada: 40 escrituras/s es una carga trivial. Para calibrar, una sola base de datos relacional modesta (un PostgreSQL en un servidor decente) maneja del orden de miles de inserciones simples por segundo sin despeinarse. 40/s es dos órdenes de magnitud por debajo de eso. Así que la escritura de Enlace no necesita nada especial: ni sharding, ni colas, ni trucos. Una base de datos sola sobra. La escritura no es el problema de Enlace, y saberlo desde el primer número te ahorra diseñar soluciones para un problema que no existe.

Ejemplo trabajado 2: el QPS de lectura, encadenado

El segundo número no necesita un dato nuevo del enunciado: sale del primero más el ratio. El número-ancla dice lectura:escritura = 100:1, es decir, por cada URL que se crea, se visita 100 veces en promedio (la gente comparte un enlace y muchos lo abren). Entonces el QPS de lectura es el de escritura por 100:

qps_read = qps_write × 100 = 40 × 100 = 4,000 lecturas/s
qps_write = 38.58            # crudo, para no arrastrar el redondeo todavia
read_write_ratio = 100
qps_read = qps_write * read_write_ratio
print(f"qps_read (crudo) = {qps_read:.0f}/s")
print(f"qps_read (redondeado) = ~{round(qps_read, -3):.0f}/s")

Qué esperar.

qps_read (crudo) = 3858/s
qps_read (redondeado) = ~4000/s

~4,000 lecturas por segundo. Y aquí el carácter de Enlace se revela entero. La lectura es 100 veces la escritura: dos órdenes de magnitud de diferencia. Enlace es un sistema read-heavy —de lectura pesada—, y esa es su propiedad definitoria. Mientras que 40 escrituras/s las hace cualquier base de datos, 4,000 lecturas/s ya es una carga que hay que tomar en serio: aunque una base de datos puede servir 4,000 lecturas/s, hacerlo pegándole al disco en cada una es frágil y caro, y peor aún si el tráfico crece. Esta es la razón de ser de la caché (módulo 4) y de las réplicas de lectura (módulo 5): proteger ese camino de lectura de 4,000/s. El número que acabas de calcular es el que justifica la mitad de la arquitectura de Enlace.

Fíjate en el patrón de encadenar: el QPS de lectura no salió de dividir otra vez el enunciado, sino de multiplicar un número que ya tenías (el de escritura) por un factor del enunciado (el ratio). Los cuatro números del módulo se encadenan así; aprender a ver qué número alimenta a cuál es la mitad de la habilidad.

¿De dónde sale el ratio 100:1?

En Enlace el ratio 100:1 viene dado por el enunciado, pero conviene entender por qué es creíble y qué harías si no te lo dieran, porque en un problema real casi nunca te regalan el ratio. La intuición es del propio dominio: un acortador de URLs existe para compartir enlaces, y un enlace se crea una vez pero se abre muchas. Alguien acorta la liga de un artículo y la publica en una red social; esa única escritura genera decenas o cientos de lecturas conforme la gente hace clic. Un ratio de 100 lecturas por escritura es, si acaso, conservador para un enlace popular —los virales llegan a miles—, y muy generoso para uno que nadie abre. En promedio sobre todo el sistema, 100:1 es una cifra razonable y redonda, y por eso es el número-ancla.

Si un enunciado no te diera el ratio, lo estimarías razonando el comportamiento típico: ¿cuántas veces se lee cada cosa que se escribe? Para un feed de red social podría ser 10:1 o 100:1 (se escribe un post, lo leen muchos seguidores); para un sistema de registro de auditoría podría ser 1:100 al revés (se escribe mucho, se lee rara vez); para un chat, cerca de 1:1 (cada mensaje enviado se entrega y se lee una o dos veces, como en el ejercicio 1). El ratio es un supuesto que declaras, igual que el factor de pico. Lo importante no es acertarlo al decimal, sino ubicarlo en la marca correcta —¿es este sistema de lectura pesada, de escritura pesada, o balanceado?— porque de esa marca sale la mitad del diseño. Para Enlace la respuesta es clarísima: lectura pesada, 100:1, y todo lo demás se sigue de ahí.

Lo nuevo: promedio contra pico

Todo lo anterior fue el QPS promedio: repartimos el total del mes por igual entre todos los segundos, como si a las 3 de la mañana Enlace recibiera tantas visitas como al mediodía. No es así. El tráfico real de casi cualquier servicio dirigido a humanos tiene una curva diaria: sube en horas de actividad, baja de madrugada, y tiene picos. Dibujado a grandes rasgos, un día de Enlace se ve más o menos así:

QPS de lectura a lo largo de un día (esquemático)
                                    ██
 pico  ~12,000 ┤                   ████
               ┤                  ██████         ██
               ┤             ██   ██████   ██   ████
 prom  ~4,000  ┤········██···██···██████···██···████···██·······  ← promedio
               ┤   ██  ████ ████ ██████ ████ ██████ ████  ██
 valle ~1,000  ┤ ████████████████████████████████████████████
               └──┬────┬────┬────┬────┬────┬────┬────┬────┬──
                  0    3    6    9   12   15   18   21   24  hora

El promedio (~4,000/s) es la línea punteada, pero el sistema no vive en el promedio: vive tanto en el valle de la madrugada (~1,000/s) como en el pico de la tarde (~12,000/s). Y aquí está la regla de oro del dimensionamiento:

Un sistema se dimensiona para el pico, no para el promedio. Un sistema que solo aguanta el promedio colapsa en su hora pico, que es exactamente cuando más gente lo usa.

¿Cuánto más alto es el pico que el promedio? Ese cociente se llama factor de pico (peak-to-average ratio), y para servicios web dirigidos a humanos suele estar entre 2x y 3x. No es una ley física; depende del servicio (uno usado en horario laboral tiene picos más marcados que uno global 24/7), pero 2-3x es el rango de servilleta razonable. Aplicándolo a Enlace:

qps_write_avg = 40
qps_read_avg = 4000
for factor in (2, 3):
    print(f"pico x{factor}:  escritura {qps_write_avg*factor}/s   lectura {qps_read_avg*factor}/s")

Qué esperar.

pico x2:  escritura 80/s   lectura 8000/s
pico x3:  escritura 120/s   lectura 12000/s

Así que Enlace, en su hora pico, recibe del orden de ~80–120 escrituras/s y ~8,000–12,000 lecturas/s. Estos son los números para los que hay que dimensionar. Nota que aun el pico de escritura (120/s) sigue siendo trivial para una base de datos —la escritura de Enlace no preocupa ni en el pico—, mientras que el pico de lectura (12,000/s) confirma con más fuerza la necesidad de caché y réplicas: doce mil lecturas por segundo pegándole al disco de una sola base de datos es una receta para el desastre.

Un matiz que la curva diaria hace visible: como el valle (~1,000/s de madrugada) es una fracción del pico (~12,000/s), tener servidores encendidos para el pico las 24 horas desperdicia capacidad de noche. Por eso los sistemas modernos escalan con la curva —encienden máquinas para el pico y las apagan en el valle, lo que se llama auto-scaling—, pagando solo por lo que usan en cada momento. La estimación del pico y del valle es justo lo que alimenta esa política: sin los dos números no sabrías entre cuántas y cuántas máquinas oscilar. No diseñamos el auto-scaling en esta guía (es tema de despliegue y operación), pero el par promedio-pico que calculas aquí es su insumo directo, y es otra razón para reportar siempre los dos.

Cómo reportarlo. Un estimador maduro da las dos cifras: "~4,000 lecturas/s en promedio, ~8,000–12,000/s en pico (factor 2–3x)". Reportar solo el promedio esconde el requisito real; reportar solo el pico exagera la carga típica. Las dos juntas cuentan la verdad: el sistema opera casi siempre en el promedio pero debe sobrevivir el pico.

Con esto, la fila de QPS de la tabla de capacidad de Enlace queda completa. Esta es la forma en que la vas a entregar en la lección 8:

OperaciónQPS promedioQPS pico (3x)Conclusión
Escritura (shorten)~40/s~120/strivial incluso en pico; una BD sola sobra
Lectura (resolve)~4,000/s~12,000/spide caché + réplicas; ~media docena de servidores

Cuatro números en una fila, cada uno defendible, y una conclusión de diseño por operación. Esa densidad —número + qué significa— es lo que distingue una tabla de capacidad útil de una lista de cifras sueltas.

La escalera del mismo número: mes → día → segundo

Un truco útil para no perderte y para poder verificar es calcular el QPS por pasos, bajando la escalera de unidades de tiempo, en vez de dividir de golpe entre 2.6 millones. A veces un enunciado te da "por día" y otras "por mes", y bajar la escalera funciona igual. Para las lecturas de Enlace:

reads_per_month = 100_000_000 * 100   # 100M escrituras x 100 lecturas c/u
reads_per_day = reads_per_month / 30
reads_per_hour = reads_per_day / 24
reads_per_sec = reads_per_hour / 3600
print(f"lecturas/mes  = {reads_per_month:,.0f}")
print(f"lecturas/dia  = {reads_per_day:,.0f}")
print(f"lecturas/hora = {reads_per_hour:,.0f}")
print(f"lecturas/seg  = {reads_per_sec:,.0f}  -> ~4,000/s")

Qué esperar.

lecturas/mes  = 10,000,000,000
lecturas/dia  = 333,333,333
lecturas/hora = 13,888,889
lecturas/seg  = 3,858  -> ~4,000/s

Cada escalón es una división por la conversión de tiempo correspondiente (÷30 para bajar de mes a día, ÷24 de día a hora, ÷3,600 de hora a segundo), y al final aterrizas en el mismo ~3,858/s que obtuviste dividiendo de golpe entre 2.6 millones. Bajar la escalera es útil por dos motivos: primero, es más fácil de verificar de cabeza (dividir entre 30, entre 24 y entre 3,600 por separado es más manejable que entre 2,592,000); segundo, te regala números intermedios valiosos. En particular, el paso "por día" te da ~333 millones de lecturas por día (o ~345.6 millones si partes del redondeado de 4,000/s × 86,400). Ese "por día" no es un desperdicio: es justo el insumo de la lección 6 para estimar el working set de la caché. Los números del módulo se reciclan entre lecciones; calcular el de lectura por día aquí te adelanta trabajo allá.

Del QPS a los servidores: para qué sirve el número

El QPS no es un adorno; su propósito es responder "¿cuántas máquinas necesito?". La cuenta es tan simple como el resto del módulo: si conoces (o supones) cuántas peticiones aguanta un servidor por segundo, el número de servidores es el QPS pico dividido entre esa capacidad, más un margen.

Supón que un servidor de aplicación de Enlace, sirviendo redirecciones desde caché, maneja cómodamente unas 2,000 peticiones/s (un supuesto de servilleta razonable para trabajo ligero). Entonces:

qps_read_peak = 12_000        # pico de lectura (factor 3x sobre 4,000)
per_server = 2_000            # capacidad supuesta por servidor
servers_needed = qps_read_peak / per_server
print(f"servidores para el pico = {servers_needed:.0f}")
print(f"con margen (+1 de reserva) = {servers_needed + 1:.0f}")

Qué esperar.

servidores para el pico = 6
con margen (+1 de reserva) = 7

Del orden de media docena de servidores de aplicación cubren el pico de lectura de Enlace, más uno de reserva por si alguno falla. Ese "+1" no es capricho: es el principio de redundancia (módulo 7) asomándose —si dimensionas con exactamente los que necesitas y uno se cae, los demás quedan sobrecargados—. Fíjate en la cadena de razonamiento completa que acabas de recorrer: enunciado (100M/mes) → QPS promedio (4,000/s) → QPS pico (12,000/s) → servidores (≈7). Cada flecha fue una cuenta de servilleta, y al final tienes un número de máquinas que puedes defender. Eso es para lo que sirve el QPS: no para saberlo, sino para dimensionar.

La misma cuenta, hecha con el pico de escritura, confirma lo que ya sospechabas: 120/s ÷ 2,000/s por servidor ≈ 0.06 servidores, es decir, una fracción de un solo servidor. La escritura de Enlace no justifica ni una máquina dedicada; cabe de sobra en cualquiera. Toda la presión de capacidad está en la lectura, y el QPS lo dice con números.

Un poco de intuición: el QPS de otros sistemas

Los números en abstracto no dicen mucho hasta que tienes con qué compararlos. Esta tabla (valores aproximados, de orden de magnitud, para calibrar el oído) ubica el QPS de lectura de Enlace entre sistemas de distintas escalas:

SistemaQPS de lectura (orden de magnitud)Qué carga es
Un blog personal~1–10/strivial: un servidor sobra
Enlace (nuestro caso)~4,000/s (pico ~12,000/s)media: pide caché y unas pocas máquinas
Una API grande de empresa~10⁵/s (cientos de miles)alta: réplicas, sharding, muchos servidores
Un gigante global (buscador, red social top)~10⁶–10⁷/s (millones)extrema: miles de máquinas, múltiples centros de datos

Enlace vive en la banda media: no es un juguete (4,000/s ya obliga a pensar en caché), pero está muy lejos de necesitar la maquinaria de un gigante. Esta ubicación importa para el diseño: te dice que las soluciones de Enlace serán "una caché, unas réplicas, media docena de servidores", no "sharding global con cientos de nodos". Diseñar Enlace como si fuera un gigante sería la sobreingeniería contra la que te vacunó la lección 1; el QPS, comparado con estas referencias, te mantiene con los pies en la tierra.

QPS no es lo mismo que conexiones simultáneas

Vale la pena separar dos números que se confunden seguido, porque miden cosas distintas y dimensionan recursos distintos. El QPS cuenta peticiones que empiezan y terminan cada segundo. Las conexiones simultáneas (o concurrencia) cuentan cuántas peticiones están abiertas a la vez en un instante dado. No son iguales, y el puente entre ellos es cuánto dura cada petición.

La relación, conocida como Ley de Little en su forma simple, es:

conexiones simultáneas ≈ QPS × duración media de cada petición

Para Enlace, una redirección desde caché es rapidísima —digamos que cada resolve toma unos 10 ms (0.01 s) de principio a fin—. Entonces, en el pico:

qps_read_peak = 12_000
seconds_per_request = 0.010        # 10 ms por redireccion desde cache
concurrent = qps_read_peak * seconds_per_request
print(f"conexiones simultaneas ~ {concurrent:.0f}")

Qué esperar.

conexiones simultaneas ~ 120

Aunque Enlace atiende 12,000 peticiones por segundo en el pico, en cualquier instante dado solo hay unas ~120 abiertas a la vez, porque cada una vive apenas 10 ms. Esta distinción es la que dimensiona cosas como el número de conexiones a la base de datos o el tamaño de los pools: no necesitas 12,000 conexiones abiertas, necesitas ~120. Y revela algo importante: si las peticiones fueran lentas, la concurrencia explotaría. Si cada resolve tomara 1 segundo en vez de 10 ms (por ejemplo, pegándole al disco sin caché), la concurrencia saltaría a 12,000 conexiones simultáneas —cien veces más—, y ahí sí el sistema se ahogaría. Otra razón, dicha con números, de por qué la caché de Enlace importa: no solo baja la carga del disco, sino que mantiene las peticiones cortas y por lo tanto la concurrencia baja.

Errores comunes

Dimensionar para el promedio y no para el pico (de subdimensionamiento). Qué pasa: alguien calcula "4,000 lecturas/s" y dimensiona el sistema justo para eso, y el sistema se cae todas las tardes en hora pico. Por qué pasa: el promedio es el número que sale directo de la división, y es fácil olvidar que el tráfico real no es parejo. Cómo detectarlo: si tu diseño aguanta exactamente el QPS promedio y ni un poco más, no tiene margen para el pico. Cómo corregirlo: multiplica el promedio por el factor de pico (2–3x) y dimensiona para ese número. Y reporta ambos. El promedio es para entender el volumen; el pico es para dimensionar la capacidad.

Mezclar lecturas y escrituras en un solo QPS (de agregación que oculta). Qué pasa: la persona reporta "Enlace hace ~4,040 peticiones/s" sumando lecturas y escrituras, y con eso pierde la información más importante del sistema. Por qué pasa: da la impresión de que "el QPS total" es más simple. Cómo detectarlo: si tu número de QPS no distingue lectura de escritura, escondiste la asimetría 100:1 que define a Enlace. Cómo corregirlo: siempre reporta los dos por separado. La brecha entre ellos (40 vs 4,000) es la que dicta la mitad del diseño; sumarlos la borra.

Confundir "usuarios" con "peticiones" (de unidad equivocada). Qué pasa: alguien lee "Enlace tiene 10 millones de usuarios" y lo mete como si fuera QPS o peticiones/mes. Por qué pasa: los enunciados mezclan métricas de negocio (usuarios, cuentas) con métricas de carga (peticiones), y no todas sirven para estimar QPS. Cómo detectarlo: si tu QPS salió de un número de "usuarios" sin pasar por "cuántas peticiones hace cada usuario", saltaste un paso. Cómo corregirlo: para llegar a QPS necesitas eventos por unidad de tiempo (URLs/mes, visitas/día), no un conteo de personas. Si solo te dan usuarios, tienes que asumir cuántas acciones hace cada uno —y declarar ese supuesto—. En Enlace el enunciado ya te da el evento directo (100M URLs/mes), así que no caes en esto; pero en otros problemas es la primera trampa.

Ejercicios

Ejercicio 1 — El QPS de un servicio nuevo. Un servicio de mensajería procesa 2,000 millones de mensajes enviados por día. (a) ¿Cuál es el QPS de escritura promedio? (b) Si cada mensaje se lee (se entrega y se abre) unas 2 veces en promedio, ¿cuál es el QPS de lectura? (c) Con un factor de pico de 2x, ¿cuál es el QPS de lectura pico? Muestra la aritmética con potencias de 10.

Ver solución
  • (a) 2,000 millones/día = 2 × 10⁹ / día. Un día = 86,400 s ≈ 8.64 × 10⁴. qps_write = 2 × 10⁹ / (8.64 × 10⁴) = (2 / 8.64) × 10⁵ ≈ 0.23 × 10⁵ ≈ 23,000/s. Redondeado: ~23,000 escrituras/s (o "del orden de decenas de miles/s").
  • (b) Ratio 2:1, así que qps_read = 23,000 × 2 = ~46,000 lecturas/s.
  • (c) Pico 2x: 46,000 × 2 = ~92,000/s, o "~90,000 lecturas/s en pico".

Nota lo distinto que es de Enlace: aquí la escritura ya es enorme (23,000/s, contra los 40/s de Enlace) porque el volumen de entrada es gigantesco (2 mil millones/día contra 100 millones/mes ≈ 3.3 millones/día). El método es idéntico; los números cambian con la escala del enunciado, que es justo por qué se calcula y no se cita.

Ejercicio 2 — ¿Por qué el pico, no el promedio? Un compañero dice: "dimensioné Enlace para 4,000 lecturas/s, que es el promedio; si a veces llega a 12,000 en la tarde, pues que se encole un poco, se desahoga solo cuando baja el tráfico". Explica en dos o tres frases por qué este razonamiento es peligroso y qué le falta.

Ver solución

El razonamiento falla porque la hora pico no es un instante, es horas, y durante todo ese tiempo la carga (12,000/s) triplica la capacidad (4,000/s). Una fila que crece durante horas a triple velocidad de la que se vacía no "se desahoga sola": explota —la latencia se dispara, las peticiones expiran, los usuarios ven errores—, y todo esto pasa en la ventana de mayor tráfico, que es cuando más importa. Encolar sirve para absorber un pico breve (segundos), no un régimen sostenido de sobrecarga. Lo que le falta: dimensionar para el pico (multiplicar el promedio por el factor 2–3x) para que la capacidad supere a la carga incluso en el peor momento. El margen no es lujo; es lo que evita el colapso en el momento de mayor uso.

Ejercicio 3 — Encadenar sin datos nuevos. Solo con que Enlace hace ~40 escrituras/s y el ratio es 100:1, sin ningún otro dato, deriva: (a) las lecturas por segundo; (b) las lecturas por día; (c) las escrituras por día. Di cuál de estos tres números vas a necesitar en la lección 6 (memoria del working set) y por qué.

Ver solución
  • (a) 40/s × 100 = 4,000 lecturas/s.
  • (b) 4,000/s × 86,400 s/día = 345,600,000 ≈ 345.6 millones de lecturas/día.
  • (c) 40/s × 86,400 = 3,456,000 ≈ 3.46 millones de escrituras/día (equivalente a los ~3.33 millones que salen de dividir 100M/mes entre 30; la pequeña diferencia viene de redondear 38.6 a 40).

El número clave para la lección 6 es las escrituras por día (~3.3 millones), porque son las URLs nuevas que entran cada día, y el working set de la caché se estima como una fracción (el 20% caliente) de las URLs distintas en juego —y las URLs nuevas del día son un buen proxy de ese conjunto que cambia—. Las lecturas por día (345.6M) cuentan visitas, no URLs distintas: una misma URL viral se lee miles de veces pero ocupa una sola entrada en la caché. Distinguir "eventos" de "cosas distintas" es la clave de la estimación de memoria, y lo desarrollamos en la lección 6.

Resumen y siguiente paso

En esta lección produjiste la primera fila de la tabla de capacidad de Enlace: el QPS. Calculaste el QPS de escritura (100M/mes ÷ 2.6M s ≈ 38.6 → ~40/s), lo encadenaste con el ratio 100:1 para obtener el QPS de lectura (40 × 100 = ~4,000/s), y aplicaste el factor de pico (2–3x) para los números que de verdad hay que aguantar: ~80–120 escrituras/s y ~8,000–12,000 lecturas/s en la hora pico. Aprendiste la regla de oro —se dimensiona para el pico, no para el promedio— y por qué se separan lecturas de escrituras desde el primer número: la brecha de 100x entre ellas es la firma read-heavy de Enlace y la justificación de la caché y las réplicas que vienen.

Antes de avanzar deberías poder: convertir "N eventos por mes (o por día)" en QPS contando ceros; encadenar el QPS de lectura desde el de escritura vía el ratio; aplicar un factor de pico y explicar por qué se dimensiona para el pico; y reportar promedio y pico juntos, separando lectura de escritura.

El siguiente número es el almacenamiento. En la lección 4 vas a responder "¿cuánto disco necesita Enlace en cinco años?" multiplicando tres cosas —cuántos registros por mes, por cuántos meses, y cuánto pesa cada registro— para llegar a los ~6 TB. Es un tipo de cuenta distinto al QPS (acumula en el tiempo en vez de repartir por segundo), y trae sus propias sutilezas: los índices, las réplicas, y qué significa "cabe pero se planea".

Recursos

  • Martin Kleppmann, Designing Data-Intensive Applications, Capítulo 1, "Describing Load" y el ejemplo de Twitter — dataintensive.net. Kleppmann usa el fan-out de Twitter para mostrar cómo el ratio lectura/escritura decide toda la arquitectura, exactamente el razonamiento que aplicamos al 100:1 de Enlace. Lectura muy recomendada; en inglés.
  • The System Design Primer, "Back-of-the-envelope" y el ejemplo del acortador de URLs (Pastebin/URL shortener) — github.com/donnemartin/system-design-primer. Recorre un cálculo de QPS para un caso casi idéntico a Enlace. Gratis, en inglés.
  • Documentación de PostgreSQL, "Performance Tips"postgresql.org/docs/current/performance-tips.html. Para calibrar qué significa "40/s es trivial" y "12,000/s hay que tomarlo en serio" en una base de datos real. No hace falta leerla entera; sirve para poner en contexto los números de QPS.