RocketChat / RocketChat/Rocket.Chat

channels.getAllUserMentionsByChannel fetches all mentions into memory to compute total count performance regression

Open
#38,908 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: bug valid
Dominant language
TypeScript
Stars
46.1k
Forks
13.9k
Avg merge
3d 3h
Merged PRs (30d)
130

Description

Description

The GET /api/v1/channels.getAllUserMentionsByChannel endpoint calls getUserMentionsByChannel twice per request — once for the paginated result and a second time without skip/limit only to compute the total.

This causes all mention documents in the channel to be loaded into application memory, even though only .length is used. This introduces unnecessary memory allocation, database load, and latency.

File:
apps/meteor/app/api/server/v1/channels.ts (lines 436–449)

// Paginated fetch — correct
const mentions = await getUserMentionsByChannel(this.userId, roomId, {
    sort: sort || { ts: 1 },
    skip: offset,
    limit: count,
});

// Fetches ALL mentions just for .length — problematic
const allMentions = await getUserMentionsByChannel(this.userId, roomId, {});

return API.v1.success({
    mentions,
    count: mentions.length,
    offset,
    total: allMentions.length, // only .length is used
});

All other paginated endpoints in this file (such as channels.messages, channels.members, and channels.files) use findPaginated or countDocuments() to compute totals efficiently.
This endpoint appears to be the sole outlier.


Steps to reproduce
  1. Create a public channel
  2. Generate a large number of user mentions in the channel (e.g., 5000+)
  3. Call
GET /api/v1/channels.getAllUserMentionsByChannel?roomId=<id>&count=25&offset=0
  1. Monitor server memory usage and response time

Expected behavior

The endpoint should obtain the total mention count using a countDocuments() query (or the existing findPaginated pattern), without loading all mention documents into memory.

Response time and memory usage should remain stable regardless of the total number of mentions.


Actual behavior

The endpoint fetches all mention documents from MongoDB into a JavaScript array (allMentions) on every request, then discards everything except .length.

In channels with thousands of mentions this results in:

  • O(n) memory allocation per API call
  • ~2× database load (two full queries instead of one query + one count)
  • Increased response latency proportional to total mentions

Additional context

Affected endpoint:
GET /api/v1/channels.getAllUserMentionsByChannel

Suggested fix:

Replace the second getUserMentionsByChannel call with:

  • a dedicated countDocuments() query, or

  • refactor the endpoint to return { data, totalCount } using the same findPaginated pattern already used by:

  • channels.messages (line 329)

  • channels.members

  • channels.files


Relevant logs

No error-level logs are produced — this is a silent performance issue.

Diagnosis is based on source inspection:
channels.ts lines 436–449

Impact can be observed via APM/profiling tools monitoring:

  • MongoDB query counts
  • Node.js heap usage under load

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/meteor/app/api/server/v1/channels.ts at the getAllUserMentionsByChannel handler and compare its total calculation with the channels.messages, channels.members, and channels.files pagination patterns. Verify the endpoint obtains the total without loading every mention document, while preserving the mentions, offset, count, and total response fields. Check the endpoint under a channel with many mentions to confirm memory and latency no longer scale with the full result set.

Written by the indexing model from the issue text.

Assessment

Tech stack
mongodb, typescript
Domain
api, backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.