Fix ESP32 “region `dram0_0_seg' overflowed by … bytes”
Global and static variables don’t fit the ESP32’s static RAM. Shrink big global arrays, allocate large buffers at runtime with malloc/PSRAM, or move constants to flash.
Community draft — report a mistake
What you see
ld.exe: CameraLogger.ino.elf section `.dram0.bss' will not fit in region `dram0_0_seg'
ld.exe: DRAM segment data does not fit.
ld.exe: DRAM segment data does not fit.
ld.exe: region `dram0_0_seg' overflowed by 97544 bytes
collect2.exe: error: ld returned 1 exit status
exit status 1
Compilation error: exit status 1ld.exe: CameraLogger.ino.elf section `.dram0.bss' will not fit in region `dram0_0_seg' ld.exe: DRAM segment data does not fit. ld.exe: DRAM segment data does not fit. ld.exe: region `dram0_0_seg' overflowed by 97544 bytes collect2.exe: error: ld returned 1 exit status exit status 1 Compilation error: exit status 1
The linker places every global and static variable into a fixed region of RAM called dram0_0_seg. If they add up to more than that region, the build fails with the exact overflow in bytes — before anything is uploaded.
// Before: 200 KB static array -> overflow
// uint8_t frame[200000];
uint8_t* frame = nullptr;
void setup() {
Serial.begin(115200);
frame = (uint8_t*)(psramFound() ? ps_malloc(200000) : malloc(200000));
if (!frame) Serial.println("Not enough RAM for frame buffer");
}Quick fix — try in order
- 1
Find the big global
Look for global arrays like
uint8_t frame[200000];orchar log[50000];. Statically allocated data on a classic ESP32 must fit in roughly 160–180 KB, shared with Wi-Fi and the core. - 2
Allocate large buffers at runtime
uint8_t* frame = (uint8_t*)malloc(200000);in setup() uses the heap, which can use RAM regions that static data can’t. Check the pointer isn’t NULL. - 3
Use PSRAM if the board has it
ESP32-CAM, WROVER and many S3 modules have 2–8 MB PSRAM. Enable it (Tools → PSRAM: Enabled) and use
ps_malloc(size)for images and big tables. - 4
Put constant tables in flash
Mark fonts, lookup tables and images
const(e.g.const uint8_t logo[] = {…};). Const data stays in flash and doesn’t use DRAM. - 5
Read which section overflowed
.dram0.bss= zero-initialised globals;.dram0.data= globals with initial values. The overflow number is how much to trim.
Why it happens
The ESP32 has 520 KB of RAM — why so little?
The 520 KB is split into instruction RAM, data RAM, cache and memory reserved by Wi-Fi/Bluetooth. Static (compile-time) data can only use part of the data RAM; the heap gets the rest.
Same code fits on an ESP32-S3
Different chips have different memory maps. The S3 and C3 have more contiguous data RAM than the original ESP32.
Variant: section `.iram0.text' will not fit in region `iram0_0_seg'
Too much code marked IRAM_ATTR. Only interrupt handlers and the functions they call need it.
Board-specific notes
ESP32-CAM: Camera frame buffers belong in PSRAM, set via config.fb_location = CAMERA_FB_IN_PSRAM — see PSRAM not found if it isn’t detected.
Related: Too much code rather than data: Sketch too big.
Did this fix it?
Thanks — that helps us keep this page right.