Escalar de 100 a 10.000 usuarios: qué se rompe primero
Qué falla primero en una app web pequeña cuando crecen los usuarios, desde consultas y conexiones hasta límites de correo y tareas pesadas, y cómo resolverlo.
Read in English →
Pasar de 100 a 10.000 usuarios casi nunca rompe el hosting en sí: un frontend estático en un hosting moderno escala prácticamente solo. Lo que se rompe primero suele ser la base de datos (consultas sin índices y luego demasiadas conexiones), después los límites de servicios externos como el correo y las APIs de IA, el trabajo lento que se hace dentro de una petición web y la falta de monitoreo para ver cualquiera de esas cosas. Si los resuelves en ese orden, la mayoría de las apps pequeñas llegan a cinco cifras de usuarios sin reescribir nada ni cambiar de arquitectura.
En esta guía repasamos qué suele fallar en cada etapa, cómo se manifiesta, el arreglo concreto y en qué no vale la pena gastar tiempo todavía.
¿Qué se rompe normalmente, y en qué orden?
| Síntoma | Causa probable | Primer arreglo |
|---|---|---|
| Listados y paneles más lentos cada semana | Consultas que recorren tablas enteras | Índices en columnas que se filtran, unen y ordenan |
| "Too many connections" o timeouts en horas pico | Cada función serverless abre su propia conexión | Usar un pooler de conexiones en modo transacción |
| Dejan de llegar los correos de registro o contraseña | Límite de envío del remitente | Pasar a un proveedor de correo dedicado con dominio verificado |
| Timeouts al exportar, importar o generar algo | Trabajo pesado dentro de la petición | Moverlo a una tarea en segundo plano |
| Errores 429 en funciones con IA, o factura disparada | Límites del proveedor y ningún límite por usuario | Cola, caché y topes de uso |
| Usuarios reportan errores que no puedes reproducir | Sin seguimiento de errores ni logs | Agregar monitoreo antes que nada |
¿Por qué la base de datos va primero?
Con 100 usuarios, una consulta que lee todas las filas de una tabla pasa desapercibida. Con 10.000, las mismas tablas son 100 veces más grandes y la consulta se ejecuta 100 veces más seguido: el costo crece por los dos lados a la vez. Nuestra guía de consultas lentas e índices explica cómo encontrarlas y qué índices crear. En Supabase revisa también el Performance Advisor, que señala claves foráneas sin índice y políticas de Row Level Security que se evalúan fila por fila.
El segundo problema son las conexiones. Postgres acepta un número limitado de conexiones simultáneas. Un servidor que corre siempre reutiliza unas pocas, pero las funciones serverless y edge pueden abrir una nueva cada vez, y un pico de tráfico agota el límite.
La solución es un pooler de conexiones. En Supabase, el código serverless debería usar el modo transacción del pooler, en el puerto 6543, en vez de la conexión directa en el 5432. El modo transacción no admite sentencias preparadas, así que la mayoría de los drivers necesitan un ajuste: prepare: false en Postgres.js y Drizzle, o pgbouncer=true en la cadena de conexión de Prisma. Las peticiones que pasan por las librerías cliente de Supabase van por su API y no necesitan esto.
¿Por qué dejan de llegar los correos?
Muchas apps arrancan con el remitente que venía con su backend. El servicio de correo integrado de Supabase, por ejemplo, está pensado para pruebas y tiene límites de envío muy bajos; para producción se espera que configures tu propio proveedor SMTP. Señales de que llegaste al límite: los correos de confirmación les llegan a algunos usuarios y a otros no, o se cortan del todo durante un lanzamiento.
Pasa a un proveedor de correo transaccional, verifica tu dominio con registros SPF, DKIM y DMARC, y separa los boletines de marketing en otro flujo de envío para que una campaña no bloquee los cambios de contraseña. Si los correos llegan pero caen en spam, mira la guía sobre correos de tu app que llegan a spam.
¿Qué cuenta como "trabajo lento dentro de una petición"?
Todo lo que tarda más de uno o dos segundos y no necesita terminar antes de que el usuario vea una respuesta:
- Enviar correos o notificaciones a muchos usuarios.
- Generar PDFs, informes o exportaciones.
- Importar un CSV con miles de filas.
- Llamar a un modelo de IA con un documento largo.
- Procesar imágenes o videos subidos.
Dentro de una petición web, estas tareas chocan con los tiempos máximos (las plataformas serverless limitan cuánto puede correr una función) y ocupan recursos mientras el usuario espera. El patrón que escala es: aceptar la petición, guardar un registro de la tarea, responder enseguida, procesar en segundo plano y avisar al usuario o actualizar la pantalla cuando termina. Casi todos los backends ofrecen alguna cola, función programada o worker para esto.
¿Y las funciones con IA?
Las APIs de IA tienen límites por minuto de peticiones y de tokens, y cobran por llamada. Con más usuarios, una función que andaba bien en pruebas empieza a devolver errores 429 en las horas pico y la factura crece más rápido que los ingresos. Limita el uso por usuario, guarda en caché las respuestas repetidas y usa modelos más baratos para los pasos simples. Ambos temas tienen su propia guía: controlar el costo de la IA en tu app y limitar el uso de funciones con IA.
¿Por qué el monitoreo importa más que todo lo anterior?
Todo arreglo empieza por saber que algo anda mal. Con 100 usuarios, los clientes te escriben; con 10.000, la mayoría se va sin avisar. Antes de crecer, ten:
- Seguimiento de errores en el frontend y el backend, para que las excepciones lleguen con la traza y la página donde ocurrieron.
- Chequeos de disponibilidad que pidan una página real y busquen un contenido esperado, no solo un estado 200.
- Métricas de la base de datos: CPU, memoria, conexiones y consultas lentas.
- Alertas que le lleguen a una persona, con umbrales que hayas probado.
Nuestra guía de monitoreo y errores en producción explica una configuración mínima.
¿De qué no debería preocuparme todavía?
A este tamaño, esto suele costar más de lo que devuelve:
- Partir la app en microservicios.
- Montar tu propio clúster de Kubernetes.
- Reescribir en un lenguaje o framework "más rápido".
- Bases de datos en varias regiones.
Una sola base Postgres bien indexada con un tamaño de cómputo razonable, una CDN para el frontend, un pooler, un ejecutor de tareas en segundo plano y buen monitoreo cubren una enorme cantidad de apps. Sube el cómputo de la base cuando sus métricas muestren que sigue ocupada con los índices ya puestos.
¿Cómo lo pruebo antes de que lleguen los usuarios?
- Llena una copia de la base con volúmenes realistas: si esperas 10.000 usuarios, crea 10.000 usuarios con la cantidad de datos típica de cada uno. Hazlo en un entorno de pruebas, nunca en producción.
- Recorre las pantallas principales y mira los tiempos en la lista de consultas lentas.
- Haz una prueba de carga sencilla con una herramienta como k6 contra la API de pruebas, empezando bajo y subiendo de a poco, mientras miras los errores y las conexiones a la base.
- Anota lo primero que se rompió. Ese es tu próximo arreglo.
Respuestas rápidas
¿Mi hosting escala solo? El frontend y las funciones serverless normalmente sí. La base de datos, el remitente de correos y las APIs externas no escalan con ellos, y por eso fallan primero.
¿Necesito un plan de base de datos más grande con 10.000 usuarios? Puede ser, pero primero agrega índices y un pooler. Muchas veces hacen innecesaria la mejora.
¿Supabase o Firebase aguantan 10.000 usuarios? Sí, los dos, siempre que el modelo de datos, los índices y las reglas de seguridad estén bien configurados.
¿Qué arreglo primero si estoy por lanzar? El monitoreo, luego los índices de las tablas más usadas y después un proveedor de correo de verdad.
¿Te preparas para crecer?
Si se viene un lanzamiento o un salto de usuarios, nuestros planes de mantenimiento de software cubren este tipo de preparación y el monitoreo que la acompaña, y el desarrollo de software a medida se encarga de cambios más grandes como las tareas en segundo plano. Empieza con la revisión gratuita de tu app o cuéntanos qué planeas. Supabase documenta las opciones de su pooler en conectarse a Postgres.


