The Direct Answer: Setting LittleFS Partition Size
To set the partition size of LittleFS in the Arduino IDE for an ESP32, you do not define the size in your C++ code. Instead, you configure it via the IDE's board settings or a custom partition table. For standard setups, navigate to Tools > Partition Scheme and select a predefined layout (e.g., 'Default 4MB with spiffs'). Despite the menu saying 'spiffs', modern ESP32 Arduino Cores (v2.x and v3.x) map this partition subtype to LittleFS when you use the LittleFS.h library.
If you need an exact, non-standard size, you must create a custom partitions.csv file and place it in your sketch folder. The Arduino IDE will automatically detect and compile this CSV into the binary, overriding the Tools menu selection.
#include <SPIFFS.h> to #include <LittleFS.h> and update your SPIFFS.begin() calls to LittleFS.begin(). The partition layout in the flash memory remains compatible.
Required Hardware and Pin Mapping
This guide targets the ubiquitous ESP32-WROOM-32 DevKit V1 (4MB Flash). The principles apply equally to the ESP32-S3-WROOM-1 (8MB Flash), though your partition scheme dropdown will offer larger byte allocations.
Parts List
- MCU: ESP32-WROOM-32 DevKit V1 (4MB SPI Flash) or ESP32-S3-WROOM-1 (8MB)
- Programmer: USB-C or Micro-USB data cable (ensure it is not a charge-only cable)
- Input: Momentary pushbutton (for manual format trigger)
- Indicator: 5mm LED with 330Ω current-limiting resistor
Control & Indicator Pin Mapping
While the internal SPI flash uses GPIOs 6-11 (which are internal and not broken out on the DevKit), we map external pins for user interaction and status feedback in our build.
| Component | ESP32 GPIO | Direction | Notes |
|---|---|---|---|
| Onboard/Status LED | GPIO 2 | OUTPUT | Active HIGH on most DevKit V1 boards |
| Format Trigger Button | GPIO 0 | INPUT_PULLUP | Shared with BOOT pin; active LOW |
| Internal Flash CLK | GPIO 6 | N/A | Internal SPI (Not accessible) |
| Internal Flash CS | GPIO 11 | N/A | Internal SPI (Not accessible) |
Step-by-Step: Configuring and Mounting LittleFS
- Install the ESP32 Board Package: Ensure you are using ESP32 Core v2.0.0 or newer (v3.x preferred for 2026 builds) via the Boards Manager. LittleFS is native to these cores.
- Select Your Board: Go to Tools > Board and select 'ESP32 Dev Module'.
- Set the Flash Size: Go to Tools > Flash Size and select '4MB (32Mb)'. If this does not match your physical chip, the partition table will corrupt the firmware.
- Choose the Partition Scheme: Go to Tools > Partition Scheme. For a 4MB board, select 'Huge APP (3MB No OTA/1MB SPIFFS)' to maximize LittleFS space while keeping a large app partition, or 'Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)' if you need Over-The-Air updates.
- Upload the Sketch: Compile and upload the code provided below. The partition table is flashed alongside the bootloader and application binary.
Complete Arduino Code with Error Handling
This code targets the ESP32 Dev Module. It initializes LittleFS, checks for a format button press on GPIO 0, and writes/reads a test file. Pin definitions and robust error handling are included.
#include <Arduino.h>
#include <FS.h>
#include <LittleFS.h>
// --- Pin Definitions ---
constexpr uint8_t PIN_LED_STATUS = 2; // Onboard LED on most DevKit V1s
constexpr uint8_t PIN_BTN_FORMAT = 0; // BOOT button on DevKit V1
// --- Configuration ---
const char* TEST_FILE = "/config.txt";
const unsigned long BAUD_RATE = 115200;
void setup() {
Serial.begin(BAUD_RATE);
pinMode(PIN_LED_STATUS, OUTPUT);
pinMode(PIN_BTN_FORMAT, INPUT_PULLUP);
digitalWrite(PIN_LED_STATUS, HIGH);
delay(1000);
Serial.println("\n--- LittleFS Partition Setup ---");
// 1. Check if user wants to format (Button held on boot)
if (digitalRead(PIN_BTN_FORMAT) == LOW) {
Serial.println("Format button pressed. Formatting LittleFS...");
if (LittleFS.format()) {
Serial.println("LittleFS formatted successfully.");
} else {
Serial.println("ERROR: LittleFS format failed!");
}
}
// 2. Mount LittleFS with auto-format fallback
// The 'true' parameter tells LittleFS to format the partition if mount fails
if (!LittleFS.begin(true)) {
Serial.println("FATAL: LittleFS Mount Failed. Check partition scheme.");
// Blink LED rapidly to indicate fatal filesystem error
while(true) {
digitalWrite(PIN_LED_STATUS, !digitalRead(PIN_LED_STATUS));
delay(100);
}
}
// 3. Output Partition Metrics
Serial.printf("LittleFS Mounted. Total bytes: %u\n", LittleFS.totalBytes());
Serial.printf("Used bytes: %u\n", LittleFS.usedBytes());
Serial.printf("Free bytes: %u\n", LittleFS.totalBytes() - LittleFS.usedBytes());
// 4. File I/O Test with Error Handling
File file = LittleFS.open(TEST_FILE, FILE_APPEND);
if (!file) {
Serial.println("ERROR: Failed to open file for appending.");
return;
}
if (file.printf("Boot timestamp: %lu\n", millis())) {
Serial.println("Data appended successfully.");
} else {
Serial.println("ERROR: File write failed.");
}
file.close();
digitalWrite(PIN_LED_STATUS, LOW);
}
void loop() {
// Main application logic goes here
delay(1000);
}
Troubleshooting: Exact Errors and Ranked Causes
When working with flash partitions, the ESP32 bootloader and LittleFS library will throw specific errors if the IDE settings mismatch the physical hardware. Here are the exact error strings and how to fix them.
First Three Things to Check When It Fails
- Flash Size Mismatch: Verify the physical chip on your ESP32 module. If it says 'ESP32-WROOM-32D', it likely has 4MB. If your IDE is set to 8MB or 16MB, the partition table will point to non-existent silicon, causing a mount failure.
- Missing 'spiffs' Subtype: Ensure your selected Partition Scheme actually includes a data partition. Schemes like 'No OTA (2MB APP/2MB SPIFFS)' work, but 'Minimal (1.3MB APP/No SPIFFS)' will fail because there is no partition allocated for the filesystem.
- Corrupted Filesystem Header: If you previously flashed SPIFFS or a different partition layout, the LittleFS header will be invalid. You must pass
truetoLittleFS.begin(true)to force a format, or use the ESP32 Flash Download Tool to erase the entire chip.
Error: 'E (xxx) esp_littlefs: littlefs_mount: mount failed'
Ranked Causes:
- Unformatted Partition: The partition exists but lacks a LittleFS superblock. Fix: Use
LittleFS.begin(true)to format on first boot. - Partition Overlap: A custom
partitions.csvhas overlapping offsets. Fix: Recalculate hex offsets ensuring App and Data partitions do not collide.
Error: 'LittleFS mount failed' (Generic Arduino Wrapper)
Ranked Causes:
- Wrong Board Selected: You selected 'ESP32-S3 Dev Module' but are using an ESP32-WROOM-32. Fix: Match the IDE board definition to the physical silicon.
- Flash Frequency Too High: Some clone boards fail at 80MHz QIO. Fix: Go to Tools > Flash Mode and drop to 'DIO' or 'QIO at 40MHz'.
Extending and Simplifying Your Build
If the predefined Arduino IDE partition schemes do not fit your exact byte requirements, you can extend your build by defining a custom partition table.
How to Use a Custom partitions.csv
- Create a file named exactly
partitions.csvin the same folder as your.inosketch file. - Define your layout using the Espressif Partition Table format. Ensure the subtype for your data partition is
spiffs(which LittleFS hooks into). - Select 'Custom' or any scheme in the IDE menu; the IDE will prioritize the local CSV file during compilation.
Example 4MB Custom CSV (2MB App, 1.9MB LittleFS):
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x200000,
littlefs, data, spiffs, 0x210000,0x1E0000,
Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed).
To simplify the build for production, remove the format button logic and rely on Over-The-Air (OTA) updates. When pushing OTA updates, the LittleFS partition is preserved, meaning your device configuration and logged data survive firmware flashes without requiring a physical USB connection.
Frequently Asked Questions
How do I set a custom LittleFS partition size not listed in the Arduino menu?
You must create a partitions.csv file in your sketch directory. The Arduino ESP32 core automatically detects this file during compilation and overrides the dropdown menu selection. Define your partitions with exact hex offsets and sizes, ensuring the data partition uses the spiffs subtype so the LittleFS library can mount it. You can verify the compiled layout by checking the build output logs in the Arduino IDE console.
Why does my ESP32 boot loop after changing the partition scheme?
A boot loop immediately after changing the partition scheme usually indicates a flash size mismatch or an overlapping partition table. If your IDE is set to '4MB Flash' but you selected a partition scheme designed for 8MB or 16MB, the bootloader will attempt to map memory addresses that do not physically exist on the silicon. Always verify the physical flash chip size on your module's metal shield (e.g., 'ESP32-WROOM-32' is 4MB, 'ESP32-S3-WROOM-1-N8' is 8MB) and match it in Tools > Flash Size.
Can I use LittleFS and SPIFFS on the same ESP32 board simultaneously?
Technically, you can define two separate data partitions in a custom CSV (one formatted as LittleFS, one as SPIFFS), but it is highly discouraged. Both libraries consume significant RAM for their cache buffers, and managing two distinct filesystems complicates wear-leveling and power-fail recovery. Since the Arduino ESP32 LittleFS library is a drop-in replacement that handles power-loss gracefully, the best practice is to migrate entirely to LittleFS and reclaim the flash space for your application or a single, larger data partition.






