min_allocation_size_to_log_stack_trace
Minimum size, in bytes, of a single charge to the global (server-wide) memory tracker for which a stack trace is captured, written to the server log atWarning level and inserted into system.trace_log with trace type MemoryLargeAllocation.
The size compared against the threshold, and reported, is what one tracker call charges, which is not necessarily one allocation: a thread defers its small allocations and flushes them as a single charge, so the reported size can exceed the allocation at the top of the reported stack by up to max_untracked_memory. Keeping the threshold well above max_untracked_memory keeps that difference immaterial.
This is a diagnostic for a global tracked total that has grown far beyond the process’s real memory usage. In that state the server refuses every allocation, down to zero-byte ones, while using a fraction of its limit, and ordinary telemetry cannot attribute the step: allocations charged under a MemoryTrackerBlockerInThread skip the limit check and the traces that accompany it, and the system.trace_log inserts that would carry the rest fail once the server is wedged. The server log keeps being written, so the stack trace reaches it.
At most 10 traces are captured per server run, because capturing and symbolizing a stack is expensive and the trigger tends to repeat. Changing this setting at runtime, in either direction, does not raise that bound.
Requires trace_log to be configured. Without a running trace collector the value is ignored and reported as 0 in system.server_settings, since the trace could only be captured and discarded. A trace the collector processes before that table is attached, which happens late in startup, reaches the server log only.
A value of 0 (default) disables the diagnostic. Set it well above the largest allocation the server legitimately makes, otherwise ordinary large allocations are logged too and startup can spend the whole budget.
min_allocation_size_to_throw_on_memory_limit
Minimum size, in bytes, of a generic C++ allocation (the kind made by standard containers, strings,std::vector growth, smart pointers, etc.) that is allowed to raise MEMORY_LIMIT_EXCEEDED once max_server_memory_usage is reached. Smaller generic allocations are still counted against the memory tracker but are allowed to succeed even past the limit, which reduces spurious failures during cleanup and exception-handling paths near OOM.
Allocations made by ClickHouse’s own large buffers — column data, hash tables, arenas, query pipelines, IO buffers — always honour the memory limit and may throw regardless of this value. This setting only affects implicit allocations that flow through operator new.
A value of 0 (default) preserves the legacy behaviour: implicit operator new allocations are never refused by the memory tracker, and only explicit ClickHouse allocations can raise MEMORY_LIMIT_EXCEEDED.
Note, to avoid side effects it is recommended to set value greater then max_untracked_memory.