SeleniumHQ / SeleniumHQ/selenium

[🚀 Feature]: [BiDi] High latency in Python & Ruby BiDi/CDP command execution due to sleep-based polling

Open
#17,797 1 comment 0 reactions 0 assignees View on GitHub
A-needs-triaging B-devtools I-enhancement
Dominant language
Java
Stars
34.5k
Forks
8.7k
Avg merge
2d 1h
Merged PRs (30d)
92

Description

### Description

### Body

### Describe the bug
When executing WebDriver BiDi or CDP commands via WebSockets in Python and Ruby bindings, there is a substantial mandatory latency (~50-100ms) per command execution.

This latency occurs because the websocket connection wrappers in both Python and Ruby execute a polling loop to wait for the target message ID to appear in the received messages queue, using a `sleep(0.1)` (100ms) sleep interval.

Even if the browser responds immediately in less than 1ms, the calling thread is forced to sleep until the next poll cycle, creating a severe performance bottleneck for high-frequency command execution (e.g., listening/responding to console log events, network traffic monitoring, etc.).

### Steps to reproduce
Run any WebDriver BiDi command (e.g., executing scripts or navigating contexts) repeatedly, and measure the round-trip latency. It consistently floors around ~50-100ms per command.

### Expected behavior
The command execution thread should block and wake up immediately when the browser's response is received on the WebSocket listener thread, without sleeping or busy-polling.

### Proposed Solution
Replace the sleep-based polling loops with standard thread synchronization primitives:
1. **Python**: Map each pending command ID to a `threading.Event` and block using `event.wait(timeout)`. Signal/set the event immediately when the response is processed.
2. **Ruby**: Map each pending command ID to a `Thread::ConditionVariable` and block using `cond.wait(mutex, timeout)`. Signal the condition variable immediately when the response is processed.

### Have you considered any alternatives or workarounds?

_No response_

Contributor guide

Open the contributing guide

Research direction

Start in the Python and Ruby WebSocket connection wrappers, tracing the sleep-based polling loops that wait for pending command IDs and the listener path that processes responses. Reproduce repeated WebDriver BiDi or CDP commands and measure the round-trip latency; done means the waiting command wakes when its response is processed rather than on a polling interval, while preserving timeout behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, ruby
Domain
backend-api-design, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.