Skip to content

Increase the broadcast budget - #55

Merged
puddly merged 1 commit into
devfrom
puddly/increase-broadcast-budget
Jul 29, 2026
Merged

Increase the broadcast budget#55
puddly merged 1 commit into
devfrom
puddly/increase-broadcast-budget

Conversation

@puddly

@puddly puddly commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Follow up to #54 (and #43).

I ran a quick packet capture test on my home network while spamming broadcasts (setting Ziggurat's limit to 255) and noticed something odd: none of my home routers behaved the way the SiLabs SDK claims they should and none of the routers ever really stopped relaying packets during a sustained burst of almost 64 broadcasts in 20 seconds.

Many manufacturers using SiLabs chips thankfully do not enable firmware encryption so we can statically analyze what they use as the firmware config. The results are a little surprising (the IKEA ones were checked by hand, the rest were checked with a script that speeds up the analysis):

Vendor Images Table size(s)
NodOn 35 15 (3), 35 (32)
IKEA 31 15 (6), 46 (4), 50 (14), 56 (7)
Innr 15 40
Bosch 5 15
SalusControls 5 15
Niko 4 40 (3), 50 (1)
Datek 3 15
Gledopto 2 40
Heiman 2 15
LEDVANCE 2 50
Aeotec 1 15
EcoDim 1 50
Inovelli 1 15

All new generation IKEA devices override the broadcast table size to 50! Inner and Gledopto use 40, LEDVANCE uses 50. Hue images are encrypted but they behaved identically to IKEA so I would assume they use at least 40-50 as well.

For a network consisting of popular router devices (IKEA, Hue, Innr, etc.), every router on the network has a broadcast table size of 40-50 and theoretically can relay broadcasts at a rate of 2/second. I think we can adjust the Ziggurat rate limiting accordingly.

Copilot AI review requested due to automatic review settings July 28, 2026 23:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adjusts Ziggurat’s broadcast rate limiting defaults (token bucket capacity and refill rate) to better match observed real-world Zigbee router broadcast table sizes/rates (e.g., IKEA/Hue/Innr-class meshes), improving sustained broadcast throughput and burst tolerance.

Changes:

  • Increased the broadcast token bucket capacity (broadcast_budget_tokens) from 15 to 40.
  • Increased the sustained broadcast admission rate by decreasing broadcast_token_refill from 1800ms to 675ms (~1.48 broadcasts/sec).
Comments suppressed due to low confidence (1)

crates/ziggurat-zigbee/src/constants.rs:388

  • The doc comment for broadcast_critical_reserve says stack-critical broadcasts may draw these tokens, but the implementation admits TrafficClass::Critical without drawing from the bucket (BroadcastBudget::take bypasses tokens entirely). This makes the comment misleading—these tokens currently act as an unconsumable floor for host/forwarding traffic, not a critical-only reserve.
    broadcast_token_refill: Duration = Duration::from_millis(675),

    /// Broadcast tokens only stack-critical broadcasts (route discovery, key updates,
    /// leaves, ZDO management) may draw; a host flood can never consume them.
    broadcast_critical_reserve: u8 = 3,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@MattWestb

Copy link
Copy Markdown

Puddly is going all in on ZHA Rappid Adaptive lighting !!!

Great digging and findings !!!
I was having the same feeling in my test sniff and i think the Styrbar was limited by its parent (IKEA GU10 WS) that was doing it in the app layer and not in the Zigbee network / 15.4 layer (then no misses counters observed that shall have bin if discarded by the network).
Broadcasts at a rate of 2/second or more is indeed possible in not very large network
The the question is have they also patched the 15.4 for not blocking for broadcast storms ?
I dont knowing how to testing it to the max it in my test systems (then is not deep enough) and my production network (around 90 devices but very spredd) is not good for doing that kind of test (running old more or less standard EZSP util being merged to Ziggurat in the near future).

One way is making one Zigbee controller bridge and broadcasting from its CLI but i think its over my competence to do right (spamming broadcast messages with one increasing number in the payload like light level 1-254 and then down agen and setting the interval for etch run).
Also interesting is testing if Telink have doing the same "patch" then most tuya devices is using that chip (and some versions of IKEA Kajplats and there thread plugs) and many users is using them widely.

Need some more barnstorming here so @tube0013 and @TheJulianJES do you both have some thinking how to testing if the 15.4 and / or Zigbee network layer is blocking for broadcast storming ? Also do you have one network with 2 or more level of routers that can testing if its working all over or only in the first level (direct connected to the coordinator) ??

I think we need to do one myth buster list in the community and putting puddly on top of it !!

I only saying that all person have one brain but most have not learning to using well but this man have !!

@puddly
puddly merged commit 96face2 into dev Jul 29, 2026
2 checks passed
@puddly
puddly deleted the puddly/increase-broadcast-budget branch July 29, 2026 13:53
@puddly

puddly commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

I'm going to merge this PR for now but I think it would be nice to have some good testing methodology to figure out the actual broadcast behavior of these devices. Anecdotally, I found my Third Reality plug (Bouffalo) to also not filter broadcasts. These were color changing commands.

I think an isolated network with just two devices sending broadcasts once per 500ms should be enough to figure out the rate limiting method. For TI/ZBOSS/etc., the router should keep accepting and relaying new broadcasts until its limit is hit and then slow down to relaying new broadcasts at its table entry aging rate. For SiLabs, it should also fill up and then stop completely in 5s bursts as it ages the whole table at once. I don't think Telink/Bouffalo/Espressif's implementations of the broadcast table will be too different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants