In 2020, I worked with an intern to characterize SD power characteristics (view the archive). As my colleagues and I embark on a mass deployment of new devices in 2025, it is time to revisit the perennial question: what SD card is best?
Specifically, what SD card has the lowest current draw in an Arduino-based, battery-powered system?
The Setup
I’m using a Joulescope JS220 with a custom battery breakout module to monitor current. The end device is an Adafruit Feather M0 Adalogger (ARM architecture).
I didn’t want to isolate the 3.3V line because the setup above is what we use in practice; also, the SD card is part of a system with potential current draw (or leaks) on all lines, so it’s not as easy as breaking the VDD/3.3V line.
Here’s a bullet-point breakdown of the test in my SD Low Power GitHub repository:
- Initial Setup:
- LED turned off
- SD Operations:
- Initialize card (CS pin 4)
- Write 512 bytes of 0xFF to test.txt
- Close file
- Call SD.end()
- Enter infinite loop
5s delays for power measurements separate each operation.
An identical version of the SD_Test.ino exists using SdFat library. I have not performed that testing yet, as that library appears to be unsupported in the future.
Measuring Current
I took one baseline (i.e., “empty”) measurement without an SD card. For others, I placed the SD card in and then coordinated the Arduino reset with the recording of the Joulescope. The five important measurements:
- Card Insertion (setup): current draw from the card simply being present.
- Begin Statement: current draw from SD.begin() function.
- Write File: current draw from testFile.write(); 512 bytes of 0xFF.
- Closed File (idle): current draw after the file was written and closed.
- SD End: current draw after SD.end().
Results
Before we look at these data, I want to remind you that all values are presented relative to the baseline recording with no SD card (empty). This should, theoretically, account for any processor-level changes in current related to the internal SPI or SD peripherals.
Card | Setup | SD.begin() | testFile.write() | testFile.close() | SD.end() |
---|---|---|---|---|---|
Empty | 11.9421 | 8.9681 | 8.9681 | 11.8865 | 8.5881 |
Samsung Pro Endurance 32GB | 12.3945 | 76.3790 | 48.2343 | 11.9775 | 8.6790 |
Lexar Micro V10 32GB | 12.9316 | 62.4502 | 53.8375 | 11.9991 | 8.6981 |
Sandisk Industrial 8GB | 12.7267 | 36.0426 | 26.0830 | 12.1328 | 8.8423 |
Sandisk Ultra 16GB | 12.9534 | 35.0439 | 23.9956 | 12.1368 | 8.8632 |
Sandisk Edge 8GB | 13.6512 | 34.3109 | 21.1517 | 12.6336 | 9.3367 |
Sandisk Outdoors FHD 32GB | 13.2205 | 38.1557 | 23.3340 | 12.3638 | 9.1094 |
MicroCenter 10 HCI 32GB | 12.9129 | 30.6266 | 27.5550 | 12.0645 | 8.7580 |
Sandisk Ultra Plus 32GB | 26.0227 | 53.5163 | 40.5740 | 12.3491 | 9.0257 |
Sandisk Max Endurance 32GB | 26.5185 | 56.3599 | 46.2154 | 12.4668 | 9.1421 |
Some SD cards will hang in a high-power state after SD.begin() is called until the first file is written (see plot above). This was true for seven of the nine SD cards I tested, and I noted this in the Excel Spreadsheet’s “begin to write sleep?” column.
Plots
ESP32-S3 Specifics
I generally found the same current draw and overall consumption patterns using the ESP32-S3, except that SD.end() does not enter a lower power state: the contrary! SD.end() on the ESP32-S3 increases the current beyond all other conditions. We’ll look at this in the next section.
Addressing the Begin-to-Write Current
As mentioned above, most SD cards will not immediately enter their idle state until the first file is written. The only cards that did enter idle were the two with the highest insertion current. Since data logging applications might not write a file right away, I investigated non-altering methods of getting to idle (e.g., creating the least amount of overhead).
As it turns out, and only on the ESP32-S3, we can simply check if a file exists to get to idle.
For projects that do not immediately write a file with the ESP32 architecture, my suggestion is to follow this procedure:
- Call
SD.begin();
at boot (as you likely already do). - Immediately call
SD.exists("/x.txt");
Interestingly, this does not work on the Adalogger M0 (ARM architecture)—you must write a file. You can also appreciate how SD.end() behaves significantly differently between the ESP32 (above) and ARM (below) architectures.
The Heat Matrix
I wanted to view these data together to help guide decision-making. Below are all our analyses (rows) against all the SD cards (columns).
Conclusion
Some of these data could be deceiving; for example, how often are you inserting an SD card and not calling begin()? Hopefully, never, but if you do that with a Sandisk Max Endurance 32GB, it will sit there and draw 10mA!
What we probably care most about is the idling current (e.g., between writes). If your goal is to save power between writes, this is the breakdown (best to worst):
- Samsung Pro Endurance 32GB – 91µA
- Lexar Micro V10 32GB – 113µA
- MicroCenter 10 HCI 32GB – 178µA
- Sandisk Industrial 8GB – 246µA
- Sandisk Ultra 16GB – 250µA
- Sandisk Ultra Plus 32GB – 463µA
- Sandisk Outdoors FHD 32GB – 477µA
- Sandisk Max Endurance 32GB – 580µA
- Sandisk Edge 8GB – 747µA
There are mixed reviews concerning using a P-FET or other strategies for turning off SD cards during operation. These methods potentially introduce undefined behavior. If you decide to power down an SD card, ensure all files are closed and you call the proper ending and beginning functions. You must test this entirely; in most cases, eating the idle current from an SD card is the most robust (albeit compromising) solution.
Correlating Idle and Write Current
There’s an interesting effect of optimizing for the idle period: you might pay for it during file writes. The inverse correlation is not perfect but is trending.
Looking closely, you’ll find that the two SD cards idling with the least current draw the most during writing. Your decision depends on how often you write to the SD card and how large those files will be.
My Recommendation
The SD cards in the bottom-left of the scatter plot demonstrate the best tradeoff between idle and write current:
- Sandisk Ultra 16GB (up arrow, turquoise)
- Sandisk Industrial 8GB (diamond, light blue)
- MicroCenter 10 HCI 32B (left arrow, yellow)
The MicroCenter 10 HCI 32GB is a great compromise, and I was lucky enough to procure it locally for this test. Although it comes in “value” packs, the individual cards are currently on sale for $3.99, making them a considerable value. Happy data logging.
NOTE: I found that the MicroCenter cards needed to be reformatted to work with the ESP32 SD Library (on MacOS: Disk Utility > Select SD > Erase > MS-DOS (FAT)
).
View all the files from this post on GitHub.