Skip to content

Conversation

@tanmaysharma2001
Copy link
Contributor

🔍 Description

This PR fixes a memory leak in RealtimeClient when using the worker: true option. Web Workers were being created during connection but never properly cleaned up during disconnection, leading to memory accumulation over time.

What changed?

  1. Added _terminateWorker() private method

    • Terminates the Web Worker when called
    • Clears the workerRef reference for garbage collection
    • Includes logging for debugging
  2. Updated _teardownConnection() method

    • Now calls _terminateWorker() during connection teardown
    • Ensures workers are properly cleaned up on disconnect
  3. Added test coverage

    • New test verifies workers are terminated on disconnect
    • Ensures workerRef is cleared after termination

Why was this change needed?

When using RealtimeClient with worker: true, each disconnect/reconnect cycle would create a new Web Worker without terminating the previous one. This caused:

  • Memory accumulation with orphaned workers
  • Workers continuing to send heartbeat messages even when disconnected
  • Potential performance degradation over time with multiple reconnections

The fix ensures proper worker lifecycle management by terminating workers during connection teardown.

Closes #1902

📸 Screenshots/Examples

Before: Workers were created but never terminated

// _teardownConnection() - line 628-649 (before fix)
private _teardownConnection(): void {
  // ... cleanup code
  this._clearAllTimers()
  this.channels.forEach((channel) => channel.teardown())
  // Worker never terminated - memory leak!
}

**After**: Workers are properly cleaned up
```typescript
// _teardownConnection() - line 628-650 (after fix)
private _teardownConnection(): void {
  // ... cleanup code
  this._clearAllTimers()
  this._terminateWorker()  // Worker properly terminated
  this.channels.forEach((channel) => channel.teardown())
}

🔄 Breaking changes

  • [☑️] This PR contains no breaking changes

📋 Checklist

  • [☑️] I have read the Contributing Guidelines
  • [☑️] My PR title follows the conventional commit format: <type>(<scope>): <description>
  • [☑️] I have run npx nx format to ensure consistent code formatting
  • [☑️] I have added tests for new functionality (if applicable)
  • [☑️] I have updated documentation (if applicable)

📝 Additional notes

Web Workers were created in _startWorkerHeartbeat() but never terminated
in _teardownConnection(), causing memory accumulation with each
disconnect/reconnect cycle.

This fix adds a _terminateWorker() private method that properly terminates
the Web Worker and clears the reference, then calls it during connection
teardown.

Fixes supabase#1902
@tanmaysharma2001 tanmaysharma2001 requested review from a team as code owners December 3, 2025 01:01
@coveralls
Copy link

coveralls commented Dec 3, 2025

Coverage Status

coverage: 95.367% (+14.2%) from 81.183%
when pulling 0949fc0 on tanmaysharma2001:fix/realtime-worker-memory-leak
into 8d1e0c5 on supabase:master.

@tanmaysharma2001
Copy link
Contributor Author

Hi @filipecabaco, I wanted to ask regarding the Label Issues and PRs check. I am not completely sure why is it failing. Is it something i need to fix from my side? Please let me know. Thank you 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Web Worker memory leak on disconnect

2 participants