Unused or internal built-in plugins are always loaded, causing excess memory usage

Studio Version: 582 Windows
I found out a inefficency in Studio that causes excess builtin plugin loading, resulting in a memory usage increase of 100s of megabytes.

Observation 1: No changes
Launch Studio as-is. Observe the commit charge on three actions:
Start page: 743,352 K

Opening A baseplate: 1,074,344 K

Pressing play: 1,684,352 K

Expected Behavior: Unused built-in or internal plugins shouldn’t have a impact on memory usage, as they are suppossed to be unloaded.

How are we going to figure out the actual behavior? Deleting said plugins.

Now let’s delete some of the secondary plugins that a scripter would use less, or are internal plugins that are unusable by anyone outside Roblox administrators. Go to the Studio install directory, BuiltInPlugins and then Optimized_Embedded_Signature. There are 51 files in there. We are going to delete 23 of them, that is either completely unused, in beta, or internal plugins.

List of plugins deleted
  • 9SliceEditor.rbxm - I don’t use it
  • AnimationClipEditor.rbxm - I am not a animator
  • AudioDiscovery.rbxm - The audio update has long passed, this is irrelevant
  • AvatarCompatibilityPreviewer.rbxm - I don’t use it
  • AvatarImporter.rbxm - I also don’t use it
  • BootcampPlugin.rbxm - Internal plugin
  • BulkFaceImporter.rbxm - I am not a UGC creator
  • CageMeshMigrationTool.rbxm - I don’t use it
  • CompositorDebugger.rbxm - Internal plugin
  • DeveloperInspector.rbxm - Internal plugin
  • DeveloperStorybook.rbxm - Internal plugin
  • DynamicHeadExportTool.rbxm - I am not a GFX artist
  • GuiDevEnv.rbxm - Internal plugin
  • InternalAvatarTools.rbxm - Internal plugin
  • LayeredClothingEditor.rbxm - I ain’t gonna use it
  • NestedPackagePublisher.rbxm - I am not gonna use it
  • R15Migrator.rbxm - I don’t have any R6 games
  • RigGenerator.rbxm - I am not gonna use it
  • RobloxClassic.rbxm - The plugin isn’t released at the moment
  • StyleEditor.rbxm - An internal plugin (?)
  • TagEditor.rbxm - I prefer scripting versus a editor
  • WindControl.rbxm - It’s in beta I think

These 23 plugins get deleted. The expected behavior is that the memory usage does not get reduced, if they are already delay-loaded. I have kept plugins that I am expected to use, or are already open.

Let’s measure memory again and see if it is really the case.

Observation 2: Trimmed down
Studio Launch: 652,116 K (down 89 MB)

Open a Baseplate: 924,872 K (down 146 MB)

Press Play: 1,385,528 K (down 292 MB)

The two measurements provided above are the same withnin margin of error.

I have also provided two other measurements, one of which the most extreme.

Measurement 3: 33 Plugins deleted
In this measurement, a further 10 less common plugins are deleted that are not used. This only leaves plugins to manage a universe with only 1 place, as long as you make everything yourself.

Studio Launch: 595,300 K (down 144 MB)
Open Baseplate: 787,260 K (down 280 MB)
Press Play: 1,160,932 K (down 524 MB)

Measurement 4: The whole BuiltinPlugins folder deleted
In this measurement to the extreme, Studio is being cut to the bare bones where even the dragger plugins are deleted. This makes Studio very light, but you can’t even move bricks.

Studio Launch: 532,884 K (down 205 MB)
Open Baseplate: 655,840 K (down 408 MB)
Press Play: 939,180 K (down 727 MB)

Actual Behavior: Deleting uncommon and internal plugins causes a memory usage reduction of up to 300 MB, suggesting that plugins are always loaded, even if completely unused

On a low-end device, this makes working on anything more than simple games to be harder due to thrashing.

Fix Suggestion: Don’t load applicable builtin plugins until the button to launch the plugin is clicked (this is called delay-loading).


This is a fantastic tip. An update undid this, so I wrote an AHK 2.0 script to disable built-in plugins for me, retaining only the essentials.
It’s also satisfying to disable garbage like the Transform dragger.

; AHK lacks anything like A_UserProfile or A_LocalAppData, so this assumes you're in C:\
dir := "C:\Users\" A_UserName "\AppData\Local\Roblox\Versions\*"

; Find last modified Studio folder
latestDir := ""
latestTime := 0
Loop Files dir, "D"
	time := FileGetTime(A_LoopFilePath)
	if time > latestTime && FileExist(A_LoopFilePath "\BuiltInPlugins")
		latestDir := A_LoopFilePath, latestTime := time

if !latestTime
	MsgBox "No latest Studio version dir found"

; Construct set of plugins to keep
set := Map()
Loop Parse "
# Draggers
# Useful
# Cloud-related
# Debugger.rbxm
# Toolbox.rbxm
)", "`n"
	set[A_LoopField] := 1

nMoved := 0

	; Need to declare that variable from above in order to access in a function (This is a good thing)
	global nMoved
	oes := plugins "\Optimized_Embedded_Signature"
	disabled := plugins "\Disabled"
	DirCreate disabled
	; Move all unkept plugins to another folder
	Loop Files oes "\*"
		if !set.Has(A_LoopFileName)
			FileMove(A_LoopFilePath, disabled), nMoved++

doDir latestDir "\BuiltInPlugins"
doDir latestDir "\BuiltInStandalonePlugins"

ToolTip "Moved " nMoved " files"
; Wait 2 seconds before exiting and wiping the tooltip
Sleep 2000

(edit: fixed blunder with untested moved file counter added just before submitting this post)

In order to lazy-load, plugins would need to create their buttons and actions first, i.e. they would have to load their code and execute first. This necessarily takes a little bit of memory.
Then they would have to delay initialization until the button/action is first used. I guess that a lot of the memory usage comes from data prepared on init even though it never gets realized (especially when playtesting).

1 Like

Thanks for the report! We’ll follow up when we have an update for you;


thank god lmao i was waiting for this