Skip to main content
Calculates the percentage of CPU time used, either per CPU core or combined across all cores.

Function Signatures

func Percent(interval time.Duration, percpu bool) ([]float64, error)
func PercentWithContext(ctx context.Context, interval time.Duration, percpu bool) ([]float64, error)

Parameters

interval
time.Duration
required
The duration over which to measure CPU usage.
  • If greater than 0, the function will sleep for this duration and calculate usage between the two measurements
  • If 0, compares against the last call to this function (non-blocking)
percpu
bool
required
If true, returns usage percentage for each CPU core individually. If false, returns combined usage for all cores.
ctx
context.Context
Context for cancellation and timeout control (WithContext variant only). Note that the context can cancel the sleep interval.

Return Value

[]float64
[]float64
Array of CPU usage percentages (0-100). Contains one element if percpu is false, or one element per CPU core if percpu is true.
error
error
Error if CPU percentage could not be calculated, nil on success. Returns error if the interval is 0 but there’s no previous measurement to compare against.

Examples

Basic CPU Usage Monitoring

package main

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

func main() {
    // Measure CPU usage over 1 second
    percent, err := cpu.Percent(time.Second, false)
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("CPU Usage: %.2f%%\n", percent[0])
}

Monitor Per-CPU Usage

package main

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

func main() {
    // Get usage for each CPU core
    percents, err := cpu.Percent(time.Second, true)
    if err != nil {
        panic(err)
    }
    
    for i, percent := range percents {
        fmt.Printf("CPU%d: %.2f%%\n", i, percent)
    }
}

Continuous Monitoring with Zero Interval

package main

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

func main() {
    // First call with interval to establish baseline
    cpu.Percent(time.Second, false)
    
    // Subsequent calls with 0 interval are non-blocking
    for i := 0; i < 10; i++ {
        time.Sleep(time.Second)
        
        percent, err := cpu.Percent(0, false)
        if err != nil {
            panic(err)
        }
        
        fmt.Printf("CPU Usage: %.2f%%\n", percent[0])
    }
}

Real-time CPU Monitor

package main

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

func main() {
    fmt.Println("Monitoring CPU usage (Ctrl+C to exit)...")
    
    ticker := time.NewTicker(2 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        percent, err := cpu.Percent(time.Second, false)
        if err != nil {
            fmt.Printf("Error: %v\n", err)
            continue
        }
        
        usage := percent[0]
        bars := int(usage / 5) // 20 bars for 100%
        
        fmt.Printf("\rCPU: [%-20s] %.1f%%", 
            string(make([]byte, bars)), usage)
    }
}

Using Context with Timeout

package main

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

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    // This will measure for 3 seconds (within the 5-second timeout)
    percent, err := cpu.PercentWithContext(ctx, 3*time.Second, false)
    if err != nil {
        if ctx.Err() == context.DeadlineExceeded {
            fmt.Println("Operation timed out")
        } else {
            panic(err)
        }
        return
    }
    
    fmt.Printf("CPU Usage: %.2f%%\n", percent[0])
}

Detect High CPU Usage

package main

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

func main() {
    threshold := 80.0
    
    percent, err := cpu.Percent(time.Second, false)
    if err != nil {
        panic(err)
    }
    
    usage := percent[0]
    
    if usage > threshold {
        fmt.Printf("WARNING: High CPU usage detected: %.2f%%\n", usage)
    } else {
        fmt.Printf("CPU usage normal: %.2f%%\n", usage)
    }
}

Per-CPU Load Balancing Check

package main

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

func main() {
    percents, err := cpu.Percent(time.Second, true)
    if err != nil {
        panic(err)
    }
    
    var sum, min, max float64
    min = 100.0
    
    for i, p := range percents {
        fmt.Printf("CPU%d: %.2f%%\n", i, p)
        sum += p
        min = math.Min(min, p)
        max = math.Max(max, p)
    }
    
    avg := sum / float64(len(percents))
    imbalance := max - min
    
    fmt.Printf("\nAverage: %.2f%%\n", avg)
    fmt.Printf("Range: %.2f%% - %.2f%%\n", min, max)
    fmt.Printf("Imbalance: %.2f%%\n", imbalance)
    
    if imbalance > 30 {
        fmt.Println("Warning: Significant load imbalance detected")
    }
}

Compare Measurement Intervals

package main

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

func main() {
    intervals := []time.Duration{
        100 * time.Millisecond,
        500 * time.Millisecond,
        time.Second,
        2 * time.Second,
    }
    
    for _, interval := range intervals {
        percent, err := cpu.Percent(interval, false)
        if err != nil {
            panic(err)
        }
        
        fmt.Printf("%v interval: %.2f%%\n", interval, percent[0])
    }
}

Notes

  • The Percent() function is a convenience wrapper that calls PercentWithContext() with context.Background()
  • When interval is 0:
    • The function returns immediately (non-blocking)
    • Calculates usage based on the difference from the last call
    • The first call with interval 0 may return an error if there’s no baseline
    • Each call updates the internal baseline for the next call
  • When interval is greater than 0:
    • The function blocks for the specified duration
    • Takes two measurements with a sleep in between
    • More accurate for short-term measurements
  • Return values range from 0 to 100 (percentage)
  • For percpu=false, the combined percentage can exceed 100% on some platforms
  • The calculation excludes idle and iowait time from the total
  • On Linux, guest and guest_nice times are excluded from the total to avoid double counting
  • Longer intervals provide more accurate measurements by smoothing out momentary spikes
  • Shorter intervals (< 100ms) may be less accurate due to measurement overhead

Build docs developers (and LLMs) love