Rendimiento
El rendimiento es una característica. Diseña para el P99, no para el promedio. Mide antes de optimizar: la intuición casi siempre se equivoca sobre dónde se va el tiempo.
Reglas
- Perfila antes de optimizar. Adivinar el punto crítico desperdicia días. Utiliza primero gráficos de llama, trazas de APM o
EXPLAIN ANALYZE. - Elimina consultas N+1. La mayor fuente de latencia en código de servicio. Prefiere combinaciones (
JOIN), recuperaciones por lotes oIN (...)en lugar de búsquedas por fila. - Pagina cada endpoint de listas. Los conjuntos de resultados sin límite pueden eventualmente agotar la memoria de un pod o saturar la base de datos. Configura la paginación basada en cursores para tablas grandes.
- Indexa sobre los predicados de las consultas, no en cada columna. Cada índice adicional ralentiza las escrituras y aumenta el almacenamiento. Añade un índice solo cuando una consulta conocida lo necesite.
- Proyecta solo las columnas que necesitas.
SELECT *en un DTO amplio desperdicia red, memoria y recolección de basura. Devuelve proyecciones estrechas para las APIs de listas. - Almacena en caché datos de solo lectura e idempotentes. Pero decide la estrategia de invalidación antes de agregar la caché: una caché sin un plan de expulsión es una fábrica de errores.
- Configura explícitamente los tamaños de los pools de conexiones y subprocesos. Los valores predeterminados rara vez son los adecuados para tu carga de trabajo. Ajústalos en función de la capacidad del sistema descendente, no hacia arriba.
- Agrupa las llamadas salientes. Una solicitud con 100 elementos supera a 100 solicitudes con un elemento en todos los aspectos: latencia, CPU, conexiones a la base de datos.
- Evita cadenas síncronas de llamadas remotas. La latencia se acumula. Distribuye en paralelo o mueve el trabajo de forma asíncrona.
- Mantén los payloads pequeños. Comprime las respuestas, elimina los campos no utilizados, utiliza protocolos binarios donde sea importante (gRPC, Protobuf).
Señales de alerta
- Bucles que consultan la base de datos.
- APIs que devuelven "todos los registros".
- Cachés sin TTL ni invalidación.
- Pool de subprocesos / pool de conexiones con el valor predeterminado del framework en producción.
- Paneles de latencia que muestran solo promedios (sin P95/P99).