Ryan Malloy 86070e4688 Add docs-site: Astro + Starlight at informix-db.warehack.ing
22 pages across Diataxis quadrants (start / how-to / reference / explain).
Custom amber-on-charcoal theme, wire-dump hero animation, Supported
Systems footer badge. caddy-docker-proxy deployment with prod + dev
profiles, Makefile with prod/dev/down/logs/local targets.
2026-05-08 03:23:22 -06:00

2.1 KiB
Raw Blame History

title description sidebar
Optimize bulk SELECT How the buffered reader works in practice — when it's on, when it isn't, how to A/B-measure your workload.
order
5

The connection-scoped buffered reader (Phase 39) is enabled by default as of 2026.05.05.12. For most workloads you don't need to touch anything — the bulk-fetch gap against IfxPy is now ~515% rather than ~140%.

For the architectural rationale, see The buffered reader →.

Disabling the buffered reader

IFX_BUFFERED_READER=0 python my_app.py

The flag is read once at connection construction. To flip behavior on existing connections, close and reopen the pool.

There's no expected reason to disable it in production. The flag exists so you can A/B-measure your own workload and so we can debug regressions if they appear.

A/B-measuring your workload

# Baseline: no buffered reader
IFX_BUFFERED_READER=0 python -m mybench

# With buffered reader
IFX_BUFFERED_READER=1 python -m mybench

For typical bulk-SELECT workloads expect a 3040% wall-time reduction. For workloads dominated by single-row queries the impact is small (small queries are RTT-bound, not framing-bound).

When the speedup is largest

Workloads where every column read makes ~45 small recv() calls — i.e. tabular data, narrow rows, large row counts. The buffered reader replaces N small recv() calls with one recv(64K) per ~64 KB of incoming data.

Workload shape Speedup
Wide row, single fetch (1 row × 100 cols) minimal
Narrow row, large fetch (100k rows × 5 cols) 3040%
executemany response drain (1k inserts) 2530%

Memory profile

The buffer is per-connection, sized to grow up to the largest single PDU it sees. Typical steady-state: 64 KB to a few hundred KB per connection. The buffer is freed when the connection closes; for long-lived pool connections it's amortized.

If you're running 10,000 connections at idle, the buffer cost is ~12 GB across the fleet. For typical pool sizes (1050 connections) it's ~110 MB total.