mtwRequest
Un solo runtime Rust para WebSocket, HTTP y agentes IA.
Dejá de pegar tres servicios. Conexión, auth y estado compartidos — en un solo core.
Tres servicios en uno
La mayoría de los stacks pegan un broker pub/sub, un framework REST y un runtime de agentes — tres deploys, tres superficies de auth, tres modos de falla. mtwRequest colapsa los tres en un único core Rust.
- →NATS / Centrifugo para pub/sub
- →Express / Fastify para HTTP
- →Framework de agentes aparte para IA
- →Tres deploys, tres superficies de auth
- →Pegamento manual para sincronizar estado
- ✓WebSocket + HTTP comparten conexión
- ✓Agentes IA como módulos de primer nivel
- ✓Una auth, un estado, un tracing
- ✓Marketplace de módulos para componer
- ✓Apache-2.0 — forkealo, mandalo a prod
Benchmarks head-to-head
Same-host, Docker 2 CPU / 2 GB por competidor, payload 128 B, HdrHistogram 3 cifras significativas.
Runner reproducible en bench-suite/.
| Escenario | mtwRequest | vs líderes |
|---|---|---|
| 🥈 Fanout 100 subs · p50 | 17.53 ms | empate con NATS (16.97 ms) |
| 🥇 Fanout 1000 subs · p50 | 197.53 ms | 1.5× más rápido que NATS (299.63 ms) |
| 🥇 Fanout 1000 subs · p99 | 367.79 ms | mejor que NATS (554.70 ms) |
| 🥈 Echo RTT · p50 | 62.2 µs | empate con NATS (Δ 3.8 µs) |
| 🥇 Connect storm · rate | 50.9 k conn/s | 2.7× más que NATS |
mtwRequest queda 🥇 o 🥈 en cada métrica de latencia — y además ofrece HTTP, agentes IA, auth, trading y MCP en el mismo core.
NATS sigue liderando en throughput crudo de broadcast en fanout-1000: 2.66 G/s vs los 506 M/s de mtwRequest (5.2× más). Es un techo estructural de TCP-sin-WebSocket — un trade-off consciente que hacemos para mantener el protocolo compatible con browsers. Si tu hot path es server-to-server, NATS es la elección correcta.
Gráficos del último run
Distribuciones sobre mtw, nats, centrifugo y socketio. Generados por el bench-suite — mismo artefacto que obtendrías localmente.
Latencia fanout
1 publisher → N subscribers · 100 y 1000 subs · payload 128 B
Echo round-trip
Requester → echo bot → requester · 2.000 round-trips
Connect storm
500 conexiones concurrentes · latencia por conexión + tasa
Corré bench-suite/run.sh en el repo para reproducirlo en tu propio host.
Qué trae el core
No es un broker pegado con cinta. Es un único runtime con baterías incluidas.
Un solo runtime, no tres
pub/sub + REST + agentes IA comparten conexión, auth y estado. Dejá de pegar NATS + Express + un framework de agentes aparte.
Wire format dual
JSON por defecto para interop. MsgPack opt-in vía subprotocolo mtw.msgpack.v1 — distribución p99 4.7× más estrecha, ~50% menos bytes.
Módulos componibles
Trait MtwModule con lifecycle hooks, middleware con prioridad, canales pub/sub con glob matching e historial. Marketplace para instalar.
Observabilidad incluida
Tracing estructurado, healthchecks por módulo, métricas HdrHistogram en el bench-suite. El cableado de producción viene en el core.
Bindings multilenguaje
Bindings nativos para Node.js, Python y PHP. Browser vía WebAssembly. Mismo wire protocol en todos los clientes.
Pub/sub con glob + historial
Suscribite con patrones tipo orders.eu.*. Los canales tienen historial reproducible: nuevos suscriptores pueden ponerse al día.
Dos vistas del mismo runtime
Suscribite desde un browser. Componé un módulo del lado servidor. Misma conexión, misma auth.
const ws = new WebSocket('wss://api.example.com/mtw', 'mtw.msgpack.v1'); ws.onopen = () => { ws.send(JSON.stringify({ "type": "subscribe", "channel": "orders.eu.*" })); }; ws.onmessage = (msg) => { const evt = JSON.parse(msg.data); console.log('event', evt.channel, evt.payload); };
use mtw_request::{MtwModule, Context, Result}; pub struct PriceFeed; #[async_trait] impl MtwModule for PriceFeed { fn name(&self) -> &str { "price-feed" } async fn on_start(&self, ctx: &Context) -> Result<()> { ctx.subscribe("ticker.*").await?; Ok(()) } async fn on_message(&self, ctx: &Context, m: Message) -> Result<()> { ctx.publish("alerts", m.payload).await } }
Bindings para cada cliente
Mismo wire protocol. Misma auth. Distinto lenguaje en el borde.
Node.js
DisponiblePython
DisponiblePHP
DisponibleBrowser (WASM)
RoadmapCuándo mtwRequest, cuándo no
Defaults honestos. Elegí la herramienta correcta para tu hot path.
Elegí mtwRequest si…
- • Necesitás WebSocket + HTTP + agentes IA en un solo runtime
- • La latencia de cola en fanout hacia browsers es tu SLA
- • Querés composición por módulos, no un broker congelado
- • Querés auth, MCP y trading en el mismo core (en roadmap / shipped)
Elegí NATS si…
- • Tu hot path es server-to-server por TCP, sin browsers
- • Necesitás 1 G/s+ de throughput crudo de broadcast
- • Ya operás un cluster JetStream que te funciona
- • No necesitás HTTP ni agentes IA en el mismo proceso
Construido sobre
Cimientos aburridos. Comportamiento predecible.
Preguntas frecuentes
¿En qué se diferencia mtwRequest de NATS o Centrifugo?
¿Los benchmarks son reproducibles?
¿JSON o MsgPack? ¿Cuál uso?
¿Qué bindings de lenguaje hay?
¿Hay marketplace de módulos?
¿Licencia y soporte?
Reproducí el bench, forkeá el core
Apache-2.0. El runner está en el repo. Si querés ayuda en producción, agendá una consulta.