Reduce SerializationBuffer stack size from 768 to 512 bytes

768 bytes on the httpd task stack contributes to stack overflow when
combined with other stack-allocated buffers (query string parsing, etc.).
512 bytes still covers all typical JSON payloads (sensors ~200B, lights
~170B, climate ~500-700B). Only extreme edge cases with 40+ options
trigger heap fallback.
This commit is contained in:
J. Nick Koston
2026-02-11 18:57:53 -06:00
parent 9ef0ad3f9d
commit 181fb4f8ac
2 changed files with 5 additions and 5 deletions

View File

@@ -75,7 +75,7 @@ SerializationBuffer<> JsonBuilder::serialize() {
// directly in the caller's stack frame, eliminating the move constructor call entirely.
//
// WITHOUT NRVO: Each return would trigger SerializationBuffer's move constructor, which
// must memcpy up to 768 bytes of stack buffer content. This happens on EVERY JSON
// must memcpy up to 512 bytes of stack buffer content. This happens on EVERY JSON
// serialization (sensor updates, web server responses, MQTT publishes, etc.).
//
// WITH NRVO: Zero memcpy, zero move constructor overhead. The buffer lives directly
@@ -94,7 +94,7 @@ SerializationBuffer<> JsonBuilder::serialize() {
// Should show only destructor, NOT move constructor
//
// Why we avoid measureJson(): It instantiates DummyWriter templates adding ~1KB flash.
// Instead, try stack buffer first. 768 bytes covers 99.9% of JSON payloads (sensors ~200B,
// Instead, try stack buffer first. 512 bytes covers 99.9% of JSON payloads (sensors ~200B,
// lights ~170B, climate ~700B). Only entities with 40+ options exceed this.
//
// ===========================================================================================

View File

@@ -17,9 +17,9 @@ namespace esphome {
namespace json {
/// Buffer for JSON serialization that uses stack allocation for small payloads.
/// Template parameter STACK_SIZE specifies the stack buffer size (default 768 bytes).
/// Template parameter STACK_SIZE specifies the stack buffer size (default 512 bytes).
/// Supports move semantics for efficient return-by-value.
template<size_t STACK_SIZE = 768> class SerializationBuffer {
template<size_t STACK_SIZE = 512> class SerializationBuffer {
public:
static constexpr size_t BUFFER_SIZE = STACK_SIZE; ///< Stack buffer size for this instantiation
@@ -177,7 +177,7 @@ class JsonBuilder {
}
/// Serialize the JSON document to a SerializationBuffer (stack-first allocation)
/// Uses 768-byte stack buffer by default, falls back to heap for larger JSON
/// Uses 512-byte stack buffer by default, falls back to heap for larger JSON
SerializationBuffer<> serialize();
private: