Predictive multi-level message queue
Same messages. Same worker. A smarter order.
Harbinger learns how long each kind of message takes, then serves cheap work first, with no hand-labelled priorities.
- 1PredictEach message's cost, from what its keyKeyWhat Harbinger groups messages by when learning: the producer, optionally plus a job_type label (and size). Each key gets its own duration history. took before.
- 2RouteCheap work to L0, heavy work to L2.
- 3LearnEligible successful AcksAckShort for acknowledgement. A consumer tells the broker it finished a message, and here it also reports how long the work took.Learn more ↗ update its duration statistics.
FIFOFIFOFirst in, first out. Messages are served strictly in arrival order, like a single supermarket line.Learn more ↗
One lane. A long job blocks everything behind it.
Harbinger
Predicts each message's cost, then serves cheap work first.
How it flows
Submit
A producerProducerA program that creates messages and sends them to the queue.Learn more ↗ sends a message over gRPCgRPCA fast way for programs to call each other over a network. Harbinger's producers and consumers talk to the broker with it.Learn more ↗. It can attach a job_type header, and optionally a size, so the brokerBrokerThe server in the middle. Producers hand messages to it, and consumers pull messages from it.Learn more ↗ can tell its jobs apart.
What it learns
No model server. The brokerBrokerThe server in the middle. Producers hand messages to it, and consumers pull messages from it.Learn more ↗ keeps a decaying duration histogramHistogramA count of how many times each range of values occurred. Here: how many jobs took 1–2 ms, 2–4 ms, and so on.Learn more ↗ per keyKeyWhat Harbinger groups messages by when learning: the producer, optionally plus a job_type label (and size). Each key gets its own duration history. and reads its medianMedianThe middle value: half the jobs are faster, half slower. It describes a typical job and ignores rare outliers.Learn more ↗. Unready or erratic keys fall back to the middle tierTierA priority level in the queue. L0 is served first, then L1, then L2.Learn more ↗.
Does it work?
Original synthetic production-flow benchmark on AWS, 5 seedsSeedA starting number for a random generator. Same seed, same random-looking data, so a run can be repeated exactly.Learn more ↗ × 7 arms, replicating a laptop run (−26% meanMeanThe ordinary average. It is pulled up by a few very slow items, so it shows the overall experience better than the median does.Learn more ↗ on a quiet machine). The tail did not improve: all-message P99P95 / P99 (tail latency)P99 is the time that 99% of messages beat. It describes the slowest 1%, the "tail", which matters because users notice the slow ones.Learn more ↗ was about 1.03× FIFOFIFOFirst in, first out. Messages are served strictly in arrival order, like a single supermarket line.Learn more ↗. These gains describe this workload, not every queue.
The latest evidence: real traces through the broker
- 0/6cells passed with default-aging routing
- 4/6cells passed with weights + pausing aging
Azure and Huawei traces now run through the real brokerBrokerThe server in the middle. Producers hand messages to it, and consumers pull messages from it.Learn more ↗ with sleeping handlers. Long backlogsBacklogMessages that have arrived but are still waiting because workers can't keep up. can erase predicted ordering under default agingAgingA message that has waited too long is moved up one priority level, so low-priority work is delayed but never stuck forever.Learn more ↗. WeightsLevel weightsInstead of always serving the highest level first, each level gets a share of worker time (for example 8 : 3 : 1). Lower levels still make steady progress. with pausing agingPausing agingAging that holds off promoting a message while the level above is still working through earlier promoted messages. It stops a long backlog from pushing everything to the top. recover gains at the two higher loads on both traces; separate Huawei runs show aging off can also recover gains, with higher window-level P99P95 / P99 (tail latency)P99 is the time that 99% of messages beat. It describes the slowest 1%, the "tail", which matters because users notice the slow ones.Learn more ↗ and long waits. Azure ran once per cell, and its load-0.8 pass is narrow.
Build and run
Start in shadow modeShadow modeThe predictor runs and learns, but its guesses are only recorded, never used. Safe way to try it on real traffic.: it records predictions without changing routing. Default routing stays static; predictive routing is opt-inOpt-inOff by default. You have to switch it on deliberately.. This is an in-memory research prototype: messages and leases are not recovered after restart, and predictorPredictorThe part of the broker that estimates how long a message will take, using what earlier messages with the same key took. snapshots save statistics, not deliveries. It is not production-ready.