BBR-lite: congestion control in plain JavaScript
A small model-based congestion controller: estimate bottleneck bandwidth and minimum RTT, and size the window from their product.
Loss-based congestion control (Reno, CUBIC) treats packet loss as the signal that the network is full. BBR takes a different view: build a model of the path — how fast is the bottleneck, and how long is the round trip when queues are empty — and send at that rate.
The model in one line
const bdp = bbr_btlbw * bbr_min_rtt;
const cwnd = clamp(
2 * bdp,
min_limit_bytes_in_flight,
max_limit_bytes_in_flight // safety net
);bbr_btlbw is the maximum delivery rate seen over the last few round trips; bbr_min_rtt is the minimum RTT over the last ten seconds. Their product, the bandwidth-delay product, is exactly the amount of data the pipe can hold without building a queue.
Why "lite"
Full BBR cycles through startup, drain, probe-bandwidth and probe-RTT phases with carefully tuned gains. QUICO keeps the model and a simplified state machine: a startup phase that doubles until delivery rate stops growing, then steady pacing at the estimated rate with periodic probing. It is a fraction of the code and easy to instrument from JavaScript.
Pacing in an event loop
Sending at a rate means spacing packets out in time. In Node.js that means batching: we compute how many bytes the pacing budget allows since the last send, flush that many packets in one turn of the event loop, and schedule the next turn. Timers below a millisecond are not reliable, so the budget absorbs the jitter.
Congestion control is listed as in progress in the README; this post is the design we are converging on.