perf: drop the live WebSocket feed from 2 Hz to 1 Hz - #1929
Closed
padddi wants to merge 9 commits into
Closed
Conversation
* Make Wi-Fi PMS optional * Disable experimental RSNO client support * Add comment
- Serialize fallback API polling, relax WebSocket timeout and retry timing, and enable HTTPD TCP keepalive to improve recovery from stale clients.
Spelling fix on settings page of web UI.
* Add Naja Duo 1201 board support (#1892) * Add Naja Duo LCD interface (#1893) * Add Naja Duo factory self-test (#1891) * Add Gamma Hex 1300 board support (#1894) * Review code (#1836) * Mitigate VLA stack risk and fix read register delay (#1836) * Use device config asic count for register loop (#1836) * Extract constants (#1836) * TPS546 PMBus Telemetry & Active-High ASIC Enable (#1837) * DeviceConfig GPIO Pin Abstraction (#1840) * Refactor device, family, and ASIC checks into declarative config * Rename device pins to BITAXE_ORIGINAL_PINS and BITAXE_COLOR_PINS * Cleanup whitespace in TPS546.h * Use typed GlobalState in asic read_registers * Add VLA stack guard * Add domain_hashrate_scale to AsicConfig * Fix vTaskDelay and add TODO tag on BM1373_read_registers * Remove unused things * Clean up asic_init_with_timings * Document BM1373 baud setting location * Clean up unused set_default_baud functions * Fix BM1397 packet length guard * fix display rotation (#12) Co-authored-by: WantClue <wantclue@users.noreply.github.com> * Fix BAP define * Set protocol_task stack to 8kb * Put display buffers in PSRAM * Allocate valid_jobs in PSRAM --------- Co-authored-by: Ben <wilsob12@gmail.com> Co-authored-by: WantClue <info@wantclue.de> Co-authored-by: WantClue <wantclue@users.noreply.github.com>
Every tick of websocket_api_task() rebuilds the full system-info JSON tree via system_api_get_full_json(), then diffs it against the previous one with cJSON_GetDiff(). cJSON objects are linked lists, so the cJSON_GetObjectItemCaseSensitive() call inside the diff loop is a linear scan per key: roughly 5,000 string comparisons over the tree's ~100 keys, per tick. At 500 ms that ran 10,000 times a second, and it is the largest recurring CPU cost on the device while the web UI is open. None of the telemetry the feed carries changes faster than once a second, so the higher rate bought nothing. Halving it is a one-line change with no structural risk. The Angular client merges whatever arrives (live-data.service.ts) and makes no assumption about the interval, so nothing on the frontend needs to change. This does not fix the underlying O(n^2) diff, only how often it runs. Replacing it — keeping the last sent state in a flat struct and comparing field by field, or walking both objects in parallel since the key order is deterministic — is a separate change. Not compiled: no ESP-IDF toolchain available in the environment this was prepared in.
padddi
force-pushed
the
perf/websocket-feed-rate
branch
from
August 30, 2026 07:54
c08fc58 to
3422072
Compare
Collaborator
|
nack, ai generated + the impact is negligible, cpu usage stays below 15% please don't open automated prs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every tick of
websocket_api_task()rebuilds the full system-info JSON tree viasystem_api_get_full_json(), then diffs it against the previous one withcJSON_GetDiff().cJSON objects are linked lists, so the
cJSON_GetObjectItemCaseSensitive()lookup inside the diff loop is a linear scan per key. Over the tree's roughly 100 keys that is on the order of 5,000 string comparisons per tick — and at 500 ms, 10,000 per second. It is the largest recurring CPU cost on the device while the web UI is open, and it runs in full even when nothing has changed.Change
One line: the rate limit goes from 500 ms to 1000 ms.
None of the telemetry the feed carries — hashrate averages, temperatures, fan RPM, share counts — changes faster than once a second, so the higher rate bought nothing. This halves the cost with no structural risk.
Frontend
No change needed.
live-data.service.tsmerges whatever arrives and makes no assumption about the interval.Scope
This changes how often the diff runs, not the diff itself. Replacing the O(n²) comparison is a separate change, and there are two reasonable approaches:
system_api_get_full_json(), so a forward scan with a fallback gets O(n) for roughly 15 lines of change.I'd suggest measuring before picking one.
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATSis already enabled insdkconfig.defaultsandtask_monitor_taskalready exists, so a before/after capture is nearly free.Testing
Not compiled — no ESP-IDF toolchain was available in the environment this was prepared in, so CI is the first real build. The change is a single constant.