The current reflex.utils.telemetry.send function creates an asyncio task to submit the telemetry event async (if an event loop exists) or it just sends it sync (when we haven't started an event loop, like in the cli).
But then it actually does the send with a synchronous httpx.post and it collects data using blocking syscalls and subprocess commands. These calls will cause the event loop to block, which could impact server operations (for example when sending runtime error telemetry at a high rate).
All telemetry event processing should be done in a separate lazy-initialized thread pool with a single worker. Internally the pool can manage work queueing and checking for/reporting telemetry send failures should be suppressed and never result in the app not working.
The current
reflex.utils.telemetry.sendfunction creates an asyncio task to submit the telemetry event async (if an event loop exists) or it just sends it sync (when we haven't started an event loop, like in the cli).But then it actually does the send with a synchronous httpx.post and it collects data using blocking syscalls and subprocess commands. These calls will cause the event loop to block, which could impact server operations (for example when sending runtime error telemetry at a high rate).
All telemetry event processing should be done in a separate lazy-initialized thread pool with a single worker. Internally the pool can manage work queueing and checking for/reporting telemetry send failures should be suppressed and never result in the app not working.