Cómo mejoramos el rendimiento de Moove en un 59%
La mayoría de los usuarios de Moove está lejos de nuestros servidores. Así redujimos un 59% el tiempo hasta la primera respuesta sin mover ningún servidor.La distancia era nuestra dependencia más lenta
La mayoría de las personas que abren la Moove app están en redes móviles de Nigeria e Indonesia, a miles de kilómetros de los servidores que les responden. Este mes cambiamos la forma en que sus solicitudes llegan hasta nosotros, y nuestro tiempo hasta el primer byte (TTFB), el tiempo que transcurre entre que un teléfono envía una solicitud y llega la primera parte de la respuesta, se redujo un 59%, de 0,74 segundos a 0,31 segundos. Para conseguirlo no movimos ni un solo servidor.
Esta entrada explica por qué la distancia nos costaba más de lo esperado, qué cambiamos, la parte que resultó más difícil que el cambio en sí y qué le diríamos a otro equipo que vaya a hacer lo mismo.
Por qué un viaje largo se convierte en tres
Los ingenieros llaman latencia al retraso entre que se envía algo y llega a su destino, y tiempo de ida y vuelta (RTT) al tiempo que tarda un mensaje en llegar a un servidor y volver con la respuesta. Desde Lagos hasta nuestros servidores, el RTT es de entre 200 y 300 milisegundos. Por sí solo, es tolerable. El problema es que una solicitud rara vez viaja sola.
Antes de que un teléfono pueda pedir nada a través de una conexión segura, tiene que completar dos handshakes (negociaciones de conexión), los breves intercambios que establecen una conexión. El handshake de TCP abre la conexión y, a continuación, el handshake de TLS acuerda las claves de cifrado que la mantienen privada. Cada uno cuesta un viaje de ida y vuelta completo. Solo entonces sale la solicitud propiamente dicha, que es el tercer viaje. A 250 milisegundos por viaje, un usuario espera aproximadamente tres cuartos de segundo antes de que nuestros servidores hayan hecho ningún trabajo.
En las redes móviles, ese coste se paga con mucha más frecuencia de la que cabría esperar. Los teléfonos cambian de antena, las radios se suspenden para ahorrar batería y las aplicaciones pasan a segundo plano. Cualquiera de esos eventos puede cortar la conexión, y la siguiente solicitud tiene que empezar desde una conexión en frío, una en la que todavía no se ha hecho ningún handshake, y pagar de nuevo el coste completo de establecerla. Una conexión en caliente, ya abierta y protegida, pasa directamente a la solicitud.
No podíamos acercar Lagos a nuestros servidores. Sí podíamos acercar el establecimiento de la conexión a Lagos.
Mover el handshake, no los servidores
Una red de distribución de contenidos (CDN) suele describirse como una caché: un conjunto de ubicaciones repartidas por el mundo que guardan copias de archivos para servirlos desde cerca. Nosotros usamos una por otra razón. Para nuestra API, la interfaz con la que la aplicación habla para todo lo que hace, el almacenamiento en caché está totalmente desactivado. Cada solicitud sigue viajando hasta nuestro origen, el nombre que da la CDN a los servidores que tiene detrás.
Lo que cambia es dónde empieza la conexión. Ahora un teléfono abre su conexión con la ubicación perimetral (edge) más cercana, también llamada punto de presencia (PoP): uno de los emplazamientos de la CDN repartidos por el mundo, a menudo a decenas de milisegundos en lugar de cientos. El edge realiza la terminación de TLS, es decir, la conexión segura con el teléfono termina allí. Después reutiliza un conjunto de conexiones en caliente con nuestro origen, mantenidas abiertas con keep-alive, un ajuste que deja una conexión abierta entre solicitudes en lugar de cerrarla. Los dos viajes costosos de preparación ocurren en el tramo corto, y solo la solicitud en sí cruza el océano, por una conexión que ya está en caliente.
Tres viajes largos se convierten en un viaje largo y dos cortos. Esa es toda la idea.
Mantuvimos el resto deliberadamente aburrido:
- Los clientes no notaron nada. La aplicación y el sitio web conservaron las mismas direcciones, así que no hizo falta publicar ninguna versión de la aplicación y nadie tuvo que actualizar nada.
- El comportamiento ante fallos no cambió. Los tiempos de espera coinciden con los de antes, de modo que lo que fallaba antes sigue fallando de la misma manera. No queríamos tipos nuevos de error.
- El edge cierra primero las conexiones inactivas. Toda conexión tiene un tiempo de inactividad máximo (idle timeout), el tiempo que puede permanecer sin uso antes de cerrarse. Si nuestros servidores cerraran una conexión silenciosa mientras el edge aún cree que está abierta, la siguiente solicitud fallaría. Si fijamos un tiempo de espera más corto en el edge, este siempre es el primero en rendirse y abre una conexión nueva.
- Protocolos más modernos para los teléfonos. Los teléfonos pueden conectarse mediante HTTP/3, la versión más reciente del protocolo de solicitudes de la web. Funciona sobre QUIC, que reúne los dos handshakes en un único viaje de ida y vuelta y soporta mejor la pérdida de paquetes habitual en las redes móviles.
- Ninguna región excluida. Los niveles más baratos de una red perimetral suelen omitir ubicaciones justo en las zonas del mundo donde viven nuestros usuarios, así que elegimos una cobertura completa.
Qué medimos
Medimos desde Sídney, que está aproximadamente tan lejos de nuestros servidores como Lagos, comparando la ruta antigua con la nueva. En cada una abrimos cinco conexiones en frío nuevas, el caso que más importa en las redes móviles, y tomamos la mediana, también escrita p50: el resultado central, que la mitad de las solicitudes mejora y la otra mitad no. El mismo proyecto activó además la compresión de los scripts de nuestro sitio web, que se enviaban a tamaño completo. La compresión reduce un archivo antes de enviarlo y el navegador lo expande de nuevo al recibirlo; usamos Brotli, un formato de compresión diseñado para la web.
| Qué medimos | Antes | Después | Mejora |
|---|---|---|---|
| Handshakes de TCP y TLS completados (p50) | 490 ms | 59 ms | 88% más rápido |
| Tiempo hasta el primer byte (p50) | 743 ms | 307 ms | 59% más rápido |
| Tamaño de los scripts de la página de inicio | 1.76 MB | 560 KB | 68% menos |
El tiempo hasta el primer byte es de donde sale el 59%. Una conexión que antes tardaba medio segundo en establecerse ahora está lista en menos de una décima parte, y una primera visita a nuestro sitio web ahora descarga dos tercios menos, en conexiones donde mucha gente paga por cada megabyte.
Estas cifras proceden de una sola ciudad, no son una referencia global. Aun así, la aritmética se traslada a Lagos y Yakarta, que es donde están nuestros usuarios.
Lo difícil fue saber quién llama
Poner algo delante de tus servidores es fácil. Conseguir que tus protecciones sigan funcionando detrás es donde se fue la mayor parte del esfuerzo.
Como la mayoría de las plataformas de pagos, Moove usa limitación de tasa (rate limiting), un tope al número de solicitudes que puede hacer un mismo llamante en un tiempo determinado, y esos límites se asignan según la dirección IP del llamante, el número que identifica a un dispositivo en internet. Detrás de una red perimetral, todas las solicitudes llegan desde la dirección de una ubicación del edge en lugar de la del usuario. Si no se hubiera cambiado nada más, todo Lagos habría compartido un único cupo, y una tarde con mucha actividad habría empezado a rechazar a personas que no habían hecho nada malo.
La solución se apoya en dos ideas.
Confiar exactamente en las capas que tienes. Una CDN es un tipo de proxy inverso, un servidor que se sitúa delante del tuyo y reenvía las solicitudes. Cada proxy añade la dirección desde la que recibió una solicitud a una cabecera estándar llamada X-Forwarded-For, de modo que el llamante real queda un número fijo de pasos, o saltos, hacia atrás en esa lista. Equivocarse en ese número es un error en ambos sentidos. Si cuentas muy pocas capas, todos los usuarios parecen su ubicación del edge. Si cuentas demasiadas, empiezas a confiar en una entrada que escribió el propio llamante. Por eso hicimos que el número sea una propiedad de la infraestructura y no del código. Cambia en el mismo momento que la red, y nuestro servicio se niega a arrancar si el valor no tiene sentido, en lugar de adivinar.
Dejar que el edge avale al llamante y creer solo al edge. Ahora el edge escribe en cada solicitud la dirección del llamante real y sobrescribe cualquier cosa que el llamante hubiera enviado en su lugar. Nuestras protecciones solo creen ese valor cuando pueden verificar que la solicitud realmente pasó por nuestro edge. Todos los límites que antes se asignaban según la dirección de red ahora se asignan según el llamante real en el tráfico del edge. Añadimos estas reglas junto a las antiguas en lugar de modificarlas, de modo que cada cambio del despliegue era una adición pura que cualquiera podía revisar de una sola lectura.
Un error que detectamos antes de publicarlo
Los Moove Profiles pueden vivir en el dominio propio de un comercio. Las solicitudes a esos dominios se pasaban a través de nuestro sitio web con el dominio del comercio adjunto, para que el sitio supiera qué perfil mostrar.
El nuevo edge delante del sitio web elimina ese tipo de información de las solicitudes entrantes, lo cual es exactamente lo correcto, porque un visitante nunca debería poder establecerla. También significaba que, una vez que el sitio web pasara a estar detrás del edge, todos los dominios de comercios habrían mostrado en silencio la página de inicio de Moove en lugar del perfil del comercio.
Lo detectamos en la revisión, movimos primero la ruta de los dominios de comercios a su propia ruta y conseguimos que nuestra infraestructura se negara a aplicar el cambio del sitio web en cualquier lugar donde ese movimiento no se hubiera hecho. Un error que antes vivía solo en la cabeza de quien revisaba es ahora algo que detiene la compilación.
La lección general: cuando añadas una capa que limpia las entradas, busca todo lo que dependía de las entradas que vas a limpiar.
Cómo lo desplegamos
En la infraestructura de pagos no se despliega «para ver qué pasa», así que cambiamos primero el entorno de pruebas (staging) y después producción, y unas cuantas decisiones hicieron que el cambio fuera tranquilo. Redujimos el TTL (tiempo de vida) de nuestros registros DNS, el directorio de internet que convierte un nombre como moove.xyz en la dirección de un servidor. El TTL es el tiempo que el resto de internet puede conservar esa respuesta en caché, y lo bajamos de una hora a cinco minutos, una hora completa antes de mover nada, de modo que la respuesta antigua había caducado en todas partes y una marcha atrás surtiría efecto en cuestión de minutos. Mantuvimos los registros de direcciones en una forma que permitía cambiarlos en el sitio, porque eliminarlos y volver a crearlos habría dejado un hueco, y un hueco es una caída del servicio. Cada paso arriesgado fue un cambio pequeño por sí mismo, con los pasos para deshacerlo escritos en orden.
Qué le diríamos a otro equipo
Si tus usuarios están lejos de tus servidores, merece la pena tener una red perimetral aunque no almacene nada en caché. Antes de hacer el cambio:
- Haz una lista de todo lo que lee la dirección del llamante, incluidos los límites de tasa, las listas de permitidos, las señales de fraude, los registros de auditoría y las reglas de seguridad. Todos ellos ven la dirección del edge a menos que lo cambies.
- Haz que el número de capas de confianza forme parte de tu infraestructura y que el servicio se niegue a arrancar cuando sea incorrecto.
- Deja que el edge registre al llamante real y confía en ese registro solo en el tráfico que puedas verificar que procede de tu edge.
- Asegúrate de que tus servidores aceptan tráfico solo a través del edge, y observa antes de aplicar la restricción.
- Si almacenas páginas en caché, construye la clave de caché, el conjunto de datos de la solicitud que una caché usa para decidir si dos solicitudes pueden compartir una misma respuesta almacenada, con todo aquello de lo que la respuesta realmente depende. Los servidores enumeran esos datos en una cabecera Vary, así que léela en lugar de fiarte de la memoria.
- Mide antes y después, y observa por separado el tiempo de handshake y el tiempo hasta el primer byte, para poder distinguir la preparación de la conexión del tiempo que dedican tus servidores a trabajar.
Mirando al futuro
La mayoría de nuestras páginas están personalizadas, así que la caché del edge del sitio web permanece casi inactiva por ahora. La mejora de la conexión se aplica a todas las páginas, y cada página puede ahora optar por el almacenamiento en caché cuando es seguro compartirla. Almacenar en caché las respuestas de la API requeriría su propio diseño y revisión, y es lo siguiente que queremos estudiar.
El dinero debería moverse a la velocidad de la red, no a la velocidad de la luz cruzando un océano.
Si desarrollas sobre Moove, lee nuestra introducción a las API y SDK de pagos Web3 y el Moove Developer Program.
Escrito por el equipo de ingeniería de moove.xyz.
Acerca De moove.xyz
moove.xyz es una plataforma global de fintech Web3 construida para el movimiento de valor sin permisos y sin esfuerzo. Permitimos que empresas y consumidores en cualquier lugar envíen, reciban, hagan staking e intercambien cualquier criptomoneda en cualquier blockchain, todo en una sola plataforma.
Somos una de las primeras empresas de fintech Web3 a nivel mundial en innovar y construir una infraestructura completa de pagos en cripto y finanzas descentralizadas, que permite una cobertura integrada y completa en acceso a carteras multicadena, identificadores de cartera personalizados, intercambios de tokens entre cadenas, transacciones integradas entre cadenas y una red financiera social descentralizada. Nuestros productos clave incluyen Moove Profile, Moove Send, Moove Receive, Moove Stake, Moove Swap, Moove Rewards, Moove Discover y más.
Nuestra misión es simple: crear y distribuir tecnología financiera sin permisos y sin esfuerzo para los próximos 1.000 millones de usuarios Web3. Creemos fundamentalmente que el futuro del movimiento de dinero y valor será sin costo, sin fronteras, sin permisos, sin esfuerzo y construido para todos, y estamos construyendo la plataforma definitiva de fintech Web3 para hacer ese futuro real.
Tu dinero. Tu movimiento.






