influxdata / influxdata/influxdb3-ref-network-telemetry

request_top_talkers exceeds documented Pattern C latency at all tested memory sizes; OOMs at default 4 GB Docker pool

Open
#2 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
0
Forks
1
PR merge metrics
No merged PRs in 30d

Description

## Summary

Under the demo's documented workload, `request_top_talkers` exceeds the
Pattern C latency budget set in `README.md:64` at every Docker memory size
tested, and exhausts the InfluxDB query memory pool at the Docker Desktop
default of 4 GB. The browser's top-talkers panel runs the same plugin every
5 s, so the failure is visible to live users, not only to `make demo`.

## What's true vs. documented

| Claim | Source | My measured (warm steady-state) | My measured (peak under demo workload) | Verdict |
| --- | --- | --- | --- | --- |
| Pattern C "10–100 ms" | README.md:64 | 230–360 ms | 1.7–4.3 s | **2–3× high at floor; 17–43× high at peak** |
| Pattern B "1–5 ms" | README.md:64 | 13 ms (UI badge), 84 ms (CLI) | unchanged under load | UI ~3× high; CLI ~17× high |
| LVC "sub-millisecond" | demo.sh:495 | 3–5 ms | 522 ms / 1.18 s / 7.6 s | **3–5× high at floor; 100–1500× high under contention** |

## Failure trace (verbatim, 4 GB Docker, original `make demo` step 8)

```
Python function call failed: QueryError: error: External error: Execution error
for 'deduplicate batches'
caused by
Resources exhausted: Additional allocation failed for SortPreservingMergeExec[0]
with top memory consumers (across reservations) as:
ExternalSorterMerge[1]#88864(can spill: false) consumed 141.7 MB, peak 141.7 MB,
ExternalSorterMerge[1]#87530(can spill: false) consumed 141.7 MB, peak 141.7 MB,
ExternalSorterMerge[1]#88598(can spill: false) consumed 141.7 MB, peak 141.7 MB,
ExternalSorterMerge[1]#88592(can spill: false) consumed 71.6 MB, peak 71.6 MB,
ExternalSorterMerge[1]#88858(can spill: false) consumed 71.6 MB, peak 71.6 MB.
Error: Failed to allocate additional 903.9 KB for SortPreservingMergeExec[0]
with 0.0 B already allocated for this reservation - 800.8 KB remain available
for the total pool executing query:
SELECT src_ip,
SUM(bytes) AS bytes,
SUM(packets) AS packets
FROM flow_records
WHERE time > now() - INTERVAL '5 minutes'
GROUP BY src_ip
ORDER BY SUM(bytes) DESC
LIMIT 10
```

## Reproduction

### Tier 1 — OOM at 4 GB Docker (deterministic)

Set Docker Desktop memory to 4 GB. `make clean && make up`. Run `make demo`.
Step 8 returns `Resources exhausted` after ~90 s and exits non-zero.

### Tier 2 — latency progression at 8 GB and 12 GB

Clean cluster (`make clean && make up`). Three calls per row, 5 s apart.
Dashboard tab open at `http://localhost:8080` (matches the live-user
condition; UI polls top_talkers every 5 s).

| Stage | flow_records (5-min) | top_talkers @ 8 GB | top_talkers @ 12 GB | LVC `COUNT(*)` @ 8 GB | LVC `COUNT(*)` @ 12 GB |
| --- | --- | --- | --- | --- | --- |
| Fresh, no scenarios | ~50 K | 180 / 180 / 297 ms | 618 / 425 / 342 ms | 3.1 / 3.9 / 4.5 ms | 22 / 3.7 / 3.6 ms |
| + congestion_hotspot | ~200 K | 242 / 240 / 231 ms | 2950 / 346 / 425 ms | 4.1 / 3.7 / 3.7 ms | 5.0 / 656 / 4.4 ms |
| + 1 × east_west_burst | ~600 K | 416 / 248 / 229 ms | 3719 / 2302 / 331 ms | 3.8 / 3.3 / 3.7 ms | 88 / 5.2 / 3.9 ms |
| + 3 × east_west_burst | – | 327 / 298 / 689 ms | 340 / 442 / 359 ms | 4.0 / 3.4 / 3.6 ms | 4.2 / 3.5 / 1183 ms |
| + 6 × east_west_burst | 686 K | 1715 / 405 / 1755 ms | 4281 / 320 / 311 ms | 3.7 / 3.7 / 522 ms | 4.0 / 4.7 / 4.2 ms |

## Pool sizing

`--exec-mem-pool-bytes` defaults to 20% of container `MemTotal`. Compose
sets no override. Measured directly via the `/metrics` endpoint:

| Docker memory | Container `MemTotal` | Pool limit | Idle reserved (8 GB sample) |
| --- | --- | --- | --- |
| 4 GB | ~3.91 GiB | ~819 MB (inferred) | not measured |
| 8 GB | 7.75 GiB | 1.55 GiB (1664511181 B) | 896 MiB (940080901 B; 56% of pool) |
| 12 GB | 11.67 GiB | 2.33 GiB (2505885286 B) | varies; 0 B at one sample |

At 4 GB the failure trace's 568 MB peak query plus the same 56% idle
reservation profile cannot fit. At 8 GB and 12 GB the query fits but
contends with the UI's 5 s polling cycle.

## Suggested mitigations

1. **Pin `INFLUXDB3_EXEC_MEM_POOL_BYTES`** in `docker-compose.yml` for
`nt-query` and `nt-process` (e.g., `1500000000`). Eliminates the 4 GB
OOM. Does not address the 8 GB and 12 GB latency.

2. **Reduce the `top_talkers` query memory footprint** in
`plugins/request_top_talkers.py` — push `LIMIT N` per partition before
the global sort. Required for the documented Pattern C latency at any
tested memory size.

3. **Document an 8 GB Docker minimum** in the README quickstart prereqs.
Doc complement to mitigation 1.

4. **Investigate `can spill: false`** on `ExternalSorterMerge` reservations.
Spillable sorts would convert the 4 GB OOM into a slowdown and reduce
the variance at 8/12 GB. Likely upstream of this repo.

Mitigation 2 is required to deliver the documented latency. Mitigations 1
and 3 prevent the deterministic OOM. Mitigation 4 is upstream.

## Side effect: LVC `COUNT(*)`

The LVC row in the verdict table above shows the same memory pool exhaustion
affecting unrelated queries: a scalar `COUNT(*)` against an in-memory cache
slows from ~4 ms to over a second when `top_talkers` is consuming the pool.
The cache itself reads in <1 ms; the query execution context shares the
pool. Mitigation 2 resolves this as a side effect.

## Environment

- Host: Apple M2 Pro (10 cores), macOS Darwin 25.4.0, 16 GB system RAM
- Docker Desktop 29.4.1; aarch64; 4 CPUs allocated to Docker
- Tested at 4 GB, 8 GB, and 12 GB Docker memory (separate runs, `make clean`
between tiers)
- Image: `influxdb:3-enterprise`, `linux/arm64` variant `v8`
(digest `sha256:7bf7cc1716fb81f0809d6de6a2da460353e027e871816f1904a91dbf4c8ed482`)
— native ARM64, no Rosetta emulation
- Compose at HEAD `d9c084a`; no `INFLUXDB3_EXEC_*` overrides
- All five InfluxDB nodes at default `--exec-mem-pool-bytes 20%`
- Dashboard tab open during measurements (UI polls top_talkers every 5 s)
- Not yet verified on linux/amd64; the OOM mechanism is memory-pool-budget
driven and is expected to reproduce there, but absolute latencies will
differ.

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the failure with `make clean && make up` and `make demo`, starting with `plugins/request_top_talkers.py` and the query's memory behavior. Inspect `docker-compose.yml` for pool configuration and `README.md:64` for the latency target. Done means the demo avoids the 4 GB OOM and `request_top_talkers` meets the documented Pattern C latency under the stated workload.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker-compose, python
Domain
backend, databases, devops, 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.