Learn

Arduino "Low memory available, stability problems may occur", and "Sketch too big"

Beginner

Or see every lesson.

  • 455parts on the bench
  • 43boards running now
  • 1.00xreal time, on every board
Arduino Uno: a knob on A0, printedlive0.000 s 0.00x
Click to open it in the editor
Open it, change a line and press Run: the build tab shows how much flash and RAM the sketch uses.

After every build the Arduino IDE prints two lines: how much of the flash the program takes and how much of the RAM its global variables take. When the RAM line passes about three quarters, a third line appears: "Low memory available, stability problems may occur." It is a warning, not an error. The sketch still uploads. Whether it then works depends on how much RAM it needs while it runs, which the compiler cannot know.

Mokxi’s build tab prints the same lines, under the same rule. The circuit above reads a knob and prints it; open it, change any line and press Run, and the build tab shows its two lines. Every number below came from a sketch built with the editor’s compiler for an Uno. Mokxi’s compiler and core are not the Arduino IDE’s, so the IDE gives slightly different numbers for the same sketch, and the page says where the difference matters.

What the two lines mean

Flash, "program storage space", holds the program itself and anything marked to stay there. RAM, "dynamic memory", holds every global and static variable, the text your sketch prints unless you move it, and, while the sketch runs, the stack: each function call’s local variables and return address. An Uno has 2,048 bytes of RAM. That is not much: one 1600-byte buffer is most of it.

A blink sketch built for an Uno in Mokxi reports "Sketch uses 1,646 bytes (5%) of program storage space. Maximum is 32,768 bytes." and "Global variables use 142 bytes (7%) of dynamic memory, leaving 1,906 bytes for local variables. Maximum is 2,048 bytes." The IDE says 32,256 for an Uno’s flash, because the bootloader keeps the last 512 bytes; Mokxi counts the whole chip. A Mega has more room: Mokxi reports a maximum of 262,144 bytes of flash and 8,192 bytes of RAM for it.

When the warning appears

We built a sketch with one global char buffer[] of different sizes. At 1200 bytes the build reported "Global variables use 1,370 bytes (67%) of dynamic memory, leaving 678 bytes for local variables" and no warning. At 1400 bytes it reported 1,570 bytes (77%), "leaving 478 bytes for local variables", and then "Low memory available, stability problems may occur." At 2000 bytes it did not build at all: the globals no longer fit, and the build says global variables do not fit in the 2 KB SRAM.

The warning is a rule of thumb. The IDE prints it past three quarters of the RAM, and Mokxi does the same, and also when what is left is smaller than the room its runtime keeps for the stack. A sketch at 80% with shallow functions can run for years; a sketch at 70% with a deep recursion or a large local array can crash at once.

What "stability problems" look like

The stack grows down from the top of the RAM toward the globals, and nothing stops it when it gets there. It writes over whatever variables are in the way and the sketch carries on with the damage. No error is printed and nothing resets. That is why the problems look random: a value changes by itself, a string grows garbage on the end, or the board resets when one rarely used function is called.

This sketch fills a 1734-byte global buffer with the letter A, calls a function that keeps 64 bytes of locals and calls itself, then counts how much of the buffer is no longer A. The build reported 1,946 bytes (95%), "leaving 102 bytes for local variables", and the warning. With the function called three levels deep, 48 bytes of the buffer had changed. Five levels deep, 188 bytes had. One or two levels deep, nothing had, and the sketch ran normally every way, printing its results without a sign of trouble.

The stack running into a global, counted
char buffer[1734];

int depth(int n) {
  char local[64];
  memset(local, n, sizeof(local));
  if (n == 0) return local[0];
  return depth(n - 1) + local[63];
}

void setup() {
  Serial.begin(9600);
  memset(buffer, 'A', sizeof(buffer));
  Serial.println(depth(5));
  int changed = 0;
  for (int i = 0; i < (int)sizeof(buffer); i++) {
    if (buffer[i] != 'A') changed++;
  }
  Serial.print("bytes of buffer changed: ");
  Serial.println(changed);
}

void loop() {
}

"Sketch too big": the flash is full

The flash has a hard limit too. The Arduino IDE stops with "Sketch too big" when the program does not fit, and there is no warning first. In Mokxi, a sketch with a 40,000-byte table in flash fails with firmware does not fit in the 32 KB flash, and the build tab adds a plain sentence: the program is bigger than the 32 KB of flash this board has, the same limit a real one has.

The fixes are the usual ones: remove libraries and code the sketch no longer uses, make big tables smaller, or choose a board with more room. A library pulled in for one function can cost several kilobytes, so check what each #include brings.

Fixes that free RAM

Make buffers the size you need, not the size you might need. Then move tables that never change into flash with PROGMEM, and read them back with pgm_read_byte(). A 1600-byte const byte table built for an Uno took 1,786 bytes (87%) of RAM and brought the warning; the same table declared PROGMEM took 186 bytes (9%), for 6 more bytes of flash, and printed the same values.

Text you print is the other big user. In the Arduino IDE, Serial.println(F("...")) keeps the text in flash and saves its RAM, and on a sketch with many messages it is often the whole fix. Mokxi’s F() does not do this: it leaves the text where it was, so twenty long lines built with and without F() both reported 1,800 bytes (88%) of RAM here. Use F() all the same, because the board on your desk will need it; just do not expect Mokxi’s number to drop when you add it.

Last, the String class makes and frees copies on the heap, which sits between the globals and the stack, and over hours that can leave the free RAM in pieces too small to use. On a board with 2 KB, fixed char arrays are the safer choice for anything that runs a long time. If the sketch still does not fit, a Mega, with four times the RAM, or an ESP32 is the honest fix.

Questions

Is "Low memory available, stability problems may occur" an error?

No. It is a warning that the global variables use more than about three quarters of the RAM. The sketch builds and uploads. It may still run fine, or it may misbehave when the stack needs more room than is left.

How much memory does an Arduino Uno have?

32 KB of flash for the program, of which the Arduino IDE offers 32,256 bytes because the bootloader keeps 512, and 2,048 bytes of RAM for variables and the stack.

What does "Sketch too big" mean?

The program does not fit in the board’s flash. Remove unused libraries and code, shrink large tables, or use a board with more flash, such as a Mega.

How do I reduce RAM use on an Arduino?

Shrink buffers, put constant tables in PROGMEM, wrap printed text in F() on a real board, avoid String in long-running sketches, and keep large arrays out of functions that call themselves.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.