The pattern you already have
Somewhere in your system, a publisher emits a stream that is faster and noisier than anything downstream actually wants.
A car publishes engine RPM ten times a second. A market data feed ticks on every quote. A temperature sensor posts a fresh reading every two seconds, mostly identical to the last one. An OBD2 dongle, a fleet tracker, and an industrial PLC all have the same shape. The publisher emits raw data at its own rate because it does not know, and should not have to know, what each subscriber cares about.
So the subscribers cope. Open the source of three consumers of that stream and you will often find the same defensive code written three times. Parse the frame. Round the float to the precision this consumer needs. Drop the reading if it is the same as the last one. Ignore values inside a deadband. Keep a small window for a moving average. Watch for a jump and raise an alert. None of it is hard. All of it is duplicated.
This is so normal that it can stop looking like a problem. It gets called consumer code, but it is still repeated work.
Why doing it many times is worse than it looks
Every subscriber reads the whole stream, including the messages it is about to throw away, then does the throwing away locally. If forty consumers each subscribe to a stream where ninety per cent of messages are repeated values, you pay to deliver and parse that ninety per cent forty times. The network moved it, every consumer socket received it, every consumer CPU parsed it, and then every consumer dropped it.
Then there is drift. The rounding logic in consumer A is 2dp. In consumer B, written eight months later by someone who has since left, it is 3dp. The deadband in one is 0.5 and in another is 0.6 because it was tuned once for a demo and never changed back. The dedupe in a third has an off-by-one error in the window.
Each difference is small. Together, they mean the same data is no longer the same data, depending on which consumer you ask. Nobody set out to create that problem. It grew one copy at a time.
The rules describe the data, not the consumer
Take a rule like this: an RPM stream should be rounded to whole numbers and should only emit a new value if it moved by at least 50. That is not a fact about one consumer. It is a fact about the stream. It is true no matter who is listening.
The same applies to duplicate reprints, price jumps, sensor deadbands, rolling averages, and threshold alerts. If the rule is true for the stream, putting it in every consumer is the wrong place for it. You have taken one definition and scattered it across many processes.
The conditioning should live in one upstream place, defined once.
A broker or rules-driven consumer is a reasonable place
Every consumer already meets the stream at the broker, and any one shared process can subscribe there before the data fans out. That shared process is the right place to run the rules.
Condition the stream once, and every subscriber downstream receives the same cleaned data. Subscribers no longer parse values they will discard because the discarding has already happened. They no longer carry rounding logic because the numbers arrive rounded. They no longer drift because they share one definition.
There is another useful effect. Once conditioning happens in one shared place, each result can have its own subject. The rounded and deduplicated price stream is a subject. The value crossed the threshold event is a subject. A consumer that only wants stable prices subscribes to the stable subject and never receives the raw stream.
That is the core idea. Signal conditioning, including rounding, deadbands, squelch, windows, moving averages, OHLC bars, and derived alerts, belongs in one upstream rules-driven step as a property of the stream.