Skip to content

Instantly share code, notes, and snippets.

@geerlingguy
Last active March 18, 2026 15:44
Show Gist options
  • Select an option

  • Save geerlingguy/91d4736afe9321cbfc1062165188dda4 to your computer and use it in GitHub Desktop.

Select an option

Save geerlingguy/91d4736afe9321cbfc1062165188dda4 to your computer and use it in GitHub Desktop.
Raspberry Pi CPU temperature and throttling test script
#!/bin/bash
# Raspberry Pi stress CPU temperature measurement script.
#
# Download this script (e.g. with wget) and give it execute permissions (chmod +x).
# Then run it with ./pi-cpu-stress.sh
#
# NOTE: In recent years, I've switched to using s-tui. See:
# https://github.com/amanusk/s-tui?tab=readme-ov-file#options
# Variables.
test_run=1
test_results_file="${HOME}/cpu_temp_$test_run.csv"
stress_length="10m"
# Verify stress-ng is installed.
if ! [ -x "$(command -v stress-ng)" ]; then
printf "Error: stress-ng not installed.\n"
printf "To install: sudo apt install -y stress-ng\n" >&2
exit 1
fi
printf "Logging temperature and throttling data to: $test_results_file\n"
# Start logging temperature data in the background.
while /bin/true; do
line=$(date | tr '\n' '\t')
# For Raspberry Pi.
line+=$(vcgencmd measure_temp | tr -d "temp=" | tr -d "'C" | tr '\n' '\t')
line+=$(vcgencmd get_throttled | tr -d "throttled=" | tr '\n' '\t')
line+=$(vcgencmd measure_clock arm | sed 's/^.*=//')
# For Intel/AMD/Ampere (might need tweaking).
# line+=$(sensors -A | sed -n '2{s/°.*//; s/[^+-]*//; p; q}' | tr '\n' '\t')
# line+=$(echo 'Not_Measured' | tr '\n' '\t')
# line+=$(awk '/MHz/{ temp+=$4; n++ } END{ printf("%f\n", temp/n) }' /proc/cpuinfo | tr '\n' '\t')
echo $line
echo $line >> $test_results_file
sleep 5
done &
# Store the logging pid.
PROC_ID=$!
# Stop the logging loop if script is interrupted or when it ends.
trap "kill $PROC_ID" EXIT
# After 5 minutes, run stress.
printf "Waiting 5 minutes for stable idle temperature...\n"
printf "Date °C Status CPU Clock\n"
sleep 300
printf "Beginning $stress_length stress test...\n"
stress-ng -c 4 --timeout $stress_length
# Keep logging for 5 more minutes.
printf "Waiting 5 minutes to return to idle temperature...\n"
sleep 300
printf "Test complete.\n"
@pyro12

pyro12 commented Jul 23, 2021

Copy link
Copy Markdown

Great little script! I'm trying to figure out why HTML5 streaming is disappointing on my Pi4b and I thought maybe throttling was the issue. I ran this and temps never report above 71 so I think I'm good, but I also found this: and I'm unclear on whether your script is logging CPU or GPU temps.... or if we can expect them to be pretty much the same...

If that link is correct, you're logging GPU temps and to also log CPU temp

echo temp=$((cat /sys/class/thermal/thermal_zone0/temp/1000)).0\'C | tr -d "temp=" | tr -d "'C" | tr '\n' '\t' >> $test_results_file;

needs to be added.

@geerlingguy

Copy link
Copy Markdown
Author

@pyro12 - According to the Pi's documentation, measure_temp "Returns the temperature of the SoC as measured by the on-board temperature sensor." — that seems to be the only reading that really matters for throttling (it's the SoC temp). Are you seeing different numbers when checking thermal_zone0?

@pyro12

pyro12 commented Jul 31, 2021

Copy link
Copy Markdown

@geerlingguy - Nope. I ran

#!/bin/bash
while true 
do
vcgencmd measure_temp | tr -d "temp=" | tr -d "'C" | tr '\n' '\t'
echo temp=$((`cat /sys/class/thermal/thermal_zone0/temp`/1000)).0\'C
sleep 10
done

via SSH and tried various uses of stress-ng and glxgears and the biggest difference I saw was 1.4 C. A curiousity, but I don't think relevant...

Thanks for helping me understand!

@geerlingguy

Copy link
Copy Markdown
Author

Weird! I'm surprised there would be that much of a difference. And now I'm wondering if there are multiple temperature sensors in the SoC :)

@yoyojacky

yoyojacky commented Nov 10, 2023

Copy link
Copy Markdown

I am using following script to record temperature :

from  gpiozero import CPUTemperature
from time import sleep, strftime, time

cpu = CPUTemperature()
count=1200      # 20 minutes
with open("/home/pi/temp_log.csv", "a") as  log:
    while True:
        temp = cpu.temperature
         log.write("{0},{1}".format(strftime("%Y-%m-%d %H:%M:%S"), str(temp)))
         sleep(1)
         count -= 1
         if count == 0:
             break

and using sysbench in a loop:

#!/bin/bash
while true; 
do 
     sysbench --test=cpu --cpu-max-prime=20000 --threads=4 run 
     sleep 0.1
done 

and it works fine.

@yoyojacky

yoyojacky commented Nov 10, 2023

Copy link
Copy Markdown

stess_temp
stress-temp-complete

@yoyojacky

Copy link
Copy Markdown

Question: how did you generated the images from the logging data? Is there any nice script for that?

maybe it can be plot by using matplotlib library.

@willipi72

willipi72 commented Jun 12, 2024

Copy link
Copy Markdown

For those like me that absolutely are newbies with Linux and Pi, this is the command to download the latest version of this file from the CLI:

curl -L https://gist.github.com/geerlingguy/91d4736afe9321cbfc1062165188dda4/raw/ -o _filename.extension_

@geerlingguy

Copy link
Copy Markdown
Author

I updated the script today to output the lines to screen before they're written to the file (helps to also see if the Pi locked up since it will stop printing data). lmk if you'd like that to be a flag so it can be disabled (like -q for quiet).

@yoyojacky

Copy link
Copy Markdown

I updated the script today to output the lines to screen before they're written to the file (helps to also see if the Pi locked up since it will stop printing data). lmk if you'd like that to be a flag so it can be disabled (like -q for quiet).

Wow, that's cool~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment