Skip to main content

Overview

The IOCounters function retrieves network I/O statistics for every network interface installed on the system. It can return either aggregated statistics for all interfaces or per-interface statistics.

Functions

func IOCounters(pernic bool) ([]IOCountersStat, error)
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error)
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error)
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error)

Parameters

pernic
bool
required
If true, returns statistics for each network interface separately. If false, returns only the sum of all interfaces with the name “all”.
filename
string
Custom file path to read statistics from (for IOCountersByFile variants)
ctx
context.Context
Context for cancellation and timeout control

Returns

Returns a slice of IOCountersStat structures containing network I/O statistics.

IOCountersStat Structure

The IOCountersStat struct contains comprehensive network I/O metrics for a network interface.
type IOCountersStat struct {
    Name        string // Interface name (e.g., "eth0", "wlan0", "all")
    BytesSent   uint64 // Number of bytes sent
    BytesRecv   uint64 // Number of bytes received
    PacketsSent uint64 // Number of packets sent
    PacketsRecv uint64 // Number of packets received
    Errin       uint64 // Total errors while receiving
    Errout      uint64 // Total errors while sending
    Dropin      uint64 // Total incoming packets dropped
    Dropout     uint64 // Total outgoing packets dropped (always 0 on OSX and BSD)
    Fifoin      uint64 // Total FIFO buffer errors while receiving
    Fifoout     uint64 // Total FIFO buffer errors while sending
}

Fields

Name
string
The name of the network interface (e.g., “eth0”, “wlan0”, “lo”). When pernic=false, this will be “all”.
BytesSent
uint64
Total number of bytes transmitted through this interface.
BytesRecv
uint64
Total number of bytes received through this interface.
PacketsSent
uint64
Total number of packets transmitted through this interface.
PacketsRecv
uint64
Total number of packets received through this interface.
Errin
uint64
Total number of errors encountered while receiving packets.
Errout
uint64
Total number of errors encountered while sending packets.
Dropin
uint64
Total number of incoming packets that were dropped.
Dropout
uint64
Total number of outgoing packets that were dropped. Note: Always 0 on macOS and BSD systems.
Fifoin
uint64
Total number of FIFO buffer errors while receiving packets.
Fifoout
uint64
Total number of FIFO buffer errors while sending packets.

Usage Examples

Get Statistics Per Interface

package main

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

func main() {
    // Get statistics for each interface
    counters, err := net.IOCounters(true)
    if err != nil {
        panic(err)
    }
    
    for _, counter := range counters {
        fmt.Printf("Interface: %s\n", counter.Name)
        fmt.Printf("  Bytes Sent: %d\n", counter.BytesSent)
        fmt.Printf("  Bytes Recv: %d\n", counter.BytesRecv)
        fmt.Printf("  Packets Sent: %d\n", counter.PacketsSent)
        fmt.Printf("  Packets Recv: %d\n", counter.PacketsRecv)
        fmt.Printf("  Errors In: %d\n", counter.Errin)
        fmt.Printf("  Errors Out: %d\n", counter.Errout)
        fmt.Printf("  Drop In: %d\n", counter.Dropin)
        fmt.Printf("  Drop Out: %d\n\n", counter.Dropout)
    }
}

Get Aggregated Statistics

package main

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

func main() {
    // Get aggregated statistics for all interfaces
    counters, err := net.IOCounters(false)
    if err != nil {
        panic(err)
    }
    
    if len(counters) > 0 {
        all := counters[0]
        fmt.Printf("Total Network I/O:\n")
        fmt.Printf("  Bytes Sent: %d\n", all.BytesSent)
        fmt.Printf("  Bytes Recv: %d\n", all.BytesRecv)
        fmt.Printf("  Packets Sent: %d\n", all.PacketsSent)
        fmt.Printf("  Packets Recv: %d\n", all.PacketsRecv)
    }
}

Calculate Throughput

package main

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

func main() {
    // Get initial counters
    counters1, _ := net.IOCounters(true)
    
    // Wait 1 second
    time.Sleep(1 * time.Second)
    
    // Get counters again
    counters2, _ := net.IOCounters(true)
    
    // Calculate throughput
    for i, c2 := range counters2 {
        c1 := counters1[i]
        if c1.Name != c2.Name {
            continue
        }
        
        sentRate := c2.BytesSent - c1.BytesSent
        recvRate := c2.BytesRecv - c1.BytesRecv
        
        fmt.Printf("%s: sent=%d B/s, recv=%d B/s\n", 
            c2.Name, sentRate, recvRate)
    }
}

Using Context

package main

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

func main() {
    // Create context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    counters, err := net.IOCountersWithContext(ctx, true)
    if err != nil {
        panic(err)
    }
    
    for _, counter := range counters {
        fmt.Printf("%s: %d bytes sent, %d bytes received\n",
            counter.Name, counter.BytesSent, counter.BytesRecv)
    }
}

Platform-Specific Notes

macOS and BSD

  • The Dropout field is always 0 on these platforms
  • Some interfaces may not report FIFO errors

Linux

  • Statistics are typically read from /proc/net/dev
  • All fields are fully supported

Windows

  • Interface names may differ from Unix systems
  • Some counters may have limited precision

Error Handling

Common errors include:
  • Permission issues reading system statistics
  • Invalid or missing network interface files
  • Platform-specific limitations
counters, err := net.IOCounters(true)
if err != nil {
    fmt.Printf("Error getting I/O counters: %v\n", err)
    return
}

See Also

Build docs developers (and LLMs) love