From n00b to ZeroCool / Profesionalización
Backend: el sótano donde vive la lógica (y por qué te conviene bajar)
Entiende el backend con casos reales: APIs, DB, auth, caché, jobs y colas. Guía práctica para elegir stack y sobrevivir producción.
Lo que vale la pena leer aquí
Son las 11:48 pm. Te aventaste el deploy “rápido” porque mañana hay demo y tu jefe ya dejó el “¿sí quedó?” en Slack. El front carga… pero la pantalla se queda pensando como si estuviera pegada a un módem de 2007.
Son las 11:48 pm. Te aventaste el deploy “rápido” porque mañana hay demo y tu jefe ya dejó el “¿sí quedó?” en Slack. El front carga… pero la pantalla se queda pensando como si estuviera pegada a un módem de 2007.
Cae el mensaje clásico: “¿Se cayó la API o es mi Wi‑Fi?”.
Ahí es cuando te acuerdas: el backend es el sótano de la app. Nadie lo enseña en el demo. Nadie lo presume en el pitch. Pero cuando algo truena, todo mundo baja a gritos.
Lo que te vas a llevar
- Qué es backend en la vida real (no de diccionario) y qué piezas lo componen.
- Cómo viaja una request: del click a tu server, a la DB, y de regreso en JSON.
- Decisiones con colmillo: monolito vs microservicios, SQL vs NoSQL, caché sí/no, colas sí/no.
- Un mapa mental para entender sistemas que ya están en producción y no perdonan.
- Errores típicos del “primer backend” y cómo evitarlos sin volverte paranoico.
El sótano sí existe (aunque no lo veas)
Piensa en una app normal: una tienda, un SaaS chiquito, un sistema interno de ventas, un negocio que literal solo necesita “que funcione”. El usuario toca un botón y espera magia.
Esa magia casi siempre es un combo de:
- API (REST/GraphQL/gRPC): recibe requests y responde.
- Lógica de negocio: reglas, validaciones, permisos, cálculos, estados.
- Base de datos: el registro oficial de “la verdad”.
- Caché: para no pegarle a la DB por cada cosa.
- Jobs/Workers: tareas que no deben vivir dentro de la request (emails, PDFs, pagos, thumbnails).
- Colas: orden y reintentos para los jobs (RabbitMQ, SQS, Redis Streams, etc.).
- Auth: login, sesiones, tokens, roles.
- Observabilidad: logs, métricas, tracing; lo que te salva cuando “no reproduce”.
En México esto tiene un sazón extra: a veces corre en un VPS modesto porque el presupuesto se fue en marketing, o porque el cliente ya dijo “no le metas tanto, nomás que jale”. Y si tu app se usa con internet irregular (bodega, ruta, campo), tus timeouts y retries dejan de ser teoría.
Cómo armar (y entender) un backend sin romperte
1) Primero entiende el flujo: request → lógica → datos → respuesta
Antes de clavarte con el stack, dibuja el flujo con una historia real.
Ejemplo: “Crear pedido” en una tienda.
- Front manda
POST /orderscon carrito y dirección. - Backend valida:
- ¿Usuario autenticado?
- ¿Hay inventario?
- ¿Dirección válida?
- ¿Reglas de negocio? (mínimo, zona, horarios)
- Backend escribe en DB (transacción si aplica):
orders,order_items, decrementa stock.
- Backend dispara procesos fuera de la request:
- Enviar confirmación por email/WhatsApp.
- Reservar guía de envío.
- Backend responde rápido:
201 Createdconorder_id.
Si tu request tarda 8 segundos porque te llevaste “generar PDF” adentro, el usuario le va a picar dos veces, te va a duplicar pedidos y soporte te va a odiar. Y tú vas a terminar haciendo un rollback a medianoche con una laptop vieja que ya suena como jet.
2) Define el contrato: APIs que no den pena
Un backend se vuelve serio cuando sus endpoints tienen contrato claro, errores consistentes y un plan decente para cambios.
Una forma simple y práctica:
- Respuestas con estructura consistente.
- Códigos HTTP bien usados.
- Errores con
codeymessage(y si se puede,details).
Ejemplo (Node/Express, pero aplica a cualquier stack):
// Respuesta OK
res.status(201).json({
data: { orderId, status: "created" },
meta: { requestId }
});
// Respuesta de error
res.status(409).json({
error: {
code: "OUT_OF_STOCK",
message: "No hay inventario para el producto 123",
details: { productId: 123 }
},
meta: { requestId }
});
Decisión que te ahorra bugs: si hoy no quieres versionar con /v1, mínimo deja un plan (header, compatibilidad, deprecación). Porque alguien —otra squad o tú en tres meses— va a consumir “como venga” y luego te va a meter un bug con un pull request de último minuto.
3) La base de datos: la verdad duele (y se paga)
La DB es donde se pelean consistencia, performance y costo.
Regla que se cumple en un chorro de proyectos:
- Si tus datos son relacionales y quieres integridad: PostgreSQL.
- Si vas empezando y no quieres sorpresas raras: PostgreSQL.
- Si ya tienes una razón real (eventos masivos, documentos, escalado específico): entonces sí, evalúas NoSQL.
Modela pensando en consultas reales, no en “qué se ve bonito”:
- ¿Qué lista se pinta siempre? (índices)
- ¿Qué filtros? (índices compuestos)
- ¿Qué reportes? (evita el
SELECT *contra tablas gigantes a la hora pico)
Ejemplo de índice útil para “pedidos por usuario ordenados por fecha”:
CREATE INDEX IF NOT EXISTS idx_orders_user_created
ON orders (user_id, created_at DESC);
Dato de guerra: el bug caro no es el 500 que explota. Es el endpoint que “funciona” pero cada semana tarda un poquito más… hasta que llega un viernes de quincena y se convierte en sopa.
4) Auth: elige tu veneno (sessions vs JWT)
Autenticación es donde se te va el sprint si no decides desde el inicio.
- Sesiones (cookie + server store): más fácil revocar, más control, ideal para web tradicional.
- JWT: útil para APIs distribuidas y mobile, pero ojo con revocación y expiraciones.
Decisión práctica:
- Si tu producto es B2B con dashboard web: sesiones suelen ser más tranquilas.
- Si tienes mobile + múltiples servicios: JWT puede tener sentido, pero exige disciplina (rotación, expiración, refresh tokens).
Mini-checklist de seguridad que sí se siente en producción:
- Passwords con bcrypt/argon2.
- Rate limit en login.
- Lockout o captcha después de intentos.
- Logs de auth sin soltar datos sensibles.
5) Caché: ponlo cuando te duela, no por deporte
El caché es como la salsa: mejora todo… hasta que tapa el sabor real y ya nadie entiende qué está pasando.
Úsalo cuando:
- Hay lecturas repetidas (catálogos, configuraciones, perfiles).
- Tu DB ya está caliente y la latencia/costo sube.
Evítalo cuando:
- Tus datos cambian cada segundo y no tienes estrategia de invalidación.
Ejemplo: cachear un catálogo por 60 segundos.
const key = `catalog:v1`;
let data = await redis.get(key);
if (!data) {
data = await db.query("SELECT id, name, price FROM products WHERE active = true");
await redis.set(key, JSON.stringify(data), { EX: 60 });
} else {
data = JSON.parse(data);
}
res.json({ data });
Tradeoff real: TTL alto y el negocio te reclama precios viejos. TTL bajo y no ganas casi nada. Lo correcto es alinear con cómo cambia el catálogo (¿un admin? ¿un ERP? ¿un Excel que te mandan por WhatsApp?).
6) Jobs y colas: saca lo pesado de la request
Si tu backend hace cosas lentas dentro de una request, te compras:
- timeouts
- usuarios duplicando acciones
- picos que tumban todo
Cosas típicas para worker:
- Enviar email
- Generar PDF
- Procesar imagen
- Webhooks
- Reintentos de pago
Patrón base:
- API recibe acción y guarda en DB.
- Publica mensaje en cola.
- Worker procesa, reintenta si falla, registra estado.
Las colas agregan complejidad, sí. Pero cuando llega el pico (campaña, mención en TikTok, o “hoy todo mundo pagó a la misma hora”), esa complejidad es justo lo que evita que production se te vaya al piso.
7) Observabilidad: si no lo puedes ver, no lo puedes arreglar
Mínimo viable:
- requestId en cada request
- logs estructurados (JSON si se puede)
- métricas básicas: latencia p95, rate de errores, throughput
Ejemplo de log con contexto (lo que sí sirve a las 2am):
{
"level": "error",
"message": "db_timeout",
"requestId": "a1b2c3",
"userId": 42,
"route": "POST /orders",
"durationMs": 5120
}
Decisión práctica: si el equipo está chico, un stack “barato” y efectivo puede ser logs a CloudWatch/ELK, métricas a Prometheus/Grafana y tracing después. Pero el requestId desde el día 1. Neta.

Screenshots sugeridos
- Diagrama simple del flujo request → API → DB → cola → worker.
- Captura de Postman/Insomnia con un
POST /ordersy respuesta de error consistente. - Screenshot de una tabla en DB con índices (pgAdmin / DBeaver) mostrando
idx_orders_user_created. - Pantalla de logs filtrados por
requestId(CloudWatch, Kibana o terminal conjq). - Gráfica de latencia p95 y rate de errores en Grafana.
Errores comunes (y cómo salir del hoyo)
Error 1: “Todo en un endpoint, todo sincronizado”
Síntoma: POST /checkout tarda 12s, a veces truena, a veces duplica.
Arreglo:
- Responde rápido.
- Mueve email/PDF/webhooks a jobs.
- Usa idempotency keys en operaciones críticas.
Ejemplo de header para idempotencia:
- Cliente manda
Idempotency-Key: <uuid> - Backend guarda la key y evita duplicados si se repite.
Error 2: “La DB aguanta, total es Postgres”
Síntoma: reportes pesados tumban al sistema.
Arreglo:
- Índices donde toca.
- Queries con
EXPLAIN. - Mueve analytics/reportes a réplicas o a un almacén dedicado (cuando ya sea necesario, no por FOMO).
Error 3: “JWT para todo” sin estrategia de revocación
Síntoma: alguien se sale de la empresa y su token sigue válido.
Arreglo:
- Expiración corta + refresh tokens.
- Lista de revocación o rotación de secrets.
- Para B2B, considera sesiones.
Error 4: “Cacheé y ahora nadie sabe por qué sale viejo”
Síntoma: cambias el precio en admin pero la app sigue mostrando el anterior.
Arreglo:
- TTL razonable.
- Invalidación por evento (actualizas producto → borras
catalog:v1). - No caches cosas que son fuente de pleito con negocio.
Error 5: “En mi máquina sí jala”
Síntoma: en local todo bien; en production truena por variables, red, permisos.
Arreglo:
.env.exampley config centralizada.- Health checks.
- Logs con contexto.
- Smoke tests chiquitos post-deploy.

Checklist final (para bajar al sótano sin romperte el cuello)
- Tengo un flujo claro request → lógica → DB → respuesta.
- Mis endpoints tienen errores consistentes (
code,message,requestId). - DB con índices alineados a consultas reales (y al menos revisé con
EXPLAIN). - Auth decidido (sesiones o JWT) con plan de expiración/revocación.
- Lo pesado va a jobs + cola (o al menos está listo para sacarse).
- Caché con TTL e invalidación pensada (no “cachea y reza”).
- Logs con
requestIdy métricas básicas (latencia p95, errores). - Tengo un plan de rollback (porque producción no perdona).
FAQ
1) ¿Backend es lo mismo que servidor?
No exactamente. El servidor es la máquina/infra. Backend es el sistema que corre ahí: APIs, lógica, DB, workers, colas, auth, etc.
2) ¿Qué lenguaje es “mejor” para backend?
El que tu equipo pueda mantener y operar sin sufrir. Node, Java, Go, Python, .NET, Ruby… lo que pesa es el setup, las prácticas, la observabilidad y la disciplina en producción.
3) ¿Monolito o microservicios para empezar?
Monolito bien hecho, casi siempre. Microservicios cuando tengas razones reales: equipos múltiples, dominios separados, escalado distinto o dolor comprobado (no por moda).
4) ¿Cuándo meto Redis?
Cuando tengas lecturas repetidas o necesites rate limiting/sesiones/una cola simple. Si lo metes “porque todos lo usan”, luego pagas con invalidación y bugs fantasma.
5) ¿Cómo sé qué está lento: mi API o mi DB?
Mide por partes: latencia por endpoint, tiempo de query, p95, y agrega requestId. Si no tienes esas señales, estás adivinando con fe.
Siguiente episodio: teaser
La puerta del sótano se abre con una llave: HTTP y APIs. Diseñar endpoints que aguanten producción es menos “arte” y más workflow: códigos de estado, timeouts y el arte de decir “no” con un 429.
Idea para cerrar bien este post: toma una sola práctica de aquí y conviértela en algo que tu equipo pueda aplicar hoy.
Cuando un artículo aterriza en decisiones reales, deja de ser contenido y se vuelve ventaja.


