Recent Performance Gains in Experience Chat

Hi Creators,

We are back with another update on Experience Chat performance and stability! As you know, Experience Chat, powered by TextChatService, is essential for many experiences on Roblox, allowing users to directly communicate with each other in real-time and feel more immersed in your experience. TextChatService is a powerful tool which can help you customize the chat’s appearance, add experience-specific commands or messages and more! We’ve also recently rolled out Experience Chat for Playstation and Xbox, helping you connect with a wider range of users.

Since April, we’ve implemented 11 changes, aimed at improving the amount of frame time Experience Chat consumes. Each of these improvements has been tested in weeks-long individual experiments to ensure positive impact. Check out our previous updates on performance here and here.

Beyond these individual changes, we’ve also measured the combined impact of these changes on engagement. When comparing user groups who received all the performance updates against those without, we’ve observed significant lifts to the number of messages sent and number of Experience Chat users. These results clearly demonstrate that our investments in Experience Chat performance are delivering tangible impact to the platform.

Background section expandable for curious minds…

Measuring and Improving Chat Performance

In order for devices to maintain a steady frame rate of 60 frames per second, they have a strict 16 milliseconds (ms) for all operations. Within Roblox, we are prioritizing minimizing the amount of frame time the core platform needs, especially for our internal Luau CoreScripts and Core UI, which use the React-lua framework. We’ve been tracking Avg P95 React Frame Time for Experience Chat because it describes how much of our time is spent in our UI code running Luau itself. It is calculated by measuring the milliseconds of work done by React for and dividing that duration by the total number of frames within the last 30 seconds. To make it more relevant, we only look at the slowest 5%. It also allows us to scale and measure both absolute and relative improvements across all experiences and device types.

Most notably, since we’ve started tracking this metric and improving performance, we’ve decreased the Avg P95 React Frame Time for Experience Chat on Android by around 69% (Android as a device type has been most sensitive to improvements since it supports the widest margin of device capabilities and constraints).

The following table is a historic record of Avg P95 React Frame Time for Experience Chat. It details how we have observed improvements across all measured device types since March.\

P95 React Frame Time for Experience Chat

Platform March 1 March 1st to April 1st April 2nd to July 1st March 2025 to now total percent change
Windows 0.96ms 0.49ms (-49%) 0.27ms (-45%) -72%
OSX 0.59ms 0.30ms (-49%) 0.19ms (-37%) -68%
Android 1.98ms 0.95ms (-52%) 0.61ms (-36%) -69%
iOS 0.36ms 0.22ms (-39%) 0.16ms (-27%) -56%
Console N/A 0.18ms 0.14ms (-22%) -22%

Microprofiler Missattributions

We know many of you rely on the Microprofiler to understand how your experience performs within a snapshot of time, under specific device conditions and we use it constantly to validate our own improvements as well. However we’ve seen some inconsistencies with how frame time is attributed to Experience Chat, which can make performance analysis tricky.
This challenge stems from our shared React scheduler, which many Core UI React surfaces use. Since the Microprofiler doesn’t fully see the scheduler’s internal operations, React UI updates can be mislabeled, often appearing under tags like ExperienceChatMain, SchedulerHostConfig.default, TopBar, or $Script.

We’re actively working with internal teams to improve work attribution for both React and non-React cases, aiming to provide you with more accurate and insightful Microprofiler data.
When sending a message in a popular Roblox experience for example, we were able to verify that both average and max frame time was decreased on a Mac. Internally we were able to fix the misattributions in the Microprofiler to calculate these differences.

Before:

After:

Key Fixes and Their Impact (Since April 2025)

In general our improvements have focused on minimizing unnecessary UI updates and optimizing data flow. Here are some key changes:

  • Reduced Unnecessary UI Updates: A major focus has been on preventing Luau UI components from doing work when the end result is unchanged. Specific target areas include improvements to bubble chat, voice speaker bubbles and the main chat window.
  • Optimized State Management: Our chat UI handles a lot of player, text, and voice state. We’ve made substantial gains by transitioning to a more efficient state management system. This is an ongoing effort and we expect to see more gains when we complete the migration of various text chat and voice related states to this new pattern.
  • Zero Cost for Unused Features: We want to ensure that features not enabled by developers consume no frame time. We addressed instances where the chat service consumed frame time even when disabled. For example, when a developer invokes StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, false) or when a user hides the Chat by interacting with the top bar, we now do less work since the ChatWindow will not need to be updated in either case.

Next Steps

While we see welcome improvements, there’s still more work to do. We are happy to see lower frame time averages but developers are still reporting spikes that occur on receiving or sending of messages, and we are continuing to investigate as a result.

We are actively fixing a backlog of issues related to TextChatService. We appreciate your patience and thank you for reporting issues in this space. Your feedback is invaluable, as we are actively listening and iterating on Experience Chat. Please share your thoughts and suggestions below!

166 Likes

This topic was automatically opened after 10 minutes.

finally, slowly becoming more viable to use textchatservice

34 Likes

Surprised it wasn’t like this already, either way nice to have better performance.

26 Likes

Weird that Windows is worse than most of other platforms, especially consoles, where chat not existed for long at all. Why it’s like that though?

11 Likes

This is my armchar guess: windows likely has a wider variety of ages and capabilities of hardware in that pool. Consoles on the other hand are much more standardized on which hardware is used

Since this is P95, there’s likely more variance on windows as a result

19 Likes

I don’t think that they make this measures on regular user’s data, because a lot of people use potato devices (like me). In this case, results will be bad.

9 Likes

On this topic, could you confirm that chat bubbles now also have zero cost when disabled?

We used to experience pretty significant overhead, especially when custom characters did not have the default expected chat root part.

7 Likes

can someone debunk (or bunk) these claims cause roblox sure does like to overexaggerate things

13 Likes

The “P95 React Frame Time for Experience Chat” metric is based off of real world data. We sample from a small percentage of population at any given time. The results are not as fine-grained as what the microprofiler measures but is more accurate for measuring the cost of our Core UI and much more lightweight.

EDIT: I want to add, this is precisely why this metric was created. Our previous method of testing performance fixes via the microprofiler relied on creating stress tests for specific scenarios and then running those on a representative sample of devices. We found that, although we increased performance in those specific scenarios on those specific devices, the impact on player device and on dev created experiences was very different. Now we have insight to how an optimization actually performs in the wild and can iterate and pivot much more quickly and accurately.

23 Likes

Really, really glad that Roblox is focusing on developer concerns. I was worried it would take years for any changes to occur.

Could we have any info on whether the microprofiler changes/misattribution errors will change anything developer-facing? More control would always be nice!

13 Likes

As far as I’m aware, the microprofiler should be accurate for dev-specific metrics. The misattribution problem seems to be exclusive to our CoreUI that use react. It is possible that you will run into similar issues if you use react-lua but I haven’t personally tested that so I can’t comment. We are working on a fix for this but it may take a few weeks to land

4 Likes

I’m glad you’re focused on making TextChatService perform better, will the TopBar, PlayersList and even the Menu will have better performance in the future?

3 Likes

This is how it looks like on a Doors server with a lot of players (around 35/40 or so) with a lot of chatting going on.

microprofile-20250709-221748.html (5.8 MB)

Spikes at the worst cases before used to peak at 15ms, now it seems to max out at 5ms, so there are improvements here. But I would like to see more improvements, specifically for these spikes to be ironed out completely. There is absolutely no reason for the chat to for example, use ~1ms frame time every frame and then suddenly jump at ~5ms later at once.

This is captured on my laptop which could be considered between low-end and mid-range, things look a lot worse on my low-end Samsung Galaxy M12 mobile phone. I think it’s always the best to see how performant and optimized things are when you test them on the least powerful supported devices.

What is it about anyways?

5 Likes

Unfortunately bubble chat still has some cost even when the feature is disabled. Fortunately from our estimates, that work seems to account for ~0.1ms per message sent (at least on my machine), or less than 10% of the cost of rendering the message to the ChatWindow.

There is some underlying work currently in progress that needs to get done before we can remove that cost (related to the “Optimized State Management” entry). That said, this is a priority for us and we want to fix this as soon as possible

8 Likes

How about more customisation?

The Chat window’s size can’t be made wider
&
Bubble Chat’s size, proportions and tail can’t be customised

Just to name a few.

8 Likes

Thanks for taking the time to reprofile. Doors in particular has been useful in validating our progress up to this point.

We primarily addressed the “average time spent in React” – now that we’re seeing larger reductions, the spikier behavior is becoming easier to measure now that our baseline is less noisy. Going forward, we are additionally tracking a “max frame time” metric that better accounts for the spikes and we will be turning our attention to improving this metric as well as the average time spent.

Yeah, there are other opportunities in CoreGui-land and we do have other teams focusing on these specific areas right now.

ExperienceChat is the most complicated and largest CoreGui and we felt like this deserved its own callout – especially since we recently had the previous removal of Legacy chat we want to be as transparent and open about progress here as we can.

15 Likes

Had my fair share of performance complaints on TextChatService and so did my player base making it a tough sell for an extremely long time.

Anecdotally these improvements have been well received, but there is still room for more on CoreGUI as a whole.

Can we expect to stay informed on developments the other teams are making on other aspects of CoreGUI through a follow up post or on the release notes?

6 Likes

Lots of future improvements we will want to properly test over a few weeks which makes release notes not the best vehicle for these updates – if the tests don’t provide solid results we will not ship them (we had a few changes that fit this description… the 11 changes that the OP references are the successful experiments… (though with adjustments the unsuccessful changes will likely be retested in following weeks)).

It’s a very methodical and careful process, however making guarantees is hard.
That said, I personally wouldn’t be surprised if we have at least another additional follow up announcement thread for CoreGui before the end of the year.

11 Likes

It’s great to finally see progress on the performance optimizations for core UI! I especially appreciate the performance measurement comparisons laid out here, without them sometimes it’s easy to be a bit skeptical when a performance win is claimed.

One aspect that I’m sure you guys are aware of but I would especially like to see is not just CPU time, but memory usage of React-based core UI. On my iPad Air 1st generation (which has 1gb ram, ~600-650mb usable before app crashes), I’ve consistently seen ridiculous amounts of memory being hogged up by core UI. I’m talking in the order of multiple hundreds of megabytes. It’s an appalling state, to the point where if you were to join a blank baseplate, the device is already maxing out its available memory with absolutely nothing going on, and the poor engine is trying its best to squeeze out every drop of memory it can out of every texture.

One thing I would suggest is maybe loading up the React states as needed, so for example, the React state tree for the escape menu should be initialized when you press escape and open the menu, and when you close said menu, it is de-initialized and GC’d. I know this is a tradeoff between UI responsiveness and baseline memory consumption, but the current state of core UI memory usage might necessitate something along these lines.

Here are some notes I took back in March of this year about several sources contributing to baseline memory usage (as in, memory usage that cannot be scaled down by either the engine OR the developer. If these items alone add up to more memory than the device can afford, the engine is entirely helpless to scale things back and will just crash instantly):

CoreScript and CoreGui Memory (with all disable-able things disabled including chat, leaderboard, etc):

corescripts and coregui memory usage is a baseline of 90mb for corescriptmemory with all developer-disableable coreguis disabled. the 90mb figure gets even worse if you look at luaheap, where it is in the range of 150-240mb for an entirely empty game (controlscript and camerascript overloaded, character spawning disabled, nothing in workspace)

Fallback Font Memory (probably extended character sets for different languages):

fonts alone take up over 50mb of memory (this is because of a couple fallback fonts that presumably contain a boatload of glyphs for supporting all the different languages and character systems)

  • you have no way to disable this, even if you game has all the translation features disabled
  • roblox will attempt to scale its memory usage by making all the textures in the game completely unusable (even the roblox ui itself becomes totally unreadable), impressively with this level of scaling the texture usage is brought down to a mere 1-2mb, but the engine is utterly helpless when it comes to stuff like fonts, which is has no way of scaling font memory usage
  • so while we’re sitting here with literally 70mb of completely useless font information, you cant even display a single 128x128 texture without it being destroyed to literally 16x16 and under

ShadowMap lighting data even when shadowmaps aren’t rendering (like at graphics 1):

another very interesting observation i’ve made is that if you game has its lighting set to shadowmaps, even if the player’s device is set to low graphics where shadowmaps get disabled, the memory reserved for shadowmaps remains. in a completely empty place, i measured a baseline of 20mb for shadowmaps even on graphics 1

  • so if you really really care about memory usage specifically, setting your game to voxel lighting can save 20mb! but this is obviously not a good recommendation because it compromises the experience for literally everyone except the poor shmucks on a 1gb ram device
16 Likes