RocketChat / RocketChat/Rocket.Chat

Performance: Optimize sequential OEmbed fetching in rocketUrlParser to run concurrently

Open
#39,710 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Currently, the rocketUrlParser in the AfterSaveOEmbed hook processes message URLs sequentially using a for await...of loop. When a user sends a single message containing multiple external URLs, the server halts and waits for each parseUrl() HTTP request to completely resolve before initiating the next one.This creates an $O(N)$ network latency bottleneck. If a message contains 4 URLs, and each takes 1.5 seconds to respond, the thread is blocked for 6 seconds. Refactoring this to fetch the metadata concurrently (e.g., using Promise.all or Promise.allSettled) will reduce the total processing time to the duration of the single slowest request.

Steps to reproduce:

  1. Boot up a local Rocket.Chat development server.
  2. Ensure OEmbed/Link Previews are enabled in Administration -> Settings -> Message.
  3. Send a single message in any channel containing 4 or 5 different external URLs (e.g., various news articles or YouTube links).
  4. Trace the server execution logs or observe the response time. The URLs are fetched one after the other, causing a noticeable delay in processing the final message state.

Expected behavior:
The server should initiate the OEmbed HTTP requests for all valid URLs in the message array concurrently, drastically reducing the total time spent in the rocketUrlParser hook.

Actual behavior:
The server waits for parseUrl(item.url) to completely finish before starting the network request for the next URL in the array, creating a sequential blocking queue.

Server Setup Information:

  1. Version of Rocket.Chat Server: develop branch (Latest)
  2. License Type: Community
  3. Number of Users: Local Dev (1)
  4. Operating System: Linux/WSL
  5. Deployment Method: Local Development
  6. Number of Running Instances: 1
  7. DB Replicaset Oplog: Enabled
  8. NodeJS Version: 22.16.0
  9. MongoDB Version: 8.2.4

Client Setup Information
Desktop App or Browser Version: Chrome/Brave (Latest)
Operating System: Windows / Linux

Additional context
Target File: apps/meteor/app/lib/server/functions/hooks/AfterSaveOEmbed.ts
Target Function: rocketUrlParserI

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/lib/server/functions/hooks/AfterSaveOEmbed.ts at the rocketUrlParser function, especially the for await...of loop and its parseUrl(item.url) calls. Confirm that valid URLs are initiated concurrently while preserving the hook’s existing behavior, then verify that processing time is no longer the sum of each request’s latency.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, performance
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.