# Arduino warns “Low memory available”: stack problems, String use and the F\(\) macro

> Cut Arduino RAM use: keep text in flash with F\(\), avoid String objects in loops, shrink arrays and read the memory figure after each build.

Canonical: https://roboticsengineering.in/fix/arduino-low-memory-available-stability-problems-f-macro/ | Published: 2026-11-03 | Updated: 2026-11-04

**Keep constant text in flash with the F() macro, and avoid String in loops.**

## What the message means

An Uno has only 2 KB of RAM. When global variables use most of it, the stack runs out and the board resets or acts oddly.

## Fix it in this order

1. Read the percentage of dynamic memory in the build output.
2. Wrap print text as Serial.println(F(“text”)).
3. Replace String objects with char arrays where you can.
4. Make arrays only as big as needed, and use smaller types such as byte.
5. Store tables in flash with PROGMEM.
6. Move to a board with more RAM if you still run out.

## Why it happens

An Uno has only 2 KB of RAM, and every text string in Serial.print() is copied into it. When RAM runs low the sketch can behave strangely or crash.

Wrap fixed text in the F() macro so it stays in flash, avoid the String class, and reduce large arrays.

```
Serial.println(F("Sensor ready"));   // text stays in flash, not RAM
```

Example sketch: change pins and values for your own wiring. It has not been bench-tested on your hardware.

## If you see this, do this

| You see | Do this |
| --- | --- |
| Resets at random after adding text | RAM nearly full. |
| Warning but works | Still risky. Free some RAM. |

## Related

[int overflow](https://roboticsengineering.in/fix/arduino-int-overflow-wrong-calculation/), [sketch too big](https://roboticsengineering.in/fix/arduino-sketch-too-big-for-flash-reduce-size/).

Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.

## Why this happens

An Arduino Uno has 2 KB of SRAM and 32 KB of flash. SRAM holds three things: global and static variables with the text strings you print, the heap used by String and malloc, and the stack used for function calls and local variables. The heap grows upward and the stack grows downward, and the compiler can only count the first part. The message appears when little is left after that count.

If the heap and the stack meet while the sketch runs, memory is overwritten silently. The result is odd behaviour, wrong values or resets with no error message. Text inside Serial.print is copied from flash into SRAM at start-up unless you wrap it in F(), so a sketch with many messages can use hundreds of bytes before it does anything.

## How to confirm the cause

- Read the compile output line that says how many bytes global variables use and how many remain for local variables, out of a maximum of 2048 on an Uno.
- Add a free-RAM function and print it at the start and inside loop(). A number that keeps falling means a leak or fragmentation, often from String.
- Add F() to the longest messages and compile again. The dynamic memory figure should fall by about the length of each string. If it does not, the text was not the problem.
- Comment out one library at a time and compile. Libraries with buffers show their cost this way.
- If free RAM is fine at start but the board still resets later, suspect a deep call chain or a large local array.

## Worked example

This free-RAM function is widely used on AVR boards. Compare the two readings.

```
int freeRam() {
  extern int __heap_start, *__brkval;
  int v;
  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}
void setup() {
  Serial.begin(9600);
  Serial.print(F("Free RAM: "));      // the label stays in flash
  Serial.println(freeRam());
}
void loop() {}
```

## Common mistakes

- Wrapping text in F() and passing it to a function that expects a normal char pointer. It needs a function that accepts the flash string type.
- Building text with String in loop(), which fragments the heap over hours.
- Declaring a big array inside a function, so it lands on the stack every call.
- Putting data in PROGMEM and then reading it like a normal variable. It must be read with the pgm_read functions.
- Ignoring the warning because the sketch still compiles.

## If this did not fix it

- Library buffers. A 128 by 64 monochrome OLED needs 128 x 64 / 8 = 1024 bytes for its frame buffer, which is half of an Uno’s RAM.
- Serial and other libraries keep their own receive and transmit buffers, so using several ports or libraries adds up.
- Recursion or deeply nested calls that use stack space only at certain moments. Simplify them or move to a board with more RAM.
