#2397·ratatui

are the mice cheese-starved? memory usage on embedded.

Author: junkdogCreated Feb 14, 2026Updated Jul 30, 2026
LabelsType: EnhancementType: RFC

the tldr

embedded devices have smol memories. we can save some of that memory by replacing Cell::symbol with a custom string type. but it should be feature-gated/only applies to embedded.

background

MCUs have tiny amounts of memory available (usually around 200kb). since memory is so precious, i've been looking around for places to free up some extra resources on memory-constrained devices. ratatui maintains two screen buffers of Vec<Cell>, where each Cell::symbol is represented by a CompactString - 12 bytes on 32-bit, 24 bytes on 64-bit architectures (this constitutes ~40% of a Cell's memory usage).

for a 50x24 terminal, that's 50*24*2=2400 cells - or just over 28kb on a 32-bit MCU just for the symbols. ratatui's cells support a wider range of symbols compared to mousefood - mousefood never allocates more than 4 bytes for a symbol. there's a pretty big optimization opportunity here if we add an opt-in feature for enabling a more compact string type.

proposal

i opened a POC as a draft PR (#2398), so that we have something to discuss around. it revolves around a 4-byte EmbeddedStr, which is internal to Cell::symbol and replaces the CompactString. this resulted in a doubling of framerate when drawing an "idle UI" (just drawing some basic widgets) - running a simple sweeping transition animation was about 30% faster, while memory usage was reduced from 120kb to 90kb. the POC also performs some optimizations around cell width calculation (it's easy on embedded - mousefood only supports single cell width fonts), but those are not memory-related.

benchmark results are posted in the POC PR, but overall it's 2-8x faster than the existing impl.

tradeoffs

the 4-byte fixed-size approach means EmbeddedStr can store a single unicode codepoint, but not multi-codepoint graphemes (emoji ZWJ sequences, combining characters, etc). append_symbol() is stubbed out as a no-op. for mousefood and similar embedded use cases, this is a non-issue - but worth mentioning.