Backpressure en colas de mensajes
Productores mas rapidos que consumidores: la cola sin limite crece hasta el OOM y la acotada obliga a elegir entre frenar, perder o mudar el problema.
📈 Que cambia para el negocio
Evita caidas por memoria y perdidas silenciosas de mensajes, y obliga a decidir explicitamente que se sacrifica cuando el consumidor no da abasto.
💼 Que demuestra tecnicamente
Muestra que el throughput se ve perfecto hasta el segundo antes del OOM, y que las tres formas de acotar una cola pagan cosas distintas: latencia, datos o deuda operativa.
✅ Evidencia que deja
- Contrasta /produce-unbounded y /produce-bounded con las tres politicas sobre la misma carga.
- Hace visible queue_depth_peak, oldest_msg_age_ms_peak y queue_bytes_peak: profundidad, latencia real y memoria.
- Expone messages_dropped_total y dlq_depth para que ninguna perdida quede sin contar.
👀 Que mirar al ejecutarlo
- Si queue_depth_peak sin limite iguala al total producido: la cola absorbio todo.
- Si oldest_msg_age_ms_peak es 3 o 4 veces mayor sin limite que con limite, con el mismo throughput.
- Si cada politica acotada paga algo distinto: producer_blocked_ms en block, dropped en drop_oldest, dlq_depth en dead_letter.
Como esta resuelto en cada stack
Cola acotada con la primitiva de cada runtime: el freno vive en listen.backlog de FPM en PHP, queue.Queue(maxsize=N) con la politica en la firma de put() en Python, stream.Writable con highWaterMark y el evento drain en Node, ArrayBlockingQueue con put/offer/offer(timeout) en Java, Channel.CreateBounded con BoundedChannelFullMode como enum del constructor en .NET, canal bufferizado con select y default en Go, y mpsc::sync_channel en Rust — donde el limite esta en el tipo y TrySendError::Full devuelve el mensaje rechazado adentro
| Stack | Health check local | Compose | Detalle |
|---|---|---|---|
| 🐘 PHP 8.3 | http://localhost:8100/15/health | compose.root.yml | README del stack |
| 🐍 Python 3.12 | http://localhost:8200/15/health | compose.python.yml | README del stack |
| 🟢 Node.js 22 | http://localhost:8300/15/health | compose.nodejs.yml | README del stack |
| ☕ Java 21 | http://localhost:8400/15/health | compose.java.yml | README del stack |
| 🔵 .NET 8 | http://localhost:8500/15/health | compose.dotnet.yml | README del stack |
| 🐹 Go 1.23 | http://localhost:8600/15/health | compose.go.yml | README del stack |
| 🦀 Rust 1.83 | http://localhost:8700/15/health | compose.rust.yml | README del stack |
El expediente completo
El caso no empieza en el codigo: empieza en el sintoma y termina en el postmortem.