Skip to content

Comments

perf: remove unnecessary stack trace capture in promiseTimeout and delayCancellable#2270

Open
jlucaso1 wants to merge 2 commits intomasterfrom
perf-remove-stack-trace
Open

perf: remove unnecessary stack trace capture in promiseTimeout and delayCancellable#2270
jlucaso1 wants to merge 2 commits intomasterfrom
perf-remove-stack-trace

Conversation

@jlucaso1
Copy link
Collaborator

promiseTimeout() and delayCancellable() capture stack traces via new Error().stack on every call, causing CPU overhead from source map parsing. These functions are called in hot paths (every WebSocket message, query, etc.).

Benchmark Results

Benchmark: 5000 ping/pong messages received and sent back.

CPU Profile Comparison

Function Before After Improvement
serializeJSStackFrame ~1.0% 0% Eliminated
promiseTimeout ~0.6% 0.02% 30x reduction

Memory Profile

Metric Before After
Source map allocations from stack capture ~2.5 MB 0 MB
serializeJSStackFrame in heap Present Gone

Proof: Boom has native .stack

Boom creates native Error instances and calls Error.captureStackTrace(). The .stack property is preserved.

From Boom API docs:

Creates a new Boom object. Decorates the error with Boom properties using boomify().

const Boom = require('@hapi/boom');
const err = new Boom.Boom('Test', { statusCode: 500 });
console.log('stack' in err);        // true
console.log(err instanceof Error);  // true

@whiskeysockets-bot
Copy link
Contributor

whiskeysockets-bot commented Jan 18, 2026

Thanks for opening this pull request and contributing to the project!

The next step is for the maintainers to review your changes. If everything looks good, it will be approved and merged into the main branch.

In the meantime, anyone in the community is encouraged to test this pull request and provide feedback.

✅ How to confirm it works

If you’ve tested this PR, please comment below with:

Tested and working ✅

This helps us speed up the review and merge process.

📦 To test this PR locally:

# NPM
npm install @whiskeysockets/baileys@WhiskeySockets/Baileys#perf-remove-stack-trace

# Yarn (v2+)
yarn add @whiskeysockets/baileys@WhiskeySockets/Baileys#perf-remove-stack-trace

# PNPM
pnpm add @whiskeysockets/baileys@WhiskeySockets/Baileys#perf-remove-stack-trace

If you encounter any issues or have feedback, feel free to comment as well.

@jlucaso1 jlucaso1 force-pushed the perf-remove-stack-trace branch from d37cd72 to 9526d74 Compare January 20, 2026 12:12
rsalcara pushed a commit to rsalcara/InfiniteAPI that referenced this pull request Feb 2, 2026
…s#2270 performance optimization

This commit addresses two critical issues identified in post-implementation review:

## Issue 1: Hosted JIDs in Interactive Messages (REVERTED) ⚠️

**Problem**: Previous changes included hosted JIDs (@HosteD, @hosted.lid) in bot node
injection logic for interactive messages, which could interfere with carousel, list,
and button delivery to hosted accounts.

**Changes**:
- Reverted `isAnyPnUser/isAnyLidUser` to `isPnUser/isLidUser` in messages-send.ts:172
- Reverted bot node logic for interactive messages (lines 1249-1251)
- Added explicit comment: "Only for regular JIDs, NOT hosted JIDs"

**Impact**:
- ✅ Zero interference with interactive messages (buttons, lists, carousels)
- ✅ Maintains original behavior for hosted JIDs
- ✅ Bot node only injected for regular PN/LID JIDs

## Issue 2: Performance - Implement PR WhiskeySockets#2270 🚀

**Problem**: Unnecessary stack trace capture in hot code paths causing:
- ~1.0% CPU overhead in `serializeJSStackFrame`
- ~0.6% CPU overhead in `promiseTimeout`
- ~2.5 MB memory allocation for source maps

**Changes in src/Utils/generics.ts**:
- Removed `const stack = new Error().stack` from `delayCancellable()` (line 131)
- Removed `const stack = new Error().stack` from `promiseTimeout()` (line 161)
- Removed stack data from Boom error constructors
- Added comments explaining Boom's native stack capture

**Rationale** (from Baileys PR WhiskeySockets#2270):
> Boom creates native Error instances and calls Error.captureStackTrace().
> The .stack property is preserved automatically without manual capture.
> Reference: https://hapi.dev/module/boom/api/?v=10.0.1

**Performance Gains**:
- `serializeJSStackFrame`: ~1.0% → 0% CPU (eliminated)
- `promiseTimeout`: ~0.6% → 0.02% CPU (30x faster)
- Memory: ~2.5 MB source map allocations freed

**Testing**:
- ✅ All generics tests passing
- ✅ Boom error handling preserved
- ✅ Stack traces still available via Boom's native Error

Related:
- Addresses concerns from implementation review
- Implements Baileys PR WhiskeySockets#2270 performance optimization
- Maintains compatibility with interactive messages

https://claude.ai/code/session_0149ZKk2ygmKCJTGu39Mr8oH
@rsalcara
Copy link

rsalcara commented Feb 2, 2026

Hi @jlucaso1, everything good? I implemented this PR in my fork. and obtained the results below.

📊 Performance Impact
Before (without PR):
1,000 contacts to map:
├─ getLIDsForPNs: 1,000 individual queries
├─ getPNsForLIDs: did not exist
├─ Store: 2,000 queries (read + write)
├─ Stack traces: +1.6% CPU overhead
└─ Total: ~5,000ms + 2.5 MB RAM

⚠️ Total: 3,000+ DB queries

After (PR):
1,000 contacts to map:
├─ getLIDsForPNs: 1 batch query
├─ getPNsForLIDs: 1 batch query
├─ Store: 2 queries (1 read + 1 write) write)
├─ Stack traces: 0% overhead
└─ Total: ~150ms + 0 MB extra

✅ Total: 4 DB queries

🚀 Speedup: 33x faster
💾 Memory: -2.5MB
🔋 CPU: -1.6%

@jlucaso1
Copy link
Collaborator Author

jlucaso1 commented Feb 2, 2026

@rsalcara What? This isn't to reduce database queries. It's just to reduce overhead when generating errors.
And these numbers were obtained in my benchmark:

💾 Memory: -2.5MB
🔋 CPU: -1.6%

How do you run this benchmark heuristic?

@rsalcara
Copy link

rsalcara commented Feb 2, 2026

Hi @jlucaso1!
I incorrectly posted the combined results of all 3 PRs in this PR's thread,
making it seem like the database improvements came from your
stack trace optimization. They didn't — they came from the batching PRs.

Your PR #2270 correctly focuses on error generation overhead, not database queries.

Sorry for the confusion! The stack trace removal works perfectly and delivers
exactly what you described. 👍

@github-actions
Copy link
Contributor

This PR is stale because it has been open for 14 days with no activity. Remove the stale label or comment or this will be closed in 14 days

@github-actions github-actions bot added the Stale label Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants