Skip to content

RTP NACK responder buffers not released after RemoveTrack/Stop (while PC still alive) #404

@ivanlukomskiy

Description

@ivanlukomskiy

Your environment.

  • Version: pion/interceptor v0.1.44; pion/webrtc v4.2.1
  • Go version: 1.25.5
  • Browser: any (it's a server-side issue)

Hi!

I use Pion in large-scale production. The app is video-only streaming from server to clients. Within a single connection users can subscribe and unsubscribe from video streams. There are hundreds of connections per pod and dozens of streams per connection.

It works great, but i got issues with large gradual growth of memory usage (several GB).

After profiling, i found out that the most of memory is occupied by NACK buffers of stopped streams.

If PC is closed, memory frees up, but in our setup we heavily reuse connections.

What did you do?

We enable NACK and RTCP interceptors like this:

webrtc.ConfigureNack(mediaEngine, interceptorRegistry)
webrtc.ConfigureRTCPReports(interceptorRegistry)
webrtc.ConfigureTWCCSender(mediaEngine, interceptorRegistry)

Streams are dynamically added/removed:

track, err := webrtc.NewTrackLocalStaticRTP(...)
transceiver, err := conn.AddTransceiverFromTrack(track, ...)
rtpSender := transceiver.Sender()

// later:
conn.RemoveTrack(rtpSender)
transceiver.Stop()
rtpSender.Stop()

Heap profiling (pprof, inuse_objects and inuse_space) shows the majority of memory retained in:

github.com/pion/interceptor/internal/rtpbuffer.(*PacketFactoryCopy).NewPacket
github.com/pion/interceptor/internal/rtpbuffer.NewPacketFactoryCopy.func2

What did you expect?

Removed tracks won't occupy large chunks of memory

What happened?

They do

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions