Impact of RAM density on suspend power consumption

RAM module capacity appears to have a significant effect on power draw during suspend.

For example, on my system (full specs in next post):

  • With 96GB (2x48GB) installed, suspend draws 1.13W and lasts 2.25 days
  • With 16GB (2x8GB) installed, suspend draws 0.33W and lasts 7.82 days

I previously assumed that RAM config had a negligible impact on battery life, and was surprised to find that a 48GB stick draws 10x more power than a 8GB stick in its low power self-refresh state (see table below). It’s a shame that RAM manufacturers don’t list their power consumption specs, but we can collect this information ourselves.

To calculate power consumed by RAM, run two suspend trials of the same duration, but remove a stick for one of the trials. The delta is the power consumption of one of the sticks.

Measurements in miliamps (mA):

RAM RAM Model Both populated One populated Per-stick Base
2x48GB-5600 CT2K48G56C46S5 73 44 29 15
2x8GB-4800 HMCG66MEBSA092N 21 18 3 15

Measurements in Watts (W):

RAM RAM Model Both populated One populated Per-stick Base
2x48GB-5600 CT2K48G56C46S5 1.130 0.681 0.449 0.232
2x8GB-4800 HMCG66MEBSA092N 0.325 0.279 0.046 0.232

Please help contribute additional entries by running this test on your machine with whatever RAM you happen to have on-hand. Here’s an example post with results in a format that will be easy to incorporate into the table. I’ll update and reorganize these tables as results are posted.

Testing procedure:

Suspending for at least an hour will help improve measurement accuracy. Make sure your laptop is not charging, and has enough juice to last for the duration of the test. Results will also be more reliable if there are no expansion cards other than USB-C, and no other devices are attached.

Linux

These commands should work on most Linux systems to compare charge before and after a suspend. Start with a quick 5-second test:

date
cat /sys/class/power_supply/BAT1/charge_now
sudo rtcwake -m mem -s 5
cat /sys/class/power_supply/BAT1/charge_now
date

Wrapping with date is optional for confirming timing.

Battery stats might be on a slightly different path, so you may need to change BAT1/charge_now to something like BAT0/energy_now. Note that the units may be different:

  • energy_now outputs microwatts (uW), divide by 1000000 for Watts (W).
  • charge_now outputs microamp-hours (uAh), divide by 1000 for milliamp-hours (mAh).

If that works, go for a full hour. Pasting the whole block should work now without interruption if you’ve already primed your shell with sudo from the above test.

date
cat /sys/class/power_supply/BAT1/charge_now
sudo rtcwake -m mem -s 3600
cat /sys/class/power_supply/BAT1/charge_now
date

You should see output like the following:

Fri Sep 13 06:20:08 PM PDT 2024
2484000
rtcwake: wakeup from "mem" using /dev/rtc0 at Sat Sep 14 02:20:09 2024
2411000
Fri Sep 13 07:20:09 PM PDT 2024

In this case, battery dropped from 2484000uAh to 2411000uAh, which is 73000uAh or 73mAh. This happened over one hour, so average current draw is simply 73mA. You can convert to mW by multiplying by the battery’s nominal voltage of 15.48V to get 1130mW or 1.13W.

Then remove a RAM stick and repeat the test. You should see lower power consumption. In my case, 44mA. This means that one stick draws 29mA (73mA - 44mA), and we can deduce that the base consumption excluding RAM is 15mA (44mA - 29mA).

AMD shortcut

If you’re on an AMD system, you can let the amd_s2idle.py script handle most of the above for you. For example, run:

sudo python amd_s2idle.py

Use defaults for everything, except the cycle duration, which you set to 3600 seconds (1 hour). Then the last line printed will be the total consumption, something like:

🔋 Battery BAT1 lost 73000 µAh (1.94%) [Average rate: 0.01A]

Note that the script may require a small typo fix for this to work.

Windows

I don’t know if there’s an equivalent test we could run on Windows, but feel free to share if you have ideas.


Related topics:

[TRACKING] Test results for standby battery use of Expansion Cards
I was failing to reproduce the 0.31W result on my system. My measurements were 3.6x higher at 1.13W. I figured something else must be up, so started investigating RAM’s contribution.

[Battery Life] Impact of RAM / memory configuration + extra data
This is a nice comparison of active power consumption for a variety of RAM configs, but does not explore the suspend use case. I was tempted to just post as a reply there, but figured it would be better to keep a separate topic focused on crowd-sourced measurements of RAM power consumption during suspend.

5 Likes

System:

  • Framework 13, AMD 7640U
  • BIOS 3.05
  • Fedora 40
  • WD Black SN850X 4GB
  • 4 USB-C expansion cards, with nothing plugged into them

RAM tests:

96GB-5600 2x48GB CT2K48G56C46S5
Both populated: 73mA
One populated: 44mA
1-hour tests

16GB-4800 2x8GB HMCG66MEBSA092N
Both populated: 21mA
One populated: 18mA
1-hour tests

2 Likes

I don’t think it’s fair to compare DDR4 vs DDR5 in terms of consumption. It should be same technology and same brand class.

Both RAM types tested so far are DDR5. I don’t think DDR4 would work at all in the laptop.

There is a small difference in transfer rate (4800 vs 5600 MT/s), but I also believe that shouldn’t make a difference in power consumption when suspended. I was doing a bit more digging into the datasheets for the memory ICs on the modules to check for their current draw while in self refresh, and the values are identical for 4800, 5600, and 6400 speeds. The speed only makes a difference in current draw for external transfers, such as a read or write.

IDK if that’s a common perspective, but it makes sense to me that it has a massive impact on suspend battery life. It’s presumably the most impactful thing.

RAM stays powered on in suspend otherwise it would wipe. So the more RAM you have, the more power you use to keep it from wiping.

I’m surprised it’s not more linear with 1 vs 2 sticks honestly.

“Negligible” was bad word choice on my part. My actual assumption was that there would be a sublinear penalty as capacity grew due to some economy of scale magic in the module design. So if you doubled capacity, power draw wouldn’t double too, and there wouldn’t be a noticeable enough downside to more RAM apart from affordability. If this was not the case, then surely a reduction in suspend time would be a more widely known and discussed caveat when deciding how much RAM to get. Maybe there’d even be some data and benchmarks. But in my research, I have only found speculative answers to this question, and even some false claims:

A 10x difference in power consumption between 8GB and 48GB modules was really surprising. I thought maybe power consumption would scale by number of ICs on the module. That would explain a 4x increase in this case (4 vs 16 ICs). And then it seemed even less likely that power consumption would scale directly with capacity, but that would only be a 6x difference (8 vs 48GB), and not 10x.

It seems that the 3GB ICs are actually drawing closer to 2x more power than the 2GB ones during self-refresh. In that case, I’d suspect a 32GB module to draw half the power of the 48GB module, despite only having a third less capacity. I’m curious to see the results of a test from someone with a 2x32GB kit.

On dual channel RAM, data is interleaved across the two modules, so they experience exactly the same usage.
And for the suspend use case, we should expect zero read/write usage on both sticks, and so the only power consumption would be from the full-chip refreshes. Now there is another fancy “partial array self refresh” (PASR) feature on some RAM ICs where the OS can specify which of [usually] 8 regions have data that needs refreshing, and so it is possible that RAM utilization before suspend could affect power consumption during suspend.

2 Likes

I did this test with my 12th gen when I got it. So DDR4 and 2x 16 GiB Crucial modules and again with 2x 8 GiB Crucial modules. Back then, it had actually no mensurable impact on suspend power consumption.

powercfg /sleepstudy gives you a full report of all sleep cycles and their power draw under Windows that can be used.
But I think Windows’ consumption might be more varied as Windows does some background work at times. So 1h would probably be to short for measuring with Windows.

Right, I guess this is s2idle isn’t it, as opposed to s2. I figured it would be linear because in s2 the cpu is effectively off, so the ram isn’t being read at all. So the power usage would be the refresh cycle only.

Since it’s s2idle, like you say it probably matters a lot how much RAM reading is happening in the background, which seems trickier to measure (actual reading, not free style usage).

1 Like

Including some notes on the process for finding expected power consumption by looking at the memory IC datasheets. These values are much more pessimistic than reality, but there are still some insights to gain. One conclusion is that increasing module capacity from 32GB to 48GB likely consumes 200% more standby power for only a 150% capacity boost. Looking forward to someone with a 64GB kit who can test this claim.

DDR4 32GB

We’ll first study a DDR4 datasheet, which has more relevant temperature-dependent data than the DDR5 datasheets.

The example part is a 32GB module with 16 2GB ICs.

There are three voltages rails, and we need to find the currents for each.

Default voltages are:

Vpp Vdd Vddq
DDR4 2.5 1.2 1.2
DDR5 1.8 1.1 1.1

The datasheet contains the currents during self-refresh. These are temperature-dependent, and we’ll consider values at 25C, which is the most likely environment for a suspended machine.

Note that these currents are unaffected by speed class. DDR4-2133 draws the same as DDR4-3200 during self refresh. This makes sense, since there’s no external I/O.

There’s no Iddq data, but it’s likely comparable to the other currents (based on DDR5 datasheets). So we’ll ignore it with the expectation that the true total may be 50% higher.

Wattage calculation:

Idd6a: 11 mA * 1.2 V = 13.2 mW
Ipp6x:  6 mA * 2.5 V = 15 mW
Iddq: Unknown
Total per IC: 28.3 mW
Total per module: 453 mW, 0.453 W 

0.453 W per module is believable, but it could be overly conservative, even without accounting for Iddq. I wouldn’t be surprised if real world tests achieve a smaller draw.

DDR5 32GB

Moving on to the equivalent 32GB DDR5 module, which has the same layout as the earlier DDR4 module with 16 2GB ICs. Test current definitions are on a separate datasheet.

Unfortunately, there’s no data for 25C consumption, and we only get worst-case numbers at 85C.

Idd6n: 110 mA * 1.1 V = 121 mW
Ipp6n:  15 mA * 1.8 V = 28 mW
Iddq6n: 25 mA * 1.1 V = 27.5 mW
Total per IC: 176.5 mW
Total per module at 85C: 2.8 W
Total per module at 25C: 0.59 W (see below for rationale)

The absurdly high result of 2.8 W is due to the high temperature test condition. To get a better estimate on what to expect at 25C, we can look back on the DDR4 datasheet and derive a temperature scaling factor for how consumption changes from 25C to 85C. It jumps from 11 mA to 55 mA, a 5x increase. This may not translate perfectly from DDR4 to DDR5, but it’s an educated guess. Applying that factor here drops 2.8 W to 0.59 W. That’s more reasonable, but probably still too high.

DDR5 48GB

And now for the 48GB DDR5 module. It’s the same as before, but the ICs are 3GB instead of 2GB.

Idd6n: 219 mA * 1.1 V = 240.9 mW
Ipp6n:  32 mA * 1.8 V = 57.6 mW
Iddq6n: 41 mA * 1.1 V = 45 mW
Total per IC: 343.5 mW
Total per module at 85C: 5.50 W
Total per module at 25C: 1.14 W

Two observations:

  • On-paper power draw is 2x higher for the 48GB module versus the 32GB module. I’d expect real-world draw to also be 2x.
  • The 1.14 W on-paper estimate is much higher than the 0.449 W measured during real-world testing of the 48GB module. We can use this mismatch to calculate a more realistic real-world estimate for the 32GB module at 0.23 W (instead of 0.59 W). That puts total consumption for a 64GB system at 0.70 W, providing a 3.65 day suspend duration.

I confirmed that my RAM module has hardware support this feature (according to the datasheet), and ran a quick test to try it out. I occupied 90% of available RAM with this command:

stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1 --vm-hang 0

Then ran a 1-hour suspend test. Power consumption was the same as my earlier tests at 5% occupation. This result suggests that the OS is not taking advantage of PASR, and letting the RAM module waste power refreshing unused banks. This is good news, as it means that there’s a potential software solution to further reduce standby power consumption.

After some additional digging, I found that there has been some work done to add this feature to Linux, but it has not been incorporated yet, and I haven’t seen any activity since 2012.

Patch Proposal
Slides
Commentary

1 Like

The temperature affects on power can vary significantly based on foundry process. The usage can also vary significantly, but that should be more comparable between types of RAM.

Out of curiosity is this the performance you are getting out of Fedora 40 out of the box or are you adding some tweaking there?
Those are downright impressive times for suspend especially when compared to the Intel based Framework laptops. (I can’t come anywhere close to either of your times. Maybe 20+ hours at best.)

1 Like

Agreed. I don’t have the details on what process nodes are used for those chips, but the 5x scaling trend from 25C → 85C holds true for what looks like a node bump on that DDR4 chip between RevB and RevE. It’s possible that some other design changes improved power efficiency by 27%, but a new process seems more likely. Of course, this trend could break down for other nodes.

25C 85C Multiplier
Rev B 15 mA 74 mA 4.93
Rev E 11 mA 53 mA 4.82
Power reduction 27% 30%

I’m not following what “usage” means here. Could you clarify?

Yep, this is stock Fedora 40 with s2idle suspend and no hibernation. I read that the AMD version beats Intel in runtime battery life, but I wouldn’t expect there to be any difference during suspend. If you share more details of your system setup, we may be able to figure out what’s responsible for all that power draw.

I was not as impressed with the 8-day suspend time, as my other laptop gets 14 days on a 57W battery, consuming only 170mW during suspend. Spoiled, I know. It’s a Lenovo x1 carbon gen 5 with 16GB. I don’t know how much of this difference is due to soldered LPDDR3 or S3 deep sleep. I’m still unsure what to expect for s2idle overhead versus S3, but will continue that discussion on Is Framework 13 AMD s2idle (modern standby) efficient enough?

2 Likes

Could you share which memory and nvme you are using?

Or any tools you use to diagnose what’s active during suspend?

I’m so using stock Fedora 40 with no hibernation. However my system can only suspend for about 1.5 days.

It sleeps through the night and just long enough to last until I get home after work.

I also am used to 14 day suspends (Dell XPS 13 Skylake). But 7+ days would enable me to use the Framework according to my natural browsing habits.

My system info is in the second post.
Tools and testing procedure are in the first post.

It would be illuminating if you would also share your memory config and the results of a power consumption test with one and two memory sticks installed (as described in the first post).

Thanks for this thorough analysis, @Miles_Frain!

It so happens that I have a 64 GB kit, so I did the measurements on my system.

Specs:

  • Framework 13, AMD 7840
  • BIOS 3.05
  • Opensuse Tumbleweed (Kernel 6.11.3)
  • Solidigm P44 Pro NVMe (2 TB)
  • Kingston Fury Impact 64GB-5600 (KF556S40IBK2-64)

For the expansion cards I tested two configurations:

Config 1:

  • 2 USB-C in the rear slots
  • USB-A front left with Yubikey attached
  • HDMI front right

Config 2:

  • No expansion cards at all

Each test was performed with the system in single user mode with the battery charged to 80% (the max set on my system in the BIOS) at the beginning of the test. And each test was performed twice, once with s2idle, once with rtcwake as per the description in the first post. Idle time was one hour, and the average current drained in mA is listed in the table.

Results for Config 1:
(results from the 10h idle test in parentheses - see EDIT below for details)

RAM rtcwake s2idle
Both populated 33 mA (32 mA) 33 mA
One populated 27 mA 28 mA
Per stick 6 mA (5 mA) 5 mA
Base (extrap.) 21 mA (22 mA) 23 mA

Results for Config 2:

RAM rtcwake s2idle
Both populated 27 mA 28 mA
One populated 23 mA 24 mA
Per stick 4 mA 4 mA
Base (extrap.) 19 mA 20 mA

Somehow, the power consumption of my 32 GB memory sticks seems to be much closer to your 8 GB sticks and quite a bit lower than what you find with your 48 GB. And my base consumption seems to be higher. That may be due to the SOC (7840 vs 7640).

EDIT:
I also did a longer test to see if 1h of sleep is sufficient to get results of a reasonable precision. This was done in Config 1, both RAM slots populated, setting the rtcwake timer to 10h.

10h: 320 mAh battery drain (32 mA average)
1h: 33 mAh battery drain (33 mA average)

So the results seem to be OK ± 1 mA, which corresponds to the resolution of the reporting of the current batter charge (which is to within 1 mAh). I updated the table with the results for Config 1 to include this measurement point.

EDIT2: typos everywhere…

4 Likes