Skip to main content
The Process struct provides methods to monitor CPU usage, including percentage-based metrics and detailed CPU time statistics.

CPUPercent

Function Signature

func (p *Process) CPUPercent() (float64, error)
func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error)
Returns the CPU usage percentage of the process since it started. This represents the average CPU utilization over the process lifetime.

Return Value

float64
float64
CPU usage percentage. Can exceed 100% on multi-core systems (e.g., 200% means using 2 full cores).

Usage Example

package main

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

func main() {
    p, err := process.NewProcess(1234)
    if err != nil {
        panic(err)
    }
    
    cpuPercent, err := p.CPUPercent()
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("CPU usage: %.2f%%\n", cpuPercent)
}

Percent (Interval-Based)

Function Signature

func (p *Process) Percent(interval time.Duration) (float64, error)
func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration) (float64, error)
Returns CPU usage percentage calculated over a specific interval.

Parameters

interval
time.Duration
  • If interval > 0: Blocks for the specified duration and returns the CPU percentage during that time
  • If interval == 0: Returns the difference from the last call (non-blocking)

Behavior

  • First call with interval = 0: Returns 0 (establishes baseline)
  • Subsequent calls with interval = 0: Returns CPU usage since last call
  • Calls with interval > 0: Waits and calculates usage during that interval

Usage Examples

Blocking Interval Measurement

package main

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

func main() {
    p, _ := process.NewProcess(1234)
    
    // Measure CPU usage over 1 second
    cpuPercent, err := p.Percent(1 * time.Second)
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("CPU usage (last 1 second): %.2f%%\n", cpuPercent)
}

Non-Blocking Continuous Monitoring

package main

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

func main() {
    p, _ := process.NewProcess(1234)
    
    // Initialize baseline (first call returns 0)
    p.Percent(0)
    
    ticker := time.NewTicker(5 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        // Get CPU usage since last call (non-blocking)
        cpuPercent, err := p.Percent(0)
        if err != nil {
            fmt.Printf("Error: %v\n", err)
            return
        }
        
        fmt.Printf("[%s] CPU: %.2f%%\n",
            time.Now().Format("15:04:05"),
            cpuPercent)
    }
}

Times

Function Signature

func (p *Process) Times() (*cpu.TimesStat, error)
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
Returns detailed CPU time statistics for the process.

Return Value

Returns a cpu.TimesStat struct:
type TimesStat struct {
    User      float64 // Time spent in user mode
    System    float64 // Time spent in kernel mode
    Idle      float64 // Idle time
    Nice      float64 // Time spent with nice priority
    Iowait    float64 // Time waiting for I/O
    Irq       float64 // Time servicing interrupts
    Softirq   float64 // Time servicing soft interrupts
    Steal     float64 // Stolen time (virtualization)
    Guest     float64 // Time spent running guest VM
    GuestNice float64 // Time spent running niced guest
}
Not all fields are available on all platforms. User and System are universally supported.

Usage Example

package main

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

func main() {
    p, _ := process.NewProcess(1234)
    
    times, err := p.Times()
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("CPU Times:\n")
    fmt.Printf("  User:   %.2f seconds\n", times.User)
    fmt.Printf("  System: %.2f seconds\n", times.System)
    fmt.Printf("  Total:  %.2f seconds\n", times.Total())
}

CPU Affinity

Function Signature

func (p *Process) CPUAffinity() ([]int32, error)
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error)
Returns the list of CPU cores the process is allowed to run on.

Example

package main

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

func main() {
    p, _ := process.NewProcess(1234)
    
    affinity, err := p.CPUAffinity()
    if err != nil {
        fmt.Printf("CPU affinity not available: %v\n", err)
        return
    }
    
    fmt.Printf("Process can run on CPUs: %v\n", affinity)
    fmt.Printf("Number of allowed CPUs: %d\n", len(affinity))
}
CPU affinity is primarily supported on Linux. Other platforms may return an error.

NumThreads

Function Signature

func (p *Process) NumThreads() (int32, error)
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error)
Returns the number of threads used by the process.

Example

p, _ := process.NewProcess(1234)
numThreads, err := p.NumThreads()
if err != nil {
    panic(err)
}
fmt.Printf("Number of threads: %d\n", numThreads)

Threads

Function Signature

func (p *Process) Threads() (map[int32]*cpu.TimesStat, error)
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error)
Returns CPU time statistics for each thread, mapped by thread ID.

Example

package main

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

func main() {
    p, _ := process.NewProcess(1234)
    
    threads, err := p.Threads()
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("Process has %d threads:\n", len(threads))
    
    for tid, times := range threads {
        fmt.Printf("  Thread %d: User=%.2fs System=%.2fs\n",
            tid, times.User, times.System)
    }
}

Monitoring Examples

Real-Time CPU Monitor

package main

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

func monitorCPU(pid int32) {
    p, err := process.NewProcess(pid)
    if err != nil {
        panic(err)
    }
    
    name, _ := p.Name()
    fmt.Printf("Monitoring CPU for %s (PID %d)\n", name, pid)
    fmt.Println("======================================")
    
    // Initialize baseline
    p.Percent(0)
    time.Sleep(100 * time.Millisecond)
    
    ticker := time.NewTicker(2 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        running, _ := p.IsRunning()
        if !running {
            fmt.Println("Process terminated")
            return
        }
        
        // Get interval-based CPU usage
        cpuPercent, err := p.Percent(0)
        if err != nil {
            fmt.Printf("Error: %v\n", err)
            continue
        }
        
        // Get thread count
        numThreads, _ := p.NumThreads()
        
        // Get CPU times
        times, _ := p.Times()
        
        fmt.Printf("[%s] CPU: %6.2f%% | Threads: %3d | User: %.2fs | System: %.2fs\n",
            time.Now().Format("15:04:05"),
            cpuPercent,
            numThreads,
            times.User,
            times.System)
    }
}

func main() {
    monitorCPU(1234)
}

CPU Usage Alert System

package main

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

func alertOnHighCPU(pid int32, threshold float64) {
    p, _ := process.NewProcess(pid)
    name, _ := p.Name()
    
    fmt.Printf("Monitoring %s (PID %d) - Alert threshold: %.0f%%\n", 
        name, pid, threshold)
    
    ticker := time.NewTicker(5 * time.Second)
    defer ticker.Stop()
    
    alertCount := 0
    
    for range ticker.C {
        cpuPercent, err := p.Percent(1 * time.Second)
        if err != nil {
            return
        }
        
        if cpuPercent > threshold {
            alertCount++
            fmt.Printf("⚠️  HIGH CPU ALERT #%d: %.2f%% (threshold: %.0f%%)\n",
                alertCount, cpuPercent, threshold)
            
            // Get additional details
            threads, _ := p.NumThreads()
            times, _ := p.Times()
            
            fmt.Printf("   Threads: %d\n", threads)
            fmt.Printf("   Total CPU time: %.2f seconds\n", times.Total())
        } else {
            fmt.Printf("[OK] CPU: %.2f%%\n", cpuPercent)
        }
    }
}

func main() {
    alertOnHighCPU(1234, 80.0) // Alert if CPU usage exceeds 80%
}

Top CPU Processes

package main

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

type ProcessCPU struct {
    PID       int32
    Name      string
    CPUPercent float64
}

func topCPUProcesses(limit int) {
    pids, _ := process.Pids()
    var processes []ProcessCPU
    
    fmt.Println("Measuring CPU usage...")
    
    for _, pid := range pids {
        p, err := process.NewProcess(pid)
        if err != nil {
            continue
        }
        
        name, err := p.Name()
        if err != nil {
            continue
        }
        
        // Measure CPU over 1 second
        cpuPercent, err := p.Percent(1 * time.Second)
        if err != nil {
            continue
        }
        
        if cpuPercent > 0 {
            processes = append(processes, ProcessCPU{
                PID:        pid,
                Name:       name,
                CPUPercent: cpuPercent,
            })
        }
    }
    
    // Sort by CPU percentage (descending)
    sort.Slice(processes, func(i, j int) bool {
        return processes[i].CPUPercent > processes[j].CPUPercent
    })
    
    fmt.Printf("\nTop %d CPU-consuming processes:\n\n", limit)
    fmt.Printf("%-8s %-30s %10s\n", "PID", "Name", "CPU %")
    fmt.Println("--------------------------------------------------")
    
    for i := 0; i < limit && i < len(processes); i++ {
        proc := processes[i]
        fmt.Printf("%-8d %-30s %9.2f%%\n",
            proc.PID,
            proc.Name,
            proc.CPUPercent)
    }
}

func main() {
    topCPUProcesses(10)
}

Understanding CPU Percentages

On multi-core systems, CPU percentage can exceed 100%. For example:
  • 100% = Using 1 full CPU core
  • 200% = Using 2 full CPU cores
  • 400% = Using 4 full CPU cores
To normalize CPU percentage to a 0-100% range regardless of CPU count:
import "runtime"

cpuPercent, _ := p.CPUPercent()
numCPU := runtime.NumCPU()
normalizedPercent := cpuPercent / float64(numCPU)

fmt.Printf("CPU: %.2f%% (%.2f%% per core)\n", cpuPercent, normalizedPercent)

Platform Notes

Reads from /proc/[pid]/stat for CPU times. All features fully supported.

Memory Usage

Monitor memory usage

I/O Counters

Monitor I/O statistics

Process Info

Get process information

Overview

Back to process package overview

Build docs developers (and LLMs) love