Last active
December 16, 2025 07:14
-
-
Save Bugaddr/04729e35e9dedda3f90cfc17a11c3037 to your computer and use it in GitHub Desktop.
Script to verify cpu thermal throttling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # --- CONFIGURATION --- | |
| DURATION=60 # How long to run the stress test (in seconds) | |
| SAFE_TEMP_LIMIT=98 # Emergency cutoff temperature (Celsius) | |
| PASTE_SPIKE_THRESHOLD=25 # If temp jumps this much in 2 seconds, suspect bad paste | |
| THROTTLE_THRESHOLD_PCT=85 # If CPU speed drops below 85% of max, suspect throttling | |
| # Colors | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| CYAN='\033[0;36m' | |
| NC='\033[0m' # No Color | |
| echo -e "${CYAN}=== CPU Thermal Health & Throttling Detector (Arch Linux) ===${NC}" | |
| # 1. Check Dependencies | |
| if ! command -v stress &> /dev/null || ! command -v sensors &> /dev/null || ! command -v bc &> /dev/null; then | |
| echo -e "${RED}Error: Missing dependencies.${NC}" | |
| echo "Please run: sudo pacman -S stress lm_sensors bc" | |
| exit 1 | |
| fi | |
| # 2. Get CPU Info | |
| CPU_MODEL=$(grep -m1 "model name" /proc/cpuinfo | cut -d: -f2 | xargs) | |
| MAX_FREQ=$(lscpu | grep "CPU max MHz" | awk '{print $4}' | cut -d. -f1) | |
| # Fallback for Max Freq if lscpu fails | |
| if [ -z "$MAX_FREQ" ]; then | |
| MAX_FREQ=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq) | |
| MAX_FREQ=$((MAX_FREQ / 1000)) | |
| fi | |
| echo -e "CPU Model: $CPU_MODEL" | |
| echo -e "Max Rated Speed: ${YELLOW}${MAX_FREQ} MHz${NC}" | |
| echo "------------------------------------------------------------" | |
| # Function to get current max core temp | |
| get_temp() { | |
| sensors | grep -E 'Core|Package|Tctl' | awk '{print $3}' | grep -o '[0-9.]*' | sort -nr | head -n1 | cut -d. -f1 | |
| } | |
| # Function to get current avg CPU freq | |
| get_freq() { | |
| grep "MHz" /proc/cpuinfo | awk '{sum+=$4} END {print sum/NR}' | cut -d. -f1 | |
| } | |
| # 3. Phase 1: Idle Check | |
| echo -e "${CYAN}Phase 1: Measuring Idle Baseline (5 seconds)...${NC}" | |
| sleep 2 | |
| IDLE_TEMP=$(get_temp) | |
| echo -e "Idle Temperature: ${GREEN}${IDLE_TEMP}°C${NC}" | |
| if [ "$IDLE_TEMP" -gt 55 ]; then | |
| echo -e "${YELLOW}WARNING: High idle temp detected! (Possible bad airflow or background load)${NC}" | |
| fi | |
| # 4. Phase 2: Stress Test | |
| echo "------------------------------------------------------------" | |
| echo -e "${CYAN}Phase 2: Starting Stress Test (Load for ${DURATION}s)...${NC}" | |
| echo "Use Ctrl+C to abort immediately." | |
| # Run stress in background | |
| stress --cpu $(nproc) --timeout $DURATION & | |
| STRESS_PID=$! | |
| # Monitoring Loop | |
| START_TIME=$(date +%s) | |
| SPIKE_DETECTED=false | |
| THROTTLING_DETECTED=false | |
| MAX_TEMP_REACHED=0 | |
| # Check initial spike after 2 seconds | |
| sleep 2 | |
| CURRENT_TEMP=$(get_temp) | |
| TEMP_RISE=$((CURRENT_TEMP - IDLE_TEMP)) | |
| if [ "$TEMP_RISE" -ge "$PASTE_SPIKE_THRESHOLD" ]; then | |
| SPIKE_DETECTED=true | |
| echo -e "${RED}ALERT: Instant Temperature Spike Detected! (+${TEMP_RISE}°C in 2s)${NC}" | |
| fi | |
| while ps -p $STRESS_PID > /dev/null; do | |
| CUR_TEMP=$(get_temp) | |
| CUR_FREQ=$(get_freq) | |
| # Update Max Temp | |
| if [ "$CUR_TEMP" -gt "$MAX_TEMP_REACHED" ]; then | |
| MAX_TEMP_REACHED=$CUR_TEMP | |
| fi | |
| # Safety Cutoff | |
| if [ "$CUR_TEMP" -ge "$SAFE_TEMP_LIMIT" ]; then | |
| echo -e "${RED}EMERGENCY: Temperature reached ${CUR_TEMP}°C. Stopping test to prevent damage.${NC}" | |
| kill $STRESS_PID | |
| wait $STRESS_PID 2>/dev/null | |
| break | |
| fi | |
| # Check Throttling (If temp is high AND freq drops below threshold) | |
| FREQ_THRESHOLD=$(echo "$MAX_FREQ * $THROTTLE_THRESHOLD_PCT / 100" | bc) | |
| if [ "$CUR_TEMP" -gt 85 ] && [ "$CUR_FREQ" -lt "$FREQ_THRESHOLD" ]; then | |
| THROTTLING_DETECTED=true | |
| echo -e "${RED}>> THROTTLING DETECTED: Temp: ${CUR_TEMP}°C | Freq dropped to: ${CUR_FREQ} MHz${NC}" | |
| else | |
| echo -ne "Running... Temp: ${CUR_TEMP}°C | Freq: ${CUR_FREQ} MHz \r" | |
| fi | |
| sleep 2 | |
| done | |
| echo -e "\n------------------------------------------------------------" | |
| echo -e "${CYAN}=== DIAGNOSTIC REPORT ===${NC}" | |
| # 5. Analysis | |
| echo "Max Temp Reached: ${MAX_TEMP_REACHED}°C" | |
| # Diagnosis: Bad Paste | |
| if [ "$SPIKE_DETECTED" = true ]; then | |
| echo -e "${RED}[BAD RESULT] Thermal Paste/Contact Issue:${NC}" | |
| echo " - Your temperature spiked instantly (+${TEMP_RISE}°C) when load started." | |
| echo " - This usually means heat cannot move from the CPU to the cooler." | |
| echo " - ACTION: Reseat cooler and re-apply thermal paste." | |
| elif [ "$MAX_TEMP_REACHED" -gt 90 ]; then | |
| echo -e "${YELLOW}[WARNING] General Overheating:${NC}" | |
| echo " - Temps are very high, but the rise was gradual." | |
| echo " - ACTION: Clean dust filters and check fan curves." | |
| else | |
| echo -e "${GREEN}[GOOD RESULT] Cooler seems functional.${NC}" | |
| fi | |
| echo "" | |
| # Diagnosis: Throttling | |
| if [ "$THROTTLING_DETECTED" = true ]; then | |
| echo -e "${RED}[BAD RESULT] Thermal Throttling Confirmed:${NC}" | |
| echo " - Your CPU slowed down to cool itself." | |
| echo " - Performance is being lost due to heat." | |
| else | |
| echo -e "${GREEN}[GOOD RESULT] No Throttling Detected.${NC}" | |
| echo " - CPU maintained frequency targets." | |
| fi | |
| echo "------------------------------------------------------------" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment