Skip to main content

Overview

The stats package provides comprehensive statistics collection for WebRTC connections. It implements the WebRTC Statistics API, allowing you to monitor and measure various aspects of peer connections, RTP streams, ICE candidates, transports, and more.

Core Types

Stats Interface

The base interface for all statistics objects.
type Stats interface {
    statsMarker()
}
All statistics types implement this interface to identify them as valid stats objects.

StatsReport

A collection of stats objects indexed by their unique identifiers.
type StatsReport map[string]Stats
Usage Example
pc, _ := webrtc.NewPeerConnection(webrtc.Configuration{})

// Get statistics report
stats := pc.GetStats()

// Iterate through all stats
for id, stat := range stats {
    switch s := stat.(type) {
    case webrtc.InboundRTPStreamStats:
        fmt.Printf("Inbound RTP: %d packets received\n", s.PacketsReceived)
    case webrtc.ICECandidatePairStats:
        fmt.Printf("Candidate pair: %s\n", s.State)
    }
}

StatsTimestamp

A timestamp represented as floating point milliseconds since epoch.
type StatsTimestamp float64
Time()
time.Time
Converts the timestamp to a Go time.Time value
Example
timestamp := stats.Timestamp
t := timestamp.Time()
fmt.Printf("Stats captured at: %s\n", t.Format(time.RFC3339))

Statistics Types

StatsType

Indicates the type of statistics object.
type StatsType string
Constants
StatsTypeCodec
string
Used by CodecStats (“codec”)
StatsTypeInboundRTP
string
Used by InboundRTPStreamStats (“inbound-rtp”)
StatsTypeOutboundRTP
string
Used by OutboundRTPStreamStats (“outbound-rtp”)
StatsTypeRemoteInboundRTP
string
Used by RemoteInboundRTPStreamStats (“remote-inbound-rtp”)
StatsTypeRemoteOutboundRTP
string
Used by RemoteOutboundRTPStreamStats (“remote-outbound-rtp”)
StatsTypeCSRC
string
Used by RTPContributingSourceStats (“csrc”)
StatsTypeMediaSource
string
Used by AudioSourceStats or VideoSourceStats (“media-source”)
StatsTypeMediaPlayout
string
Used by AudioPlayoutStats (“media-playout”)
StatsTypePeerConnection
string
Used by PeerConnectionStats (“peer-connection”)
StatsTypeDataChannel
string
Used by DataChannelStats (“data-channel”)
StatsTypeTransport
string
Used by TransportStats (“transport”)
StatsTypeCandidatePair
string
Used by ICECandidatePairStats (“candidate-pair”)
StatsTypeLocalCandidate
string
Used by ICECandidateStats for local candidates (“local-candidate”)
StatsTypeRemoteCandidate
string
Used by ICECandidateStats for remote candidates (“remote-candidate”)
StatsTypeCertificate
string
Used by CertificateStats (“certificate”)
StatsTypeSCTPTransport
string
Used by SCTPTransportStats (“sctp-transport”)

RTP Stream Statistics

InboundRTPStreamStats

Statistics for an inbound RTP stream currently being received.
type InboundRTPStreamStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    SSRC                 SSRC
    Kind                 string
    Mid                  string
    
    // Transport and codec
    TransportID          string
    CodecID              string
    
    // Packet metrics
    PacketsReceived      uint32
    PacketsLost          int32
    PacketsDiscarded     uint32
    PacketsRepaired      uint32
    PacketsDuplicated    uint32
    PacketsFailedDecryption uint32
    
    // Byte metrics
    BytesReceived        uint64
    HeaderBytesReceived  uint64
    
    // Quality metrics
    Jitter               float64
    
    // RTCP feedback
    FIRCount             uint32
    PLICount             uint32
    NACKCount            uint32
    SLICount             uint32
    
    // Jitter buffer
    JitterBufferDelay           float64
    JitterBufferTargetDelay     float64
    JitterBufferEmittedCount    uint64
    JitterBufferMinimumDelay    float64
    
    // Video-specific (when Kind == "video")
    FramesReceived              uint32
    FramesDecoded               uint32
    KeyFramesDecoded            uint32
    FramesRendered              uint32
    FramesDropped               uint32
    FrameWidth                  uint32
    FrameHeight                 uint32
    TotalDecodeTime             float64
    TotalInterFrameDelay        float64
    TotalSquaredInterFrameDelay float64
    QPSum                       uint64
    PauseCount                  uint32
    TotalPausesDuration         float64
    FreezeCount                 uint32
    TotalFreezesDuration        float64
    PowerEfficientDecoder       bool
    DecoderImplementation       string
    
    // Audio-specific (when Kind == "audio")
    TotalSamplesReceived           uint64
    ConcealedSamples               uint64
    SilentConcealedSamples         uint64
    ConcealmentEvents              uint64
    InsertedSamplesForDeceleration uint64
    RemovedSamplesForAcceleration  uint64
    AudioLevel                     float64
    TotalAudioEnergy               float64
    TotalSamplesDuration           float64
    
    // Processing
    TotalProcessingDelay        float64
    
    // Burst and gap metrics
    BurstPacketsLost       uint32
    BurstPacketsDiscarded  uint32
    BurstLossCount         uint32
    BurstDiscardCount      uint32
    BurstLossRate          float64
    BurstDiscardRate       float64
    GapLossRate            float64
    GapDiscardRate         float64
    
    // FEC
    FECPacketsReceived     uint32
    FECPacketsDiscarded    uint64
    
    // References
    TrackID                     string
    ReceiverID                  string
    RemoteID                    string
    
    // Timing
    LastPacketReceivedTimestamp StatsTimestamp
    AverageRTCPInterval         float64
    
    // DSCP
    PerDSCPPacketsReceived map[string]uint32
}
stats := pc.GetStats()
for _, stat := range stats {
    if inbound, ok := stat.(webrtc.InboundRTPStreamStats); ok && inbound.Kind == "video" {
        fmt.Printf("Video Stats:\n")
        fmt.Printf("  Packets: %d received, %d lost\n", 
            inbound.PacketsReceived, inbound.PacketsLost)
        fmt.Printf("  Frames: %d decoded, %d dropped\n",
            inbound.FramesDecoded, inbound.FramesDropped)
        fmt.Printf("  Resolution: %dx%d\n",
            inbound.FrameWidth, inbound.FrameHeight)
        fmt.Printf("  Jitter: %.3f seconds\n", inbound.Jitter)
        
        // Calculate packet loss rate
        total := uint32(int32(inbound.PacketsReceived) + inbound.PacketsLost)
        if total > 0 {
            lossRate := float64(inbound.PacketsLost) / float64(total) * 100
            fmt.Printf("  Loss Rate: %.2f%%\n", lossRate)
        }
    }
}

OutboundRTPStreamStats

Statistics for an outbound RTP stream currently being sent.
type OutboundRTPStreamStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    SSRC                 SSRC
    Kind                 string
    Mid                  string
    Rid                  string
    
    // Transport and codec
    TransportID          string
    CodecID              string
    MediaSourceID        string
    
    // Packet metrics
    PacketsSent                uint32
    PacketsDiscardedOnSend     uint32
    RetransmittedPacketsSent   uint64
    
    // Byte metrics
    BytesSent                  uint64
    HeaderBytesSent            uint64
    RetransmittedBytesSent     uint64
    BytesDiscardedOnSend       uint64
    
    // RTCP feedback
    FIRCount             uint32
    PLICount             uint32
    NACKCount            uint32
    SLICount             uint32
    
    // Video-specific (when Kind == "video")
    FramesSent                         uint32
    HugeFramesSent                     uint32
    FramesEncoded                      uint32
    KeyFramesEncoded                   uint32
    FrameWidth                         uint32
    FrameHeight                        uint32
    FramesPerSecond                    float64
    QPSum                              uint64
    TotalEncodeTime                    float64
    QualityLimitationReason            QualityLimitationReason
    QualityLimitationDurations         map[string]float64
    QualityLimitationResolutionChanges uint32
    PowerEfficientEncoder              bool
    EncoderImplementation              string
    ScalabilityMode                    string
    
    // Bitrate
    TargetBitrate           float64
    TotalEncodedBytesTarget uint64
    
    // Timing
    TotalPacketSendDelay        float64
    LastPacketSentTimestamp     StatsTimestamp
    AverageRTCPInterval         float64
    
    // FEC
    FECPacketsSent     uint32
    
    // References
    TrackID            string
    SenderID           string
    RemoteID           string
    
    // State
    Active             bool
    
    // DSCP
    PerDSCPPacketsSent map[string]uint32
}
Example
stats := pc.GetStats()
for _, stat := range stats {
    if outbound, ok := stat.(webrtc.OutboundRTPStreamStats); ok && outbound.Kind == "video" {
        fmt.Printf("Outbound Video Stats:\n")
        fmt.Printf("  Packets sent: %d\n", outbound.PacketsSent)
        fmt.Printf("  Frames encoded: %d (key frames: %d)\n",
            outbound.FramesEncoded, outbound.KeyFramesEncoded)
        fmt.Printf("  Target bitrate: %.0f bps\n", outbound.TargetBitrate)
        fmt.Printf("  Quality limitation: %s\n", outbound.QualityLimitationReason)
        
        // Calculate average encode time
        if outbound.FramesEncoded > 0 {
            avgEncodeTime := outbound.TotalEncodeTime / float64(outbound.FramesEncoded)
            fmt.Printf("  Avg encode time: %.2f ms\n", avgEncodeTime * 1000)
        }
    }
}

RemoteInboundRTPStreamStats

Statistics for the remote endpoint’s inbound RTP stream, measured at the remote endpoint and reported via RTCP.
type RemoteInboundRTPStreamStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    SSRC                 SSRC
    Kind                 string
    TransportID          string
    CodecID              string
    
    // Packet metrics
    PacketsReceived      uint32
    PacketsLost          int32
    PacketsDiscarded     uint32
    PacketsRepaired      uint32
    
    // Quality metrics
    Jitter               float64
    
    // RTCP feedback
    FIRCount             uint32
    PLICount             uint32
    NACKCount            uint32
    SLICount             uint32
    QPSum                uint64
    
    // Burst and gap metrics
    BurstPacketsLost       uint32
    BurstPacketsDiscarded  uint32
    BurstLossCount         uint32
    BurstDiscardCount      uint32
    BurstLossRate          float64
    BurstDiscardRate       float64
    GapLossRate            float64
    GapDiscardRate         float64
    
    // Round trip time
    RoundTripTime              float64
    TotalRoundTripTime         float64
    FractionLost               float64
    RoundTripTimeMeasurements  uint64
    
    // Reference
    LocalID              string
}

RemoteOutboundRTPStreamStats

Statistics for the remote endpoint’s outbound RTP stream, measured at the remote endpoint and reported via RTCP.
type RemoteOutboundRTPStreamStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    SSRC                 SSRC
    Kind                 string
    TransportID          string
    CodecID              string
    
    // Packet metrics
    PacketsSent             uint32
    PacketsDiscardedOnSend  uint32
    FECPacketsSent          uint32
    
    // Byte metrics
    BytesSent               uint64
    BytesDiscardedOnSend    uint64
    
    // RTCP feedback
    FIRCount             uint32
    PLICount             uint32
    NACKCount            uint32
    SLICount             uint32
    QPSum                uint64
    
    // Round trip time
    RoundTripTime              float64
    TotalRoundTripTime         float64
    RoundTripTimeMeasurements  uint64
    
    // References
    LocalID             string
    RemoteTimestamp     StatsTimestamp
    ReportsSent         uint64
}

Codec Statistics

CodecStats

Statistics for a codec currently being used by RTP streams.
type CodecStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    
    PayloadType          PayloadType
    CodecType            CodecType
    TransportID          string
    MimeType             string
    ClockRate            uint32
    Channels             uint8
    SDPFmtpLine          string
    Implementation       string
}
CodecType
string
Either CodecTypeEncode or CodecTypeDecode
Example
stats := pc.GetStats()
for _, stat := range stats {
    if codec, ok := stat.(webrtc.CodecStats); ok {
        fmt.Printf("Codec: %s\n", codec.MimeType)
        fmt.Printf("  Payload Type: %d\n", codec.PayloadType)
        fmt.Printf("  Clock Rate: %d Hz\n", codec.ClockRate)
        fmt.Printf("  Type: %s\n", codec.CodecType)
        if codec.Channels > 0 {
            fmt.Printf("  Channels: %d\n", codec.Channels)
        }
    }
}

Media Source Statistics

AudioSourceStats

Statistics for an audio track attached to sender(s).
type AudioSourceStats struct {
    Timestamp                  StatsTimestamp
    Type                       StatsType
    ID                         string
    TrackIdentifier            string
    Kind                       string
    
    AudioLevel                 float64
    TotalAudioEnergy           float64
    TotalSamplesDuration       float64
    EchoReturnLoss             float64
    EchoReturnLossEnhancement  float64
    DroppedSamplesDuration     float64
    DroppedSamplesEvents       uint64
    TotalCaptureDelay          float64
    TotalSamplesCaptured       uint64
}

VideoSourceStats

Statistics for a video track attached to sender(s).
type VideoSourceStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    TrackIdentifier      string
    Kind                 string
    
    Width                uint32
    Height               uint32
    Frames               uint32
    FramesPerSecond      float64
}
Example
stats := pc.GetStats()
for _, stat := range stats {
    switch source := stat.(type) {
    case webrtc.AudioSourceStats:
        fmt.Printf("Audio Source: %s\n", source.TrackIdentifier)
        fmt.Printf("  Audio Level: %.2f\n", source.AudioLevel)
        fmt.Printf("  Samples Captured: %d\n", source.TotalSamplesCaptured)
        
    case webrtc.VideoSourceStats:
        fmt.Printf("Video Source: %s\n", source.TrackIdentifier)
        fmt.Printf("  Resolution: %dx%d\n", source.Width, source.Height)
        fmt.Printf("  FPS: %.1f\n", source.FramesPerSecond)
    }
}

ICE Statistics

ICECandidatePairStats

Statistics for an ICE candidate pair.
type ICECandidatePairStats struct {
    Timestamp                       StatsTimestamp
    Type                            StatsType
    ID                              string
    TransportID                     string
    LocalCandidateID                string
    RemoteCandidateID               string
    
    State                           StatsICECandidatePairState
    Nominated                       bool
    
    // Packet metrics
    PacketsSent                     uint32
    PacketsReceived                 uint32
    PacketsDiscardedOnSend          uint32
    
    // Byte metrics
    BytesSent                       uint64
    BytesReceived                   uint64
    BytesDiscardedOnSend            uint32
    
    // Timing
    LastPacketSentTimestamp         StatsTimestamp
    LastPacketReceivedTimestamp     StatsTimestamp
    FirstRequestTimestamp           StatsTimestamp
    LastRequestTimestamp            StatsTimestamp
    FirstResponseTimestamp          StatsTimestamp
    LastResponseTimestamp           StatsTimestamp
    FirstRequestReceivedTimestamp   StatsTimestamp
    LastRequestReceivedTimestamp    StatsTimestamp
    
    // Round trip time
    TotalRoundTripTime              float64
    CurrentRoundTripTime            float64
    
    // Bandwidth
    AvailableOutgoingBitrate        float64
    AvailableIncomingBitrate        float64
    
    // STUN metrics
    RequestsReceived                uint64
    RequestsSent                    uint64
    ResponsesReceived               uint64
    ResponsesSent                   uint64
    RetransmissionsReceived         uint64
    RetransmissionsSent             uint64
    ConsentRequestsSent             uint64
    ConsentExpiredTimestamp         StatsTimestamp
    
    // Circuit breaker
    CircuitBreakerTriggerCount      uint32
}
Example
stats := pc.GetStats()
for _, stat := range stats {
    if pair, ok := stat.(webrtc.ICECandidatePairStats); ok && pair.Nominated {
        fmt.Printf("Active Candidate Pair:\n")
        fmt.Printf("  State: %s\n", pair.State)
        fmt.Printf("  RTT: %.3f ms\n", pair.CurrentRoundTripTime * 1000)
        fmt.Printf("  Bytes sent: %d, received: %d\n",
            pair.BytesSent, pair.BytesReceived)
        fmt.Printf("  Available bitrate: out=%.0f, in=%.0f bps\n",
            pair.AvailableOutgoingBitrate, pair.AvailableIncomingBitrate)
    }
}

ICECandidateStats

Statistics for an ICE candidate.
type ICECandidateStats struct {
    Timestamp            StatsTimestamp
    Type                 StatsType
    ID                   string
    TransportID          string
    
    NetworkType          string  // Deprecated
    IP                   string
    Port                 int32
    Protocol             string
    CandidateType        ICECandidateType
    Priority             int32
    URL                  string
    RelayProtocol        string
    Deleted              bool
}
Example
stats := pc.GetStats()
for _, stat := range stats {
    if candidate, ok := stat.(webrtc.ICECandidateStats); ok {
        fmt.Printf("Candidate %s:\n", candidate.ID)
        fmt.Printf("  Type: %s\n", candidate.CandidateType)
        fmt.Printf("  Address: %s:%d\n", candidate.IP, candidate.Port)
        fmt.Printf("  Protocol: %s\n", candidate.Protocol)
        if candidate.RelayProtocol != "" {
            fmt.Printf("  Relay Protocol: %s\n", candidate.RelayProtocol)
        }
    }
}

Transport Statistics

TransportStats

Statistics for the ICE/DTLS transport.
type TransportStats struct {
    Timestamp                StatsTimestamp
    Type                     StatsType
    ID                       string
    
    PacketsSent              uint32
    PacketsReceived          uint32
    BytesSent                uint64
    BytesReceived            uint64
    
    RTCPTransportStatsID     string
    ICERole                  ICERole
    DTLSState                DTLSTransportState
    ICEState                 ICETransportState
    SelectedCandidatePairID  string
    LocalCertificateID       string
    RemoteCertificateID      string
    DTLSCipher               string
    SRTPCipher               string
}
Example
stats := pc.GetStats()
for _, stat := range stats {
    if transport, ok := stat.(webrtc.TransportStats); ok {
        fmt.Printf("Transport:\n")
        fmt.Printf("  ICE State: %s\n", transport.ICEState)
        fmt.Printf("  DTLS State: %s\n", transport.DTLSState)
        fmt.Printf("  DTLS Cipher: %s\n", transport.DTLSCipher)
        fmt.Printf("  SRTP Cipher: %s\n", transport.SRTPCipher)
        fmt.Printf("  Total bytes: sent=%d, received=%d\n",
            transport.BytesSent, transport.BytesReceived)
    }
}

CertificateStats

Statistics for a certificate used by an ICE transport.
type CertificateStats struct {
    Timestamp               StatsTimestamp
    Type                    StatsType
    ID                      string
    
    Fingerprint             string
    FingerprintAlgorithm    string
    Base64Certificate       string
    IssuerCertificateID     string
}

Data Channel Statistics

DataChannelStats

Statistics for a data channel.
type DataChannelStats struct {
    Timestamp               StatsTimestamp
    Type                    StatsType
    ID                      string
    
    Label                   string
    Protocol                string
    DataChannelIdentifier   int32
    TransportID             string
    State                   DataChannelState
    
    MessagesSent            uint32
    BytesSent               uint64
    MessagesReceived        uint32
    BytesReceived           uint64
}
Example
stats := pc.GetStats()
for _, stat := range stats {
    if dc, ok := stat.(webrtc.DataChannelStats); ok {
        fmt.Printf("DataChannel '%s':\n", dc.Label)
        fmt.Printf("  State: %s\n", dc.State)
        fmt.Printf("  Messages: sent=%d, received=%d\n",
            dc.MessagesSent, dc.MessagesReceived)
        fmt.Printf("  Bytes: sent=%d, received=%d\n",
            dc.BytesSent, dc.BytesReceived)
    }
}

SCTPTransportStats

Statistics for the SCTP transport used by data channels.
type SCTPTransportStats struct {
    Timestamp               StatsTimestamp
    Type                    StatsType
    ID                      string
    TransportID             string
    
    SmoothedRoundTripTime   float64
    CongestionWindow        uint32
    ReceiverWindow          uint32
    MTU                     uint32
    UNACKData               uint32
    BytesSent               uint64
    BytesReceived           uint64
}

PeerConnection Statistics

PeerConnectionStats

Statistics for the overall peer connection.
type PeerConnectionStats struct {
    Timestamp               StatsTimestamp
    Type                    StatsType
    ID                      string
    
    DataChannelsOpened      uint32
    DataChannelsClosed      uint32
    DataChannelsRequested   uint32
    DataChannelsAccepted    uint32
}

Additional Statistics Types

AudioPlayoutStats

Statistics for audio playout path.
type AudioPlayoutStats struct {
    Timestamp                   StatsTimestamp
    Type                        StatsType
    ID                          string
    Kind                        string
    
    SynthesizedSamplesDuration  float64
    SynthesizedSamplesEvents    uint64
    TotalSamplesDuration        float64
    TotalPlayoutDelay           float64
    TotalSamplesCount           uint64
}

RTPContributingSourceStats

Statistics for a contributing source (CSRC).
type RTPContributingSourceStats struct {
    Timestamp              StatsTimestamp
    Type                   StatsType
    ID                     string
    
    ContributorSSRC        SSRC
    InboundRTPStreamID     string
    PacketsContributedTo   uint32
    AudioLevel             float64
}

Sender and Receiver Statistics

type AudioSenderStats struct {
    Timestamp                   StatsTimestamp
    Type                        StatsType
    ID                          string
    TrackIdentifier             string
    RemoteSource                bool
    Ended                       bool
    Kind                        string
    
    AudioLevel                  float64
    TotalAudioEnergy            float64
    VoiceActivityFlag           bool
    TotalSamplesDuration        float64
    EchoReturnLoss              float64
    EchoReturnLossEnhancement   float64
    TotalSamplesSent            uint64
}

Utility Functions

UnmarshalStatsJSON

Unmarshals a Stats object from JSON.
func UnmarshalStatsJSON(b []byte) (Stats, error)
Parameters
b
[]byte
required
JSON-encoded statistics object
Returns
Stats
Stats
The unmarshaled statistics object (specific type based on the “type” field)
error
error
Error if unmarshaling fails or type is unknown
Example
jsonData := []byte(`{
    "type": "inbound-rtp",
    "id": "RTCInboundRTPVideoStream_12345",
    "timestamp": 1234567890.0,
    "ssrc": 12345,
    "kind": "video",
    "packetsReceived": 1000,
    "bytesReceived": 500000
}`)

stat, err := webrtc.UnmarshalStatsJSON(jsonData)
if err != nil {
    log.Fatal(err)
}

if inbound, ok := stat.(webrtc.InboundRTPStreamStats); ok {
    fmt.Printf("Received %d packets\n", inbound.PacketsReceived)
}

Common Patterns

Monitoring Connection Quality

func monitorConnectionQuality(pc *webrtc.PeerConnection) {
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        stats := pc.GetStats()
        
        // Find active candidate pair
        for _, stat := range stats {
            if pair, ok := stat.(webrtc.ICECandidatePairStats); ok && pair.Nominated {
                fmt.Printf("RTT: %.0f ms, Bitrate: %.0f kbps\n",
                    pair.CurrentRoundTripTime * 1000,
                    pair.AvailableOutgoingBitrate / 1000)
            }
        }
        
        // Check video quality
        for _, stat := range stats {
            if inbound, ok := stat.(webrtc.InboundRTPStreamStats); ok && inbound.Kind == "video" {
                if inbound.PacketsReceived > 0 {
                    total := uint32(int32(inbound.PacketsReceived) + inbound.PacketsLost)
                    lossRate := float64(inbound.PacketsLost) / float64(total) * 100
                    fmt.Printf("Video Loss Rate: %.2f%%\n", lossRate)
                }
            }
        }
    }
}

Exporting Stats to JSON

func exportStats(pc *webrtc.PeerConnection) ([]byte, error) {
    stats := pc.GetStats()
    return json.MarshalIndent(stats, "", "  ")
}

Calculating Bitrates

type BitrateCalculator struct {
    lastStats     webrtc.InboundRTPStreamStats
    lastTimestamp time.Time
}

func (bc *BitrateCalculator) Calculate(current webrtc.InboundRTPStreamStats) float64 {
    now := current.Timestamp.Time()
    
    if bc.lastTimestamp.IsZero() {
        bc.lastStats = current
        bc.lastTimestamp = now
        return 0
    }
    
    deltaBytes := current.BytesReceived - bc.lastStats.BytesReceived
    deltaTime := now.Sub(bc.lastTimestamp).Seconds()
    
    bc.lastStats = current
    bc.lastTimestamp = now
    
    if deltaTime > 0 {
        return float64(deltaBytes) * 8 / deltaTime // bits per second
    }
    
    return 0
}

See Also

Build docs developers (and LLMs) love