Cuando testear me salvó de ir a producción con una API lenta - Episodio 37

Llevaba semanas afinando el backend en Flask, creando endpoints, protegiendo rutas con JWT, y devolviendo datos simulados con cariño.
Todo funcionaba bien...
Pero algo me rondaba la cabeza:
¿Qué pasa si 10 personas entran al mismo tiempo?
¿Y si 30 consultan piezas a la vez?
¿Y si explota justo el día que lanzo?
Sí, quizás soy un "cagao" y me asusto por escenarios que nunca van a ocurrir.
Pero al margen que esto pueda suceder o no, estoy aquí para aprender.
Para aprender, haciendo y con la Inteligencia Artificial como copiloto y socia estratégica.
🔧 ¿Y si mi API no aguantaba ni a 10 usuarios conectados? 🗓 Diario de un SaaS
No quería averiguarlo en producción.
Así que decidí hacer mi primer test de carga.
Y menos mal que lo hice.
🧪 La herramienta elegida: Locust
Después de buscar alternativas, me decidí por Locust:
- Es simple.
- Puedes escribir los test en Python.
- Tiene una interfaz web para ver cómo responde tu API en tiempo real.
Instalación rápida:
pip install locust
📝 El archivo locustfile.py
Creé un archivo básico para testear los endpoints públicos /parts y /parts?search=piezaXYZ:
from locust import HttpUser, task, between
class APIUser(HttpUser):
host = "http://127.0.0.1:5000"
wait_time = between(1, 5)
@task
def get_parts(self):
self.client.get("/parts?page=1&per_page=20")
@task
def search_parts(self):
self.client.get("/parts?search=piezaXYZ&page=1&per_page=10")
Y lo lancé con:
locust -f locustfile.py
Accedí al panel en http://localhost:8089 y definí 20 usuarios simultáneos, con un ratio de spawn de 5/s.
📉 Primeros resultados y susto incluido
Al principio todo iba bien.
Pero cuando los usuarios aumentaban, empecé a ver:
- Tiempos de respuesta por encima de 1 segundo.
- Respuestas fallidas 500 cuando llegaban demasiadas peticiones a la vez.
Y eso que solo estaba devolviendo datos simulados desde memoria.
¿Qué hubiera pasado con una base de datos real?
Spoiler: se habría roto.
🔍 Lo que aprendí al mirar los logs
- La función
/partsno tenía paginación ni limitación real. - Cada petición devolvía demasiados elementos de golpe.
- No había cacheo ni control de carga.
- El servidor Flask, ejecutándose con
debug=True, no está preparado para producción ni concurrencia real.
🛠️ Pequeños ajustes, gran diferencia
- Añadí parámetros
pageyper_pagereales con un máximo de 50:
per_page = min(int(request.args.get("per_page", 20)), 50)
- Limité el número de resultados en memoria.
- Pensé en futuras capas de caché (como Redis).
- Me mentalicé de que Flask debe usarse con un servidor como Gunicorn + NGINX en producción.
💡 Lecciones aprendidas
🔹 Testear es invertir en tranquilidad
No me imagino haber lanzado sin saber cómo respondía mi API. Habría sido un desastre.
🔹 Una API rápida no siempre escala bien
Lo que va bien con un usuario puede colapsar con diez si no lo preparas.
🔹 Locust es como un espejo incómodo, pero necesario
Te muestra lo que no quieres ver. Y eso es lo que necesitas.
🎯 Próximo paso
- Empezar a implementar cacheado y control de concurrencia real.
- Preparar el backend para producción con Gunicorn y NGINX.
- Documentar todo para que no se me escape la próxima vez.
🧠 Cierre
Hoy no lancé nada al mundo.
Pero entendí algo que vale oro:
Mejor testear y ajustar hoy que pedir disculpas mañana.
¿Has probado alguna vez tu API con tests de carga?
¿Te sorprendieron los resultados?
Cuéntamelo en los comentarios. 🚀
Si quieres conocer otros artículos parecidos a Cuando testear me salvó de ir a producción con una API lenta - Episodio 37 puedes visitar la categoría Proyecto-IA.

Deja una respuesta