Conceptoactiveverificado 2026-04-15#architecture#performance#postgres#django#observability#backend#refactor#audit-abril-2026
Guía de Optimización de Performance - CreaRack Pro
Optimizaciones de Queries (Database)
1. Select Related y Prefetch Related
Problema N+1 Queries:
# ❌ MAL - Genera N+1 queries
devices = Device.objects.filter(rack__organization=org)
for device in devices:
print(device.rack.name) # Query adicional por cada device
Solución con select_related (ForeignKey):
# ✅ BIEN - Una sola query con JOIN
devices = Device.objects.select_related('rack').filter(rack__organization=org)
for device in devices:
print(device.rack.name) # No hay query adicional
Solución con prefetch_related (ManyToMany):
# ✅ BIEN - 2 queries en lugar de N+1
racks = Rack.objects.prefetch_related('device_set').filter(organization=org)
for rack in racks:
for device in rack.device_set.all(): # No hay queries adicionales
print(device.name)
2. Optimizaciones Implementadas
Blueprints API (blueprints/api.py)
- ✅
get_blueprint_racks():select_related('rack').prefetch_related('rack__devices')(Critical for Canvas load)
Dashboard View (racks/views.py)
- ✅
index():prefetch_related('groups', 'devices')(Critical for Dashboard load)
Network API (network/api.py)
- ✅
list_backups():select_related('created_by') - ✅
view_backup():select_related('device__rack') - ✅
get_device_credentials():select_related('rack')
Racks API (racks/api.py)
- ✅
clone_rack():select_related('group').prefetch_related('device_set') - ✅
create_stencil_from_device():select_related('rack__organization')
3. WebSocket Optimization (Valkey/Redis)
Problema de Desbordamiento:
En entornos SaaS con alta concurrencia, el Channel Layer por defecto tiene una capacidad baja (100 mensajes), lo que puede causar desconexiones durante auditorías masivas.
Solución Implementada (settings/base.py):
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("cache", 6379)],
"capacity": 5000, # Aumentado de 100 a 5000
"expiry": 10, # Expiración rápida de mensajes viejos
},
},
}
4. Only() y Defer()
Limitar campos cargados:
# ✅ Solo cargar campos necesarios
racks = Rack.objects.only('id', 'name').filter(organization=org)
# ✅ Excluir campos grandes (como config_text)
backups = ConfigBackup.objects.defer('config_text').filter(device=device)
4. Database Indexes
Modelos con índices críticos:
class Device(models.Model):
ip_address = models.CharField(max_length=50, db_index=True)
rack = models.ForeignKey(Rack, on_delete=models.CASCADE, db_index=True)
class Meta:
indexes = [
models.Index(fields=['rack', 'u_position']),
models.Index(fields=['ip_address', 'vendor']),
]
5. Bulk Operations
Bulk Create:
# ✅ BIEN - Una sola query para insertar múltiples objetos
devices = [
Device(name=f"Device {i}", rack=rack, u_position=i)
for i in range(10)
]
Device.objects.bulk_create(devices)
# ❌ MAL - 10 queries separadas
for i in range(10):
Device.objects.create(name=f"Device {i}", rack=rack, u_position=i)
Bulk Update:
# ✅ BIEN - Una sola query
Device.objects.filter(rack=rack).update(vendor='cisco_ios')
# ❌ MAL - N queries
for device in Device.objects.filter(rack=rack):
device.vendor = 'cisco_ios'
device.save()
Optimizaciones de Cache (Redis/Valkey)
1. Cache de Queries Frecuentes
from django.core.cache import cache
def get_rack_with_devices(rack_id):
cache_key = f'rack_devices_{rack_id}'
result = cache.get(cache_key)
if result is None:
rack = Rack.objects.select_related('group').prefetch_related('device_set').get(id=rack_id)
result = {
'rack': rack,
'devices': list(rack.device_set.all())
}
cache.set(cache_key, result, timeout=300) # 5 minutos
return result
2. Invalidación de Cache
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Device)
def invalidate_rack_cache(sender, instance, **kwargs):
cache_key = f'rack_devices_{instance.rack_id}'
cache.delete(cache_key)
Optimizaciones de Templates
1. Template Caching (Producción)
# config/settings/production.py
TEMPLATES[0]["OPTIONS"]["loaders"] = [
(
"django.template.loaders.cached.Loader",
[
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
],
),
]
2. Static Files
# Collectstatic con whitenoise
python manage.py collectstatic --noinput
# Minificar JS/CSS en producción
npm run build
Monitoreo de Performance
1. Django Debug Toolbar (Dev)
# config/settings/dev.py
INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
2. Query Logging
# config/settings/dev.py
LOGGING = {
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
3. Silk (Profiling)
pip install django-silk
# Acceder a http://localhost:8000/silk/
Database Connection Pooling
Configuración en Producción
# config/settings/production.py
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"CONN_MAX_AGE": 600, # Mantener conexiones abiertas 10 minutos
"OPTIONS": {
"connect_timeout": 10,
}
}
}
Checklist de Optimización
Antes de hacer Deploy a Producción
- Todas las queries usan
select_relatedoprefetch_relateddonde corresponde - Índices de base de datos en campos frecuentemente consultados
- Cache configurado para queries pesadas
- Static files compilados y comprimidos
-
DEBUG = Falseen producción - Template caching habilitado
- Connection pooling configurado
- Logs de queries desactivados en producción
- Whitenoise o CDN para archivos estáticos
Comandos Útiles
# Analizar queries lentas
python manage.py showmigrations
python manage.py dbshell
EXPLAIN ANALYZE SELECT * FROM racks_device WHERE rack_id = 1;
# Profiling con django-extensions
python manage.py runprofileserver
# Cargar datos de prueba
python manage.py loaddata fixtures/demo_data.json
Última actualización: 20-01-2026 Versión: v5.0.0-alpha
Véase también
- [[crearack-tech—backend—autoplan-performance]] — performance de Auto-Plan
- [[crearack-tech—backend—database-architecture]] — arquitectura de base de datos
- [[crearack-tech—frontend—performance-guidelines]] — guidelines de performance frontend
- [[crearack-tech—reports—audit-abril-17-2026]] — auditoría del 17-abril-2026
- [[feature—refactor—audit-abril-2026]] — feature — refactor post-auditoría Abril 2026
- [[crearack-tech—guides—capacity-planning]] — planificación de capacidad de infra