24 puntos por GN⁺ 2025-10-16 | 3 comentarios | Compartir por WhatsApp
  • Unkey, que ofrece un servicio de autenticación para API, migró de una arquitectura serverless basada en Cloudflare Workers a servidores con estado basados en Go para resolver problemas de rendimiento y complejidad arquitectónica
  • La nueva estructura ofrece tiempos de respuesta 6 veces más rápidos y además elimina métodos complejos para rodear las limitaciones del caché y la sobrecarga de los pipelines de datos
  • En un entorno serverless, no hay garantía de memoria persistente entre invocaciones de funciones, por lo que cada lectura de caché requería una solicitud de red, generando una latencia p99 de caché de más de 30 ms
  • Al pasar de un sistema distribuido a una arquitectura de aplicación más simple, se habilitó el self-hosting, se ganó independencia de plataforma y mejoró mucho la experiencia de desarrollo
  • Serverless sigue siendo adecuado para cargas de trabajo esporádicas o patrones simples de solicitud/respuesta, pero cuando se necesita baja latencia consistente o manejo de estado persistente, los servidores con estado resultan más efectivos

Límites de serverless y cuellos de botella de rendimiento

  • En Unkey, la autenticación de API estaba en una parte crítica de la ruta de solicitudes, así que una latencia de apenas unos milisegundos impactaba directamente la experiencia del usuario
  • El despliegue global en el edge de Cloudflare Workers y su escalado automático eran atractivos, pero la falta de persistencia del caché y la latencia de las solicitudes de red terminaron siendo un problema
  • Problemas de caché

    • Las funciones serverless no tienen memoria persistente entre invocaciones, así que cada consulta al caché requería una solicitud de red externa
      • La latencia p99 de consulta de caché en Cloudflare se midió en más de 30 ms
      • Aunque se apilaran múltiples capas de caché (SWR, Redis, etc.), en esencia nada puede ser más rápido que “0 solicitudes de red”
    • Como resultado, no fue posible alcanzar el objetivo de respuestas por debajo de 10 ms
  • Problemas por el acoplamiento con SaaS

    • Serverless reduce la carga de administrar infraestructura, pero en la práctica hace que herramientas SaaS adicionales sean imprescindibles
      • Caché → Redis, procesamiento por lotes → Queue, logs → Durable Objects, etc.
      • Cada servicio agrega latencia, costo y puntos de falla
    • Incluso mezclando Cloudflare Durable Objects, Queues y Workflows, la complejidad real terminó aumentando
  • Problemas en el pipeline de datos

    • Como serverless es un entorno efímero, había que vaciar los datos inmediatamente en cada invocación
      • Para procesar eventos, logs y métricas, tuvieron que construir por su cuenta servicios complejos de buffering e intermediación
    • Ejemplos:
      • Envío por lotes de logs a ClickHouse mediante chproxy
      • Construcción de un servidor de buffering separado para rodear el rate limit al enviar logs a Axiom
    • Como resultado, incluso una función de analítica simple terminó teniendo la complejidad de un sistema distribuido de procesamiento de eventos

Migración a servidores con estado

  • Con la introducción del servidor con estado v2 basado en Go, se hizo posible agrupar en memoria y hacer flush periódico
    • Ya no se necesitan servicios adicionales ni pipelines complejos
    • El mantenimiento, el debugging y las pruebas locales se simplificaron enormemente
  • Resultados de rendimiento

    • La comparación entre /v1/keys.verifyKey y /v2/keys.verifyKey mostró una reducción de latencia de 6 veces
    • Incluso con menos infraestructura que los 300 POP globales de Cloudflare, la percepción de rendimiento del usuario mejoró de forma notable

Beneficios más allá del rendimiento

  • Self-hosting

    • Como dependía del runtime de Cloudflare, los clientes no podían hacer self-hosting de Unkey
      • Aunque el runtime de Workers es técnicamente open source, ejecutarlo localmente (incluso en modo de desarrollo) es extremadamente difícil
    • Al pasar a un servidor Go estándar, el self-hosting se volvió sencillo
      • Puede ejecutarse solo con el comando docker run -p 8080:8080 unkey/api
      • No se necesita un runtime especial ni una configuración compleja
    • Ahora los desarrolladores pueden ejecutar toda la pila de Unkey localmente en cuestión de segundos, lo que hace mucho más fácil el debugging y las pruebas
    • La velocidad de desarrollo y debugging local mejoró drásticamente
  • Mejora en la experiencia de desarrollo

    • Limitaciones que sufrían en serverless:
      • necesidad de considerar restricciones de ejecución de funciones
      • dificultad para mantener estado entre invocaciones
      • debugging complejo de logs distribuidos
      • entorno incómodo para pruebas locales
    • Al migrar a servidores con estado, se eliminó este impuesto a la complejidad (Complexity Tax)
  • Independencia de plataforma

    • Ya no dependen del ecosistema de Cloudflare
      • Pueden desplegar en cualquier lugar
      • Pueden usar cualquier base de datos
      • Pueden integrar servicios de terceros sin preocuparse por compatibilidad de runtime

Estrategia de migración y lecciones aprendidas

  • Aprovecharon la migración como una oportunidad para corregir problemas de diseño de la API acumulados con el tiempo
    • La nueva API v2 corre junto con la v1 existente, y los clientes pueden usar ambas versiones durante el período de deprecación
  • Una ventaja de mantener serverless fue que aunque el uso cayera a cero, el costo de operar la API v1 seguía siendo bajo, lo que permitió un período de migración gratuito
  • Lo que mantuvieron

    • No desecharon por completo todo el enfoque serverless
      • Despliegue global en el edge: usan AWS Global Accelerator para mantener baja latencia a nivel mundial
      • Escalado automático: Fargate se encarga del escalado sin las restricciones de serverless
  • Mejora en el rendimiento del rate limiter

    • En el modelo serverless, hacían falta trade-offs importantes entre velocidad, precisión y costo, y por su naturaleza distribuida era casi imposible lograr las tres cosas a la vez
    • Con servidores con estado y estado en memoria, construyeron un rate limiter más rápido, más preciso y con menor costo operativo

Cuándo serverless sí encaja (y cuándo no)

  • Cuándo serverless sí encaja

    • Cargas de trabajo esporádicas: cuando no corre de forma continua, la economía de escalar a cero es excelente
    • Patrones simples de solicitud/respuesta: cuando no se requiere estado persistente ni pipelines de datos complejos
    • Arquitectura orientada a eventos: sobresale al responder a eventos sin administrar infraestructura
  • Cuándo serverless no encaja

    • Cuando se necesita baja latencia consistente: la dependencia de redes externas degrada el rendimiento
    • Cuando se necesita estado persistente: rodear la falta de estado aumenta la complejidad
    • Cargas de trabajo de alta frecuencia: el modelo de cobro por invocación deja de ser económico
    • Cuando se necesita control fino: la abstracción de la plataforma puede convertirse en una limitación
  • El costo de la complejidad

    • La mayor lección de la migración fue entender el costo de complejidad de tratar de rodear las limitaciones de la plataforma
    • Lo que construyeron en serverless

      • una biblioteca sofisticada de caché para rodear la falta de estado
      • varios servicios auxiliares para procesamiento de datos por lotes
      • un pipeline complejo de logs para recopilar métricas
      • soluciones sofisticadas para desarrollo local
    • En los servidores con estado

      • todo lo anterior desaparece
      • pasaron de un sistema distribuido con muchas piezas móviles a una arquitectura de aplicación más simple
      • a veces, en vez de rodear las restricciones, la mejor solución es elegir una base distinta

Siguientes pasos

  • Actualmente corre en AWS Fargate detrás de Global Accelerator, pero esto es una medida temporal
  • El próximo año planean lanzar su propia plataforma de despliegue, "Unkey Deploy", que permitirá a los clientes (y al propio Unkey) ejecutar Unkey donde quieran
  • La transición a servidores con estado en Go es el primer paso para hacer que Unkey sea realmente portable y apto para self-hosting
  • Los detalles de implementación están publicados como open source en el repositorio de GitHub

3 comentarios

 
ds2ilz 2025-10-18

Yo también en algún momento fui casi un creyente del serverless y lo promovía con mucha fuerza, pero últimamente prefiero más una estructura hecha con una sola instancia de EC2 y una sola de RDS. Y luego voy separando de a poco lo que se necesita. Ahora pienso mucho más antes de adoptar serverless.
Hay varias razones, pero incluso si en el equipo hay una sola persona que no tiene conocimientos de serverless, los costos de comunicación y mantenimiento aumentan bastante. Y al volver a operar servidores, volví a sentir que el serverless no era tan barato ni tan cómodo como pensaba.

 
GN⁺ 2025-10-16
Opiniones de Hacker News
  • Como alguien que usó entornos serverless durante años (principalmente Amazon Lambda, y también otros), coincido totalmente con la opinión del autor.
    Serverless sí te quita trabajo en algunas partes, pero al mismo tiempo te agrega trabajo en otras por tener que resolver “problemas artificiales”.
    Un caso que me tocó fue el límite de tamaño de subida.
    Cuando migramos una aplicación existente a serverless, pensé que bastaría con crear un endpoint de API para importar grandes volúmenes de datos de clientes y conectarle un worker en segundo plano.
    Pero en el "API Gateway" (el proxy que invoca tu código) no se podían subir más de 100 MB, y cuando pregunté si era posible cambiar ese límite, simplemente me dijeron que le indicara a los clientes que dividieran sus archivos en partes más pequeñas para subirlas.
    Técnicamente puede sonar razonable, pero en la realidad ningún cliente va a cambiar su forma de subir archivos.
    Se siente como eso de “funciona bien en el vacío”: en teoría suena genial, pero cuando lo haces en la práctica, el tiempo y dinero que ahorras al pasarte a serverless terminas reinvirtiéndolos en resolver problemas propios de serverless.

    • Para resolver esto, hay que entregar URLs prefirmadas de S3.
      Puedes integrarlo haciendo que el usuario suba directamente a S3 y luego te envíe el resultado de la subida, o distinguiendo los archivos por request id, entre otras opciones.
      Como alguien que lleva mucho tiempo usando AWS, esto sí me parece fastidioso, pero también entiendo el límite de 100 MB porque dejar abierta una API de subida arbitraria de archivos implica mucho riesgo de ataques DoS.
      Aun así, considerando que hoy el internet es mucho más rápido, un umbral de 100 MB ya se siente un poco anticuado.
      De todas formas, sí creo que en algún punto tiene que existir un límite.

    • Nuestra empresa llegó a ser, en algún momento, el cliente que representaba al área de certificados SSL de AWS.
      Queríamos soportar Vanity URLs (dominios personalizados), así que necesitábamos un certificado SSL por cada dominio, y hacían falta miles.
      La herramienta de gestión de certificados de AWS solo funcionaba cómodamente hasta unos pocos cientos, así que esto tardó como 3 meses en resolverse.
      Me sorprendió que algunos servicios de AWS no pudieran responder rápido a necesidades de una cantidad tan pequeña de clientes.

    • Al principio Lambda parecía tener muchísimo potencial y la adoptamos, pero al final abandonamos todos nuestros proyectos en Lambda y los movimos a entornos con contenedores según fue necesario.
      Lambda también te obliga a actualizar el runtime de Node cada 1 o 2 años, y con contenedores tú decides ese ciclo, así que es mucho más flexible.

    • El problema más difícil de la informática es copiar un archivo de una computadora a otra.

    • Dejo una referencia para quienes lean esto en el futuro.
      Si usas el uploader y endpoint de "tus", obtienes funciones como carga por partes, reanudación, etc., así que sirve muy bien para superar este tipo de limitaciones.
      https://tus.io/

  • Como explica el artículo, serverless definitivamente tiene sus usos.
    Pero creo que no es adecuado para la mayoría de las aplicaciones.
    Salvo en casos muy especiales, no planeo usar serverless como infraestructura central.
    En la práctica, más bien me da la impresión de que la gestión de infraestructura se vuelve más engorrosa.
    Cada plataforma tiene requisitos distintos, y también varían mucho las formas de probar y desarrollar, así que todo se vuelve ambiguo y hasta las pruebas locales son difíciles.
    Las capas de abstracción de cada plataforma también tienen trampas, y no existe un estándar real.
    Empaquetar ejecutables como imágenes de Docker me resulta mucho más cómodo, y además permite abstraer la configuración del entorno lo suficiente como para que el desarrollo me resulte natural.
    Siento que la abstracción mínima al nivel de entorno Linux y sistema de archivos es la más eficiente.
    Si hace falta, siempre puedes levantar esa imagen en un servidor y operarla bajo demanda o dejándola siempre activa.

    • Si ves varias de las modas tecnológicas de los últimos 10 años, muchas se popularizaron porque grandes empresas usaron tecnologías para resolver problemas que en realidad solo existían a su escala.
      Ejemplos de esto serían GraphQL, react, Tailwind, NextJS y varias más.
      Ninguna herramienta sirve para todo; lo importante es elegir según tu situación y tus problemas, con experiencia y entendimiento.

    • Ojalá pudiera contarles lo “divertido” que la estoy pasando tratando de ejecutar una app de Amazon Lambda en local.
      Intentar probarla antes del despliegue es un desafío en sí mismo.

    • Knative (Serverless para Kubernetes) recibe contenedores directamente.
      Como usa un formato de empaquetado estándar, es fácil moverlo entre distintas plataformas.

    • En realidad, ese equipo no estaba desarrollando una aplicación, sino una biblioteca que iba a integrarse en una aplicación de servidor con estado.
      La ventaja de rendimiento tampoco venía de serverless como tal, sino de procesar la autenticación cerca del entorno del cliente.

    • ¿No aceptan imágenes de Docker en realidad todas las plataformas “serverless”?
      Según entiendo, Cloud Run sí lo hace.
      En realidad, la preocupación es que una “serverless function” abstrae demasiadas cosas.

  • A ClickHouse no le gustan miles de inserts pequeños, así que nosotros agrupamos eventos con un servicio en Go llamado chproxy y los enviamos en lotes grandes.
    Cada Cloudflare Worker manda eventos analíticos a chproxy, y chproxy los agrupa para enviarlos en masa a ClickHouse.
    Solo para datos de ClickHouse, me pregunto por qué no usaron la función de inserts asíncronos en vez de crear otro servicio aparte.
    https://clickhouse.com/docs/optimize/asynchronous-inserts

  • Siento que los desarrolladores están enterrados bajo herramientas que supuestamente “lo hacen más fácil”.
    En realidad, la mayoría de los problemas se pueden resolver fácilmente con las herramientas más básicas: compiladores, scripts de bash y bibliotecas.
    Esta obsesión con las herramientas a veces termina perjudicando tanto a las empresas como a los propios desarrolladores.

    • En mi opinión, Docker en 2013 fue la última herramienta que realmente produjo un cambio universal y positivo.
      Desde entonces han salido cosas que pueden ayudarle a algunas empresas, pero que al intentar aplicarse a todas terminan rompiendo la productividad o incluso tumbando sistemas.
      Hoy en lugares como Cloudflare están empujando los v8 isolates como si fueran “el próximo Docker”, pero aunque son perfectos para algunas cargas, no sirven para todo.
      El patrón de “tomar una imagen de Docker y ponerla en internet” es tan poderoso que me parece que seguirá siendo la opción más fuerte incluso en 2040.

    • También es un problema que cada vez haya menos gente con bases sólidas.
      El trabajo se hace subcontratando la mayor parte del stack a servicios de terceros, y lo único que uno construye directamente es una parte de la aplicación central.
      Y hasta eso podría terminar escribiéndolo la IA.
      Toda la industria está fomentando una especie de “indefensión aprendida”.

    • Mucha más gente de la que uno pensaría no conoce bien compiladores, scripts de bash ni bibliotecas.

    • AWS Lambda es ridículamente barato.

    • ¡Sirve para hacer marca personal!
      Nunca he visto a alguien llegar a nivel Staff escribiendo scripts de bash.

  • Quisiera preguntarle al "vercel security checkpoint":
    cuando entro desde un iPhone usando la combinación de Proton VPN y Firefox Focus, saliendo por nodos de California o Canadá, me aparece repetidamente el error code 99 "Failed to verify your browser".
    ¿Qué está mal?

    sfo1::1760587368-8k6JCK3uO27oMpuTbnS4Hb3X2K9bVsc
    
  • Este hilo me reafirma algo que ya pensaba.
    El término serverless es tan ambiguo en su definición que el propio nombre me parece un sinsentido.
    Los servidores siguen existiendo.
    Es como decir “sin electricidad” cuando en realidad sí usas electricidad.
    Se siente como un cambio de nombre que no te dice qué está pasando realmente.

  • No creo que toda la lección sea simplemente “serverless es malo”.
    La enseñanza más importante es que, si tu servicio tiene dependencias, mover el servicio cerca del cliente sin mover también esas dependencias puede hacer que la experiencia end-to-end sea sorprendentemente lenta.
    Inevitablemente es mejor construir cerca de las dependencias, y si eso no alcanza, hay que mover o sincronizar todas las dependencias cerca del cliente, pero en la práctica ese proceso suele volverse demasiado complejo.

    • No estoy seguro de que eso sea una regla que aplique siempre.
      Depende de cómo y con qué frecuencia usas las dependencias, y si se trata de una base de datos, a veces conviene que esté cerca del servidor y otras cerca del cliente, según el caso.
      Hay escenarios de uso donde necesitas respuesta rápida y otros donde no importa tanto.
      También puedes fragmentarlo según qué cosas puedas cachear en el servidor o en el cliente.
      No creo que haya que verlo de forma tan binaria.
  • Si quieres la mejor relación precio-rendimiento, la respuesta es configurar tú mismo las instancias y encargarte directamente de lo que necesites.
    No hay que dejar que los proveedores cloud se conviertan en magos del sobrecargo.

  • En este momento, el “máximo local” al que hemos llegado es usar contenedores de Docker como entorno estándar y artefacto de despliegue, inyectando secretos solo cuando hace falta.
    Así las pruebas locales son sencillas, y se conservan la mayoría de las ventajas importantes, como automatización de infraestructura y reproducibilidad.
    Serverless es excesivo para la mayoría de las apps, pero encaja bien en algunas.
    En particular, puede funcionar mejor para utilidades simples sin infraestructura propia, servicios bajo demanda o apps stateless de gran escala.
    No es que serverless solo sirva para casos simples; más bien creo que existe una contradicción fundamental entre el modelo de “web app tradicional” y las plataformas serverless.

    • Creo que ya estoy listo para recibir misterio.
      https://github.com/daitangio/misterio
      Es un wrapper sencillo para un clúster de Docker stareless.
      Empezó en mi homelab y luego empezó a tener eco.

    • Docker se parece un poco a microservices.
      Sirve para algunas aplicaciones, pero se ha exagerado como si fuera un estándar universal.
      Si abusas de Docker, aparecen cargas operativas y parches de seguridad, y usarlo a ciegas en todos los proyectos significa fallar en la gestión del riesgo.
      El problema de dependencias hoy la mayoría de los desarrolladores ya lo resuelve evitando instalaciones globales.
      Docker ya no es tan indispensable como antes, aunque sigue siendo dominante.
      Desde la perspectiva de los proveedores de hosting, estimo que adoptar Docker aumenta el margen al menos en un 10%.
      Siento que Docker también entra en esa “obsesión por las herramientas” que alguien mencionó más abajo.

  • El punto no es que serverless no funcione, sino que los autores no entendían bien la base sobre la que estaban construyendo.
    Poner una API sensible a la latencia sobre un edge runtime stateless es un error de principiante, y el sufrimiento que les causó era totalmente predecible.

    • En mi experiencia, la mayoría de los problemas de los servicios cloud vienen de mal uso o malentendidos de la arquitectura.
      Son problemas humanos que se habrían evitado con un diseño más cuidadoso.
      Pero el problema es que los vendors cloud promocionan sus productos con marketing convincente y esconden las métricas reales de rendimiento.
      No sabes si Lambdas realmente son lo bastante rápidas para tu carga de trabajo, o si la replicación externa de AWS RDS te conviene, hasta que lo pruebas.
      Aprendí por experiencia que el rendimiento real de AWS hay que medirlo uno mismo.

    • El punto no es que los autores no lo entendieran; lo valioso es la información que alguien compartió.

    • No creo que esto pueda verse solo como un “error de principiante”.
      En la práctica, los ingenieros suelen saber que cierto enfoque no es adecuado para producción, pero los gerentes lo empujan fácilmente porque “así se hace ahora”.
      O a veces, por restricciones de tiempo y presupuesto, no queda otra que tomar una decisión “menos buena”.
      O también puede que el equipo original realmente no lo entendiera bien, pero en cualquier caso creo que compartir estas historias ayuda muchísimo al progreso de toda la comunidad.

    • En mi experiencia, si necesitas garantías reales (autoescalado rápido, baja latencia, CPU, disco, velocidad de red, etc.), lo más seguro es administrar instancias EC2 tú mismo.
      Si entregas el control y esperas mejoras de rendimiento, acabas encontrándote con cuellos de botella que no puedes corregir.

    • Al final, los autores simplemente están admitiendo que hoy fueron “una de las 10,000 personas”.
      https://xkcd.com/1053/
      Personalmente les agradezco haber compartido esta información y estos errores.

 
github88 2025-10-18

La ingeniería siempre es una batalla de costos
Al principio se usa para reducir el tiempo de prototipado o de construcción del negocio
Más adelante hay que optimizar y reducir los costos
Un texto como este en sí mismo demuestra qué tan poco ingeniero es uno
Esto