Using delay() VS coroutines?

Brushing up on my Lua and I found a built-in Roblox global delay(). It looks like it’s the same thing as starting a coroutine with wait(x). Is there a difference, and is one preferable over the other?

Edit: Here’s a great resource.

Thanks for the insight, everyone!
-Ethan

Both have their benefits, but it’s generally better to use coroutines as they run instantaneously, rather than delay having to be reliant on the scheduler (coroutines are much harder to debug than delay if I recall correctly).

wait() is bad to use in general

1 Like

No.

Let’s talk about wait(). Not wait(n)

2 Likes

wait(n) is still bad to use either way

And why is that? Unless you want absolute perfect timing, wait(n) is perfectly fine.

4 Likes

usually when using delay you want it to be accurate and it was being compared to a coroutine with a wait so I am assuming you would want accuracy with the coroutine

besides wait(n) can even be seconds off or more sometimes and is unreliable

local start = os.clock()
delay(3, function()
	print("DELAY", os.clock() - start)
end)

local start = os.clock()
coroutine.wrap(function()
	wait(3)
	print("WRAP", os.clock() - start)
end)()

> DELAY 3.0058319000527
> WRAP 3.0060056999791

There is barely a difference.

This is only true if you are using wait() a lot of times in a short period of time.

2 Likes

A trick for a “custom” delay is using the RunService.Heartbeat event. I use this if I want a short delay and if I don’t want to clog up my coroutines. It’s just another method that I like using with other methods such as coroutines.

I like using this in a module that I can require from the client and server side so it isn’t repeated in multiple scripts.

function module:Delay(waitTime, andThen)
	local connection;
	local timeCount = 0;
	local allow = true;
	
	connection = RunService.Heartbeat:Connect(function(delta)
		timeCount += delta
		
		if timeCount >= waitTime and allow then
			allow = false;
			
			andThen()
			
			connection:Disconnect()
		end
	end)
end

Benchmarking under heavy script load and performance:
Delaying for 5 seconds:

Local Script: 4.9397112999999

Script: 4.8625788000005

IMPORTANT: Please remember to not just rely on this one method, and use a couple methods combined to get the best optimization possible. Use coroutine for important back-end code, and something like this for front-end code such as UI, Visual Effects, User Input, etc.

This method is also only efficient for very big projects which is what I tend to create. If you’re planning on making a small project that doesn’t have many events, delays, waits, coroutines, etc. then just keep using delay().

1 Like

Kampfkarren which made the post about wait literally said on Twitter that he doesn’t recommend wait(n) either, or using wait in general.


It seems like task.spawn is finally active for usage in production according to @loueque, so I’m using it instead of coroutine.wrap.

Also about wait, there’s also task.wait which runs off heartbeat which should be better than normal wait.

Also for wait there’s this custom wait function if you have heavy usage.

4 Likes

Yes. That’s where I got my inspiration from for my custom delay.

It’s still fine to use wait(n) if you’re creating a small project with little to waits in any scripts, but it’s always best to use a custom wait using RunService.

2 Likes

I think task.defer helps with this? I think that isn’t activated right now though. I’m not sure, my understanding is that deferred threads run after there is no code being ran.

Yep. If you’re working with server scripts most use cases on the server side it doesn’t matter how accurate it is, but usually it does on the client, like for instance an auto save is like whatever, but UI is different.

@PysephDEV has released this a long time ago, I haven’t tried it but it may help as a “custom task scheduler”.

1 Like

I linked it up there lol

It kind of does yeah, it’s really just a table but helps

I did mention an issue (which can or not be an issue to certain people) about it which just has really to do with it using os.clock which is really easy to fix, but overall it’s actually a great option if you REALLY NEED heavy wait usage

1 Like

I tend to make a ton of complex visual effects using meshes and parts and a custom yielding function helps a lot with getting something to happen right when I need it to, and with vfx there tends to be a ton of yielding usually.

If there’s any better resources out there than what @PysephDEV has released then I’d be interested to see them.

If you refer to the example I posted you can see that using wait(n) yields for pretty much 3 seconds, so in this case it would be fine. It all depends on what you are doing.

Thanks for the reply. That custom wait function should come in handy.

Thank you for the comprehensive reply. Appreciate it!