Skip to main content
The sensors package provides access to hardware sensor data, primarily temperature sensors. This allows monitoring of system thermal characteristics for performance tuning and thermal management.

Key Features

Temperature Monitoring

Read temperature data from CPU, GPU, and other hardware sensors

Main Functions

SensorsTemperatures

Retrieves temperature readings from all available hardware sensors.
func SensorsTemperatures() ([]TemperatureStat, error)
func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error)
Returns: Slice of TemperatureStat containing temperature sensor data

Data Structures

TemperatureStat

Contains temperature data from a single sensor.
type TemperatureStat struct {
    SensorKey   string  // Sensor identifier/name
    Temperature float64 // Current temperature in Celsius
    High        float64 // High threshold temperature
    Critical    float64 // Critical threshold temperature
}
SensorKey
string
Unique identifier for the sensor. Examples:
  • "coretemp_core_0" - CPU core temperature
  • "acpitz" - ACPI thermal zone
  • "nvme_composite" - NVMe drive temperature
Temperature
float64
Current temperature reading in degrees Celsius.
High
float64
High temperature threshold in degrees Celsius. When exceeded, the system may throttle or warn. Returns 0 if not available.
Critical
float64
Critical temperature threshold in degrees Celsius. When exceeded, the system may shut down to prevent damage. Returns 0 if not available.

Platform Support

Temperature sensor support varies significantly by platform:

Linux

Full support via hwmon and thermal_zone interfaces

macOS

Limited support, platform-specific

Windows

Limited support, may require additional drivers

FreeBSD/OpenBSD

Platform-specific implementation

Usage Examples

Basic Temperature Reading

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/sensors"
)

func main() {
    temps, err := sensors.SensorsTemperatures()
    if err != nil {
        panic(err)
    }
    
    if len(temps) == 0 {
        fmt.Println("No temperature sensors found")
        return
    }
    
    fmt.Println("Temperature Sensors:")
    for _, temp := range temps {
        fmt.Printf("  %s: %.1f°C\n", temp.SensorKey, temp.Temperature)
    }
}

Monitor with Thresholds

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/sensors"
)

func main() {
    temps, err := sensors.SensorsTemperatures()
    if err != nil {
        panic(err)
    }
    
    fmt.Println("Sensor Status:")
    fmt.Println("--------------------------------------------------")
    
    for _, temp := range temps {
        fmt.Printf("%s: %.1f°C", temp.SensorKey, temp.Temperature)
        
        if temp.Critical > 0 && temp.Temperature >= temp.Critical {
            fmt.Print(" [CRITICAL]")
        } else if temp.High > 0 && temp.Temperature >= temp.High {
            fmt.Print(" [HIGH]")
        } else {
            fmt.Print(" [OK]")
        }
        
        if temp.High > 0 {
            fmt.Printf(" (High: %.1f°C)", temp.High)
        }
        if temp.Critical > 0 {
            fmt.Printf(" (Critical: %.1f°C)", temp.Critical)
        }
        fmt.Println()
    }
}

Find Hottest Component

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/v4/sensors"
)

func main() {
    temps, err := sensors.SensorsTemperatures()
    if err != nil {
        panic(err)
    }
    
    if len(temps) == 0 {
        fmt.Println("No sensors found")
        return
    }
    
    // Find hottest sensor
    hottest := temps[0]
    for _, temp := range temps[1:] {
        if temp.Temperature > hottest.Temperature {
            hottest = temp
        }
    }
    
    fmt.Printf("Hottest component: %s at %.1f°C\n", 
        hottest.SensorKey, hottest.Temperature)
}

Continuous Monitoring

package main

import (
    "fmt"
    "time"
    "github.com/shirou/gopsutil/v4/sensors"
)

func main() {
    fmt.Println("Temperature Monitor (Ctrl+C to exit)")
    
    ticker := time.NewTicker(2 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        temps, err := sensors.SensorsTemperatures()
        if err != nil {
            fmt.Println("Error:", err)
            continue
        }
        
        fmt.Printf("\n[%s]\n", time.Now().Format("15:04:05"))
        
        for _, temp := range temps {
            status := "OK"
            if temp.Critical > 0 && temp.Temperature >= temp.Critical {
                status = "CRIT"
            } else if temp.High > 0 && temp.Temperature >= temp.High {
                status = "HIGH"
            }
            
            fmt.Printf("  %-30s %.1f°C [%s]\n", 
                temp.SensorKey, temp.Temperature, status)
        }
    }
}

Filter CPU Temperatures

package main

import (
    "fmt"
    "strings"
    "github.com/shirou/gopsutil/v4/sensors"
)

func main() {
    temps, err := sensors.SensorsTemperatures()
    if err != nil {
        panic(err)
    }
    
    fmt.Println("CPU Temperatures:")
    
    cpuTemps := make([]sensors.TemperatureStat, 0)
    for _, temp := range temps {
        // Filter for CPU-related sensors
        if strings.Contains(strings.ToLower(temp.SensorKey), "core") ||
           strings.Contains(strings.ToLower(temp.SensorKey), "cpu") ||
           strings.Contains(strings.ToLower(temp.SensorKey), "proc") {
            cpuTemps = append(cpuTemps, temp)
        }
    }
    
    if len(cpuTemps) == 0 {
        fmt.Println("  No CPU temperature sensors found")
        return
    }
    
    // Calculate average CPU temperature
    var sum float64
    for _, temp := range cpuTemps {
        fmt.Printf("  %s: %.1f°C\n", temp.SensorKey, temp.Temperature)
        sum += temp.Temperature
    }
    
    avg := sum / float64(len(cpuTemps))
    fmt.Printf("\nAverage CPU Temperature: %.1f°C\n", avg)
}

Using Context

package main

import (
    "context"
    "fmt"
    "time"
    "github.com/shirou/gopsutil/v4/sensors"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    temps, err := sensors.TemperaturesWithContext(ctx)
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("Found %d temperature sensors\n", len(temps))
    for _, temp := range temps {
        fmt.Printf("  %s: %.1f°C\n", temp.SensorKey, temp.Temperature)
    }
}

Linux Implementation Details

On Linux, the sensors package reads from two sources:

hwmon Interface (Primary)

Reads from /sys/class/hwmon/hwmon*/temp*_input:
  • Standard hardware monitoring interface
  • Provides temperature in millidegrees Celsius
  • Includes high and critical thresholds when available
  • Sensor labels from temp*_label files

thermal_zone Interface (Fallback)

Reads from /sys/class/thermal/thermal_zone*/:
  • Used on systems without hwmon (e.g., Raspberry Pi)
  • Reads from temp and type files
  • Limited threshold information

Common Sensor Types

Intel CPU core temperatures. Each CPU core typically has its own sensor.
AMD CPU temperatures (Ryzen, EPYC).
NVMe SSD temperatures, including composite and individual sensor readings.
ACPI thermal zones, generic motherboard temperature sensors.
Intel wireless adapter temperature.
GPU temperatures for NVIDIA and AMD graphics cards.

Common Use Cases

  • Thermal Monitoring - Track system temperatures for cooling optimization
  • Performance Tuning - Identify thermal throttling issues
  • Datacenter Management - Monitor server thermal characteristics
  • Overclocking - Ensure safe temperatures during performance tuning
  • Alerting - Trigger warnings when temperatures exceed thresholds
  • Hardware Diagnostics - Detect failing cooling systems

Best Practices

Check for sensor availability: Not all systems expose temperature sensors through software interfaces.
Handle missing thresholds: The High and Critical fields may be 0 if thresholds aren’t available.
Platform-specific behavior: Test on target platforms as sensor availability varies widely.

Error Handling

temps, err := sensors.SensorsTemperatures()
if err != nil {
    fmt.Printf("Error reading sensors: %v\n", err)
    return
}

if len(temps) == 0 {
    fmt.Println("No temperature sensors found on this system")
    return
}

Limitations

  • Platform-dependent: Full functionality primarily on Linux
  • Requires kernel support: System must have proper drivers
  • Permission issues: May require elevated privileges on some systems
  • Virtual machines: Sensors often not available in VMs
  • Laptop vs Desktop: Sensor availability varies by hardware

See Also

Build docs developers (and LLMs) love