Skip to content

Native async ClickHouse client: await the network instead of pinning worker threads #30

Description

@FreaxMATE

Motivation

Async consumers (energydb in particular) reach ClickHouse through asyncio.to_thread(sync_call) today, at three sites in energydb's _io.py. Profiling on the engine read path shows ch_ms is 94 to 98% of read wall time (45.1 of 47.5 ms at one series, 3,785 of 3,795 ms at 6,000 series), so almost everything that currently pins a worker thread is pure network wait.

clickhouse-connect (already pinned >=1.7.2) ships a real aiohttp-based AsyncClient. Its query_arrow awaits the network natively and offloads only the pyarrow IPC parse to an executor, which is exactly the split timedb wants.

A second benefit: the network phase becomes cancellable. A to_thread CH call is not, as the comment in energydb's _io.py puts it: "await it or the query thread outlives the read that started it."

Proposal

Add a native async client path to timedb (e.g. an AsyncTimeDBClient alongside the existing sync TimeDBClient) built on clickhouse_connect.get_async_client, and move async consumers' read/write paths onto it.

Scope notes

  • TimeDBClient is synchronous top to bottom and the published wheel has sync consumers, so this is an API addition, not a drop-in swap.
  • One clickhouse-connect AsyncClient binds to one event loop; lifecycle needs to account for that.
  • The clickhouse-connect[async] extra must be declared. No version pin bump is needed.

🤖 Generated with Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions