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
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
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= %.2f s System= %.2f s \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: %.2f s | System: %.2f s \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 ( " \n Top %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 )
Reads from /proc/[pid]/stat for CPU times. All features fully supported.
Uses proc_pidinfo() with PROC_PIDTASKINFO. Thread-level stats may be limited.
Uses GetProcessTimes() API. Some fields like nice and iowait are not available.
Uses kvm_getprocs() or sysctl. Feature availability varies by BSD variant.
Memory Usage Monitor memory usage
I/O Counters Monitor I/O statistics
Process Info Get process information
Overview Back to process package overview