9.4 Resource Exhaustion

9.4.1 Memory #

If the out-of-memory killer takes eventd, it is treated exactly as a crash (§8.5): the databases are consistent, the ring buffers are untouched, peinit restarts the daemon, and the gap is recorded.

The principal long-lived memory consumers are:

ConsumerProportional toBounded by
Series cachedistinct metric series held in memoryMetricSeriesCacheSize (§5.3)
Event-type and log-origin intern setsdistinct committed identifiers not yet cleaned from active cataloguescatalogue cardinality; no independent memory setting (§3.1, §4.2)
Adaptive index countersdistinct event fields queriedthe event query surface
SQLite page cachesconnections and active indexesper-connection configuration (§C)
Event handoff channelsoccupied slots and copied event bytesstartup-fixed internal slot and byte limits (§2.3)

The handoff limits do not follow live MaxBatchSize changes. The channels are small scheduling handoffs; KMES remains the real event backlog.

High-cardinality producers are the likely surprise. The series cache cannot grow past its limit, but the series table can grow and make it thrash on the thread that also drains the metric socket (§5.3). Identifier intern sets intentionally trade memory for zero catalogue work on known-name ingestion. The default 1 GiB metric retention ceiling and low-priority orphan cleanup bound persistent growth indirectly, but do not bound the number of active series between retention passes.

9.4.2 Query slots #

Reaching MaxConcurrentQueries, MaxStreamingQueries or MaxQueriesPerUser rejects new queries with an error rather than queueing them (§6.5). The per-user bound keeps one caller from occupying every slot; several callers together, or SYSTEM, still can.

Ingestion is unaffected, because queries and ingestion are separate channels and separate threads. That separation is what makes query-side exhaustion an inconvenience rather than data loss.

9.4.3 Descriptors #

An event query opens a read-only connection per shard database, and each connection holds one or two file descriptors (§6.4). Many historical shards multiplied by many concurrent queries reaches a process limit faster than anything else eventd does.

Where eventd cannot allocate what an admitted query needs, it fails that query rather than blocking a writer or exceeding its own limit (§6.1).

9.4.4 Writer stalls #

Two things stall a writer thread briefly, and both are bounded by design.

An index build in progress. Drain threads detect rising write pressure and signal cancellation; the writer aborts the CREATE INDEX, SQLite rolls back the partial index, and event writing resumes immediately (§3.4).

A writer-owned maintenance command. Retention and adaptive-index maintenance execute only as bounded, low-priority commands at transaction boundaries. Ingestion wins before the next command; there is no competing read-write connection or writer mutex (§3.6).

Neither stall loses anything by itself. Both contribute to ring buffer pressure, and prolonged enough, both end at §9.1.

Edit this page