En 2023, la gloria está a solo 11 MB/s de distancia
(thmsmlr.com)- Incluso un sitio web dentro del top 1000 con unos 200 millones de visitas mensuales requiere, viendo solo el HTML, alrededor de 30 TB/mes, es decir, un promedio de 11 MB/s de transferencia, una escala que un solo servidor puede manejar
- El cálculo parte de Business Insider, asumiendo 2 páginas por visitante, 400 millones de documentos HTML al mes, HTML comprimido de unos 75 KB, y dejando JS, CSS e imágenes al CDN
- Ejecutar en el edge tiene la ventaja de estar en un servidor cercano al usuario, pero si durante el renderizado hay viajes de ida y vuelta a la base de datos, la latencia vuelve a quedar atada a la ubicación de la base de datos original
- La diferencia de costos también es grande: Hetzner ofrece un servidor con 16 núcleos, 64 GB de RAM y NVMe por $0.34/hora, con 20 TB de transferencia gratis y luego $1.5/TB, mientras que AWS y Vercel tienen costos de ancho de banda mucho más altos
- A menos que sea una carga que realmente necesite la nube, una configuración de servidor único + SQLite + Litestream + CDN es más simple y barata, y evita la escalabilidad horizontal innecesaria
La escala real de un sitio destacado vista desde 11 MB/s
- Se usa Business Insider como ejemplo de un sitio dentro del top 1000
- Según SimilarWeb, ocupaba el puesto 587 a nivel mundial y tenía unas 200 millones de visitas al mes
- Si se toman 2 páginas por visitante en promedio, hay que servir 400 millones de documentos HTML al mes
- En un artículo de muestra, el documento HTML estándar pesa unos 75 KB después de comprimirlo
- Multiplicando eso, solo el HTML requiere alrededor de 30 TB/mes de ancho de banda
- 30 TB/mes equivalen, en promedio, a unos 11 MB/s
- En el caso de Business Insider, eso da unas 150 requests/sec
- Se asume que no se usa CDN para el HTML, mientras que JS, CSS e imágenes sí pueden servirse por CDN
- Los 75 KB de HTML comprimido son un tamaño relativamente grande, así que según la implementación también se puede reducir el tamaño del HTML o aumentar el número de requests
- En hardware moderno, generar 11 MB/s de HTML con código de aplicación es una exigencia baja
- Los procesadores de servidor AMD más recientes ofrecen 64 núcleos y 128 hilos
- Se rumorea que los procesadores de servidor Zen 5 Turin llegarán a 192 núcleos, y en servidores de doble socket se mencionan configuraciones cercanas a 400 núcleos y hasta 768 hilos
- Desde esta perspectiva, Docker, lo serverless y la escalabilidad horizontal no son siempre opciones necesarias
Ejecutar en el edge no siempre reduce la latencia
- El límite físico inferior del viaje de ida y vuelta al otro lado del planeta es de unos 200 ms, según la velocidad de la luz
- En la práctica, muchas veces llegar a un buen datacenter al otro lado del mundo toma alrededor de 300 ms
- Si JS, CSS y medios se sirven desde un CDN, reducir 300 ms del tiempo de procesamiento del servidor en el renderizado inicial puede producir un efecto parecido al de mover el servidor más cerca del usuario
- Las tecnologías serverless de segunda generación han reducido mucho el problema anterior de los cold boot, que fácilmente se comían ese presupuesto de 300 ms de latencia, pero los viajes a la base de datos siguen ahí
- Si una página necesita aunque sea una sola consulta a la base de datos para renderizarse, el servidor edge tiene que volver a hacer un viaje a la ubicación de la base de datos original, como us-east-1
- La latencia se traslada de la ruta entre usuario y servidor original a la ruta entre servidor edge y servidor original
- Las páginas complejas muchas veces requieren 5 o más consultas a la base de datos para renderizarse
- Muchos frameworks web ejecutan las consultas de forma secuencial en un solo hilo, así que varios viajes entre datacenters pueden terminar siendo más lentos que ir una sola vez al origen
- Hay una regla práctica según la cual la comunicación entre datacenters es 10 veces más lenta que dentro de un datacenter, y dentro de un datacenter es 10 veces más lenta que dentro del mismo dispositivo
- En este contexto, SQLite local aparece como una opción favorable para reducir la latencia
Diferencias de costo entre Hetzner, AWS y Vercel
- El servidor de 16 núcleos de Hetzner cuesta $0.34/hora e incluye 64 GB de RAM y unidad NVMe
- En AWS, el m5a.4xlarge de EC2, comparado como un servidor x86 similar, cuesta $0.68/hora
- La diferencia en el precio del ancho de banda es todavía mayor
- Hetzner ofrece 20 TB de transferencia gratis y después cobra $1.5/TB
- AWS ofrece 100 GB gratis y luego cobra $90/TB
- Se menciona a Vercel como ejemplo: después del primer 1 TB gratis, cobra $200/TB
- Las cuotas gratuitas de los proveedores cloud facilitan el arranque, pero cuando el proyecto escala pueden convertirse en costos elevados
Operar de forma simple con una configuración de servidor único
- Salvo en casos de uso específicos de nube, como transcodificación de video, ejecutar modelos de IA propios o trabajos que realmente metan una carga fuerte al sistema, un sitio web o SaaS puede correr en un solo servidor
- Si el servidor está en Virginia, puede ofrecer a usuarios angloparlantes una latencia menor a 100 ms
- La configuración recomendada se centra en una sola máquina y la mantiene simple
- La base de datos usa SQLite en la misma máquina
- Litestream hace backup continuo de SQLite
- CSS, JS e imágenes se cachean en un CDN
- El renderizado del servidor se hace cerca de SQLite para reducir viajes de ida y vuelta y mejorar el rendimiento
- Tampoco hace falta complicar el despliegue
- El CI puede enviar el código al servidor por SCP
- NGINX admite despliegues sin tiempo de inactividad
- Docker y la virtualización se consideran factores que ralentizan la ejecución del código y el CI/CD
Cuándo hace falta escalabilidad horizontal y cuándo no
- La idea de que siempre hace falta escalabilidad horizontal está exagerada en la mayoría de los casos
- La premisa es que el rendimiento de los servidores mejora más rápido que el crecimiento de internet
- Si la latencia realmente importa, se puede agregar una configuración con servidores en Alemania y California
- Las escrituras se enrutan al primary
- Las lecturas usan un read replica local
- Este tipo de configuración escala lo suficiente, mantiene baja la complejidad operativa y además resulta bastante barata
- Servir HTML a escala de 11 MB/s no hace falta volverlo innecesariamente difícil
1 comentarios
Opiniones de Hacker News
Mi antiguo pequeño negocio de hosting pasó por su auge y caída justo en este punto, y en ese momento no entendía qué estaba pasando.
Cuando crecíamos a principios de los 2000, los ingresos grandes casi siempre venían de stacks complejos, y había muchas configuraciones que los clientes querían aunque en realidad excedían sus necesidades, como balanceadores de carga y firewalls redundantes.
El failover a menudo tenía un costo de complejidad operativa mayor que el beneficio que se obtenía cuando un servidor moría de la forma prevista, y también construimos una plataforma de hosting en la nube basada en API para competir con AWS, pero los ingresos llegaron a su punto máximo en 2012.
Los clientes querían soluciones más complejas que usaran AWS en parte o por completo, mientras que nosotros pensábamos que, como el hardware se había vuelto mucho más potente que 10 años antes, incluso los clientes grandes querrían servidores menos numerosos y más simples.
Pero eso no era vender inteligencia, sino vender precio, y no entendimos la ambición financiera necesaria para esa transición. Nadie confiaba en un servidor único barato, y aunque compraran dos, faltaba una respuesta a la escalabilidad.
Al final los ingresos se sostuvieron, pero no pudimos crear un stack de servicios administrados y un ecosistema de software más rápido que Amazon, y vendimos la empresa en 2018, después de que se agotaran los nuevos desafíos técnicos.
Como habíamos crecido con bootstrapping, una factura de hosting sin límite se sentía como un riesgo demencial, y el diseño del producto también salió de esa forma de pensar; recién después vi que todos estaban asumiendo ese riesgo.
AWS se arraigó no solo porque el VC hizo posibles productos caros, sino porque su tipo particular de ingenio quedó incorporado en toda una generación de desarrolladores de software. Eso sí, el conocimiento de cuándo no se necesita la nube y cuáles son las alternativas ahora se siente bastante de nicho.
Hay varios problemas con los números.
Primero, el tráfico no se distribuye de manera uniforme. La cifra del artículo de 400 millones de cargas de página al mes puede estar sujeta a una regla 80/20 recursiva, y visto así se concentran unos 205 millones de requests durante 5.8 horas, lo que da unos 9.7 mil requests por segundo.
Es posible con un solo sistema, pero ya no es trivial, especialmente si además se quiere una sola DB sin réplicas de lectura. Aunque el tráfico total sea el mismo, el límite de ancho de banda necesario para la carga pico termina siendo mucho mayor que los 11 MB/s promediados de forma optimista.
Segundo, la latencia unidireccional de extremo a extremo solo aplica a datos en streaming. En un cold start real, si no hay HTTP/3, se necesitan 3 viajes de ida y vuelta para la conexión TCP y al menos 2 para la conexión TLS, y recién después van y vienen el request y la respuesta HTTP.
Para servir a personas reales, todo lo observable debe ocurrir en menos de 1 segundo; después de eso, la proporción de usuarios que concluyen que el sistema está roto y cierran la pestaña aumenta drásticamente.
Hace tiempo ayudé a operar una bolsa de apuestas: el tráfico tenía picos extremos y los requisitos de latencia eran estrictos, y el volumen de operaciones se concentraba en una fracción muy pequeña de toda la ventana del evento. En trading en tiempo real, el resultado tenía que aparecer en pantalla dentro de los 100 ms desde que el usuario iniciaba la acción, y la latencia de ida y vuelta de la red se comía el presupuesto de procesamiento del evento.
Referencia: https://www.nngroup.com/articles/response-times-3-important-...
Esa carga también se puede manejar con una configuración de servidor único grande, pero ya no se trata de un simple servidor web, sino de construir un balanceador de carga frontend bastante potente con un servidor web incorporado.
Aunque AWS cobre caro, hay una enorme ingeniería en sus balanceadores de carga e infraestructura de red, y gracias a eso los demás no tenemos que convertirnos en expertos en toda esa parte del stack.
¿Cuántos servicios realmente necesitan alcance global? ¿También construyeron soporte para varios idiomas?
Si prestas servicio dentro de Estados Unidos o la UE, con un buen servidor central puedes dar latencia por debajo de 30 ms a toda esa región.
Salvo que tengas un requisito verdaderamente global y además debas administrar una base de datos global, el edge está sobrevalorado.
Al ver que aparece
500 Internal Server Error, parece que el autor está recibiendo más tráfico que 11 MB/s. La copia archivada está aquí: https://archive.is/UVpg0PR_END_OF_FILE_ERROR. Varios sitios web dicen que puede deberse a proxies, VPN o DNS-over-HTTPS, pero en mi caso no aplica.Creo que este artículo está mirando el problema de forma equivocada.
Un mejor enfoque es no escalar demasiado pronto.
Construye lo que necesites, y en la mayoría de los casos incluso un CDN es un costo innecesario, siempre que no estés pagando el impuesto excesivo de ancho de banda de un proveedor cloud.
Si empiezas a ver problemas de rendimiento, entonces los atiendes; y si tu caballo de batalla común de pronto se convierte en el unicornio que todos quieren, ese es un problema que quisieras tener.
Si el producto es bueno, los usuarios volverán a intentar una hora después en vez de cambiarse de inmediato a un competidor. Si aparecen problemas de escalabilidad, puedes pasar a un modelo híbrido donde solo se escalen las partes intensivas en recursos.
Aun así, si desde el principio quieres webscale, decenas de microservicios, estados de falla que explotan entre ellos y quemar dinero de VC en la factura de AWS antes del primer cliente, adelante.
Operar servidores físicos propios es un problema para después, no para ahora. Para cuando tenga que elegir entre una factura de AWS de un millón de dólares y un gran servidor único, no voy a decidir leyendo un post de blog: estaré corriendo mis propias pruebas.
Cuando usas AWS, también estás comprando un chivo expiatorio. Una caída de un gran servicio cloud es fácil de explicar a tu jefe o a inversionistas, pero es mucho más difícil explicar que el mismo tiempo de inactividad acumulado se debió a errores humanos del equipo.
Entonces me pregunto cómo encaja eso con la interpretación de que la nube es un chivo expiatorio.
Si estás apuntando a escalar verticalmente, ¿por qué SQLite? Nada impide ejecutar Postgres autohospedado o Supabase junto con la app en el mismo servidor, y no se me ocurren muchas desventajas aparte de que requiere más esfuerzo de configuración.
Si vas sin DB y mantienes todo el estado global en la memoria real de un gran servidor, lo conservas como objetos dentro del proceso sin idas y vueltas a Redis, de vez en cuando haces snapshots de la memoria a disco y usas un lenguaje multihilo compilado, puedes saturar una NIC de más de 1 Gbit y servir al mundo desde una sola caja.
También me gustaría que hubiera casos reales para usar una arquitectura así.
Fuera de los patrones estándar de persistencia relacional, las diferencias de funcionalidad son grandes y Postgres puede ser mejor, pero en ciertos patrones arquitectónicos SQLite también puede estar por delante.
En aplicaciones centradas en contenido como BusinessInsider, el patrón Baked Data basado en SQLite puede ser mejor en costo y latencia.
simonw (datasette) creó muchas herramientas y artículos sobre el uso de SQLite en producción para sitios web centrados en contenido o ricos en datos: https://simonwillison.net/2021/Jul/28/baked-data/
Tiene sentido, porque SQLite corre dentro del proceso y no necesita serialización. Además, tiene la ventaja adicional de que las operaciones pueden procesarse en serie, lo que hace mucho más fáciles las pruebas, el razonamiento y la construcción de capas de caché.
Si no usas sockets Unix también hay sobrecarga de red, pero como se dijo que es el mismo servidor, lo dejo como punto adicional. En la práctica, es muy común poner Postgres en otra máquina por aislamiento, y esa también es una de las principales ventajas de una DB en red.
Tiene todas las funciones necesarias, y además ofrece más simplicidad y velocidad. SQLite puede manejar datos de terabytes, múltiples lecturas y backups por streaming en tiempo real, y en general es una implementación de SQL bastante equilibrada.
Solo consideraría Postgres/MySQL cuando se supere el escalamiento vertical de una sola caja.
https://blog.cloudflare.com/introducing-d1
Parece que mucha gente, al ver que el autor se enfoca en latencia, ancho de banda y costo, siente que debe defender el estado actual por razones de disponibilidad y confiabilidad.
Mi conclusión no es negar las ventajas de la nube frente a los trade-offs, sino preguntar si los patrones de arquitectura cloud que ahora están en todas partes, y sus dependencias asociadas, son realmente imprescindibles.
La comparación de esto contra aquello es un recurso retórico para presentar alternativas, y cuál solución es la correcta depende de muchísimos factores según el caso de uso. Justamente esos factores son los que les dan trabajo a los ingenieros.
Aun así, incluso dentro del patrón que propone el autor se pueden resolver las preocupaciones de SRE. “¿Y qué pasa con la disponibilidad si se cae un solo servidor?” es casi un hombre de paja, porque la disponibilidad puede resolverse de maneras distintas a las de los sistemas a los que estamos acostumbrados, y la solución debe ajustarse a lo que realmente importa.
Hay una forma de obtener mucho más con un presupuesto austero agregando solo un nivel: colocar juntos la API y la DB SQLite.
Idealmente, la API usaría un formato de serialización binaria de baja sobrecarga y conexiones persistentes, y para servir la web se podría aprovechar el nivel gratuito de algún servicio edge financiado por VC que quema dinero. Por ahora Cloudflare Workers es bastante generoso y el tráfico de salida también es gratis.
La clave es que SQLite puede manejar una cantidad enorme de consultas por segundo incluso con un solo hilo. Puedes empujar muchas operaciones en serie, lo que facilita el razonamiento, y el cacheo en memoria del lado de la API y la invalidación también se vuelven más simples.
Separar el servido web permite aprovechar el rendimiento del edge en los handshakes y omitir por completo la DB en páginas estáticas. El artículo subestimó el problema del tiempo de ida y vuelta; las apps reales requieren más idas y vueltas de lo que uno cree, así que este problema es bastante real.
La mayor parte del uso de CPU fuera de la DB viene del parsing, la deserialización, la copia de datos y TLS, así que al quitar una porción grande puedes conseguir fácilmente decenas de miles de escrituras por segundo incluso en máquinas básicas, y las lecturas son aún más rápidas.
Aun así, siempre vale la pena hacer benchmarks de los cuellos de botella típicos, especialmente I/O. Los proveedores suelen exagerar o inducir a error, así que hay que probarlo directamente en el nivel gratuito. También conviene tener listas pruebas de integración y benchmarks para cuando toque migrar.
Para resultados grandes funciona bastante bien, pero espero que el propio PostgreSQL no se convierta en cuello de botella al convertir datasets grandes a JSON.
La gente dice que hay que estar en el edge, cerca del usuario, y reducir la latencia.
Pero, en la práctica, ¿qué tan grande es el problema de la latencia?
Un ejemplo es Gnooks, un proyecto de recomendación de libros operado desde un servidor en Alemania: https://www.gnooks.com
Me pregunto si a alguien le parece demasiado lento.
En los últimos años recibí miles de sugerencias de usuarios para este proyecto, pero que yo recuerde nadie sacó el tema de la latencia. Y eso que el grupo más grande de usuarios está en EE. UU.
Por eso sufre mucho menos problemas de latencia que una PWA moderna que implementa la mayor parte de la lógica en el frontend y luego envía varias consultas al backend para cargar los datos necesarios.
Aun así, el sitio en sí está bien. Si el sitio ya fuera lento, ahí sí se volvería un problema.
Si haces eso desde Europa, obtendrás aproximadamente el doble de la latencia que ve un usuario australiano, lo que ayuda a estimar la peor experiencia.
Lo bueno es que esto se puede probar de forma confiable para verificar si realmente importa. Así se obtiene una respuesta concreta.
El artículo no aborda en absoluto la disponibilidad. Un servicio que corre en una sola máquina tendrá tanto downtime planificado como downtime inesperado.
También hay que pensar en RPO/RTO. Cuando la máquina se rompa —o mejor dicho, si se rompe— hay que ver cuánto tardará la recuperación y cuántos datos se perderán.
Respecto a la frase de que, si hay aunque sea una consulta a la base de datos para renderizar una página, hay que volver a la DB en us-east-1, existen estas opciones:
https://aws.amazon.com/rds/aurora/global-database/
https://aws.amazon.com/dynamodb/global-tables/
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Conce...
https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/...
Hay muchas cosas parecidas más, y sufrirás si intentas armar algo equivalente por tu cuenta de forma improvisada.
Hace 10 o 20 años habría estado de acuerdo. Internet era nuevo, la gente culpaba al sitio si se caía y la situación se ponía fea rápidamente. Pero ahora es más probable que culpen primero al proveedor de internet o que intenten de nuevo más tarde.
No todo el mundo es Google, y los sistemas más simples también tienen menos probabilidad de fallar desde el principio. Mantén backups y, si de verdad te preocupa, replica la DB a un sitio frío de recuperación ante desastres. Para la mayoría de las empresas y situaciones que no son FAANG, eso alcanza.
Mientras no se pierdan datos, para muchas empresas no pasa de ser una interrupción breve. Si la comunicación es buena y el evento es muy raro, incluso unos días de caída pueden ser tolerables; en algunos casos, hasta cierta pérdida de datos puede ser tolerable.
Se decía que cada nueve adicional de confiabilidad duplicaba el costo, y eso debe reflejarse al calcular el ROI. Cuánta confiabilidad necesita realmente el negocio depende del mercado objetivo, y creo que la respuesta predeterminada de IT de 100% automático es incorrecta.
Un modelo de servidor único o doble también tiene mucha menos complejidad, y por eso equipos de operaciones como el de LetsEncrypt eligieron esta arquitectura de dos servidores físicos para operar un servicio global a escala web: https://letsencrypt.org/2021/01/21/next-gen-database-servers...
Gracias a la latencia interna muy baja de una DB dentro del servidor o justo al lado, el software puede ejecutar consultas a la DB varios órdenes de magnitud más rápido, usar menos recursos por usuario y ofrecer una experiencia de usuario más ágil que un servicio real de DB administrada.
La complejidad crea sus propias trampas, y creo que no hay servicio web que nunca haya metido la pata con esto. Incluso AWS puede causar incidentes.
No se puede decir que un VPS sea peor en este aspecto.