mikhailshilkov / mikhailio-hugo

Sources of https://mikhail.io migrated to Hugo
MIT License
12 stars 8 forks source link

Comments to "Cold Starts in Azure Functions" #3

Open mikhailshilkov opened 5 years ago

mikhailshilkov commented 5 years ago

Add your comment to Cold Starts in Azure Functions. The comments will be displayed directly on the page.

I might edit your mentions for better display on the website.

vitalybibikov commented 5 years ago

Hello, Mikhail.

Do you know, how often cold start happens, when function is warmed up by timer trigger/ availability test?

mikhailshilkov commented 5 years ago

I've seen it survive several days, but I don't have any statistics. I suppose such instance will be killed only when Microsoft wants to roll an update, do maintenance or other administrative tasks.

tomhundley commented 5 years ago

Hey. If you have 10 functions in the app, am I correct to assume that the cold start applies to overall app and not individual functions? For example, if one of the functions is a heartbeat function, does calling that function from the availability tests keep the other 9 functions warmed up as well? Thanks in advance.

mikhailshilkov commented 5 years ago

Yes, you are right.

So, it's quite common to add a function like this to any Function App with HTTP functions:

[FunctionName("Warmer")]
public static void WarmUp([TimerTrigger("0 */15 * * * *")]TimerInfo timer)
{
    // Do nothing
}
SoucianceEqdamRashti commented 5 years ago

Thanks for a nice article. By the way I noticed that v2 java functions sometimes have a cold start of 50 seconds. Is that something you have encountered as well?

mikhailshilkov commented 5 years ago

Honestly, I don't use Java functions in any real applications, so my dataset is limited to what I show in the article. It is a "Hello World" type of function with cold starts mostly in the range of 2 to 16 seconds. Does your "sometimes" mean for some functions (do they have a lot of dependencies) or rarely (1 out of 100 times won't show in my chart) or something else?

SoucianceEqdamRashti commented 5 years ago

@mikhailshilkov , it happens on every cold start. There are not that many dependencies, a few other java libs. It takes anywhere from 30-50 seconds to start.

mikhailshilkov commented 5 years ago

Would you be able to share a basic repro of this? A full Java function that I could deploy myself and see this issue?

rene78 commented 5 years ago

Hi mikhailshilkov, it is quite surprising to read, that zipping does not have any positive impact on the cold start times. For my simple node.js functions the cold start times went from >30s to around 6-10s. Was it your "Hello World" function, that you zipped or something with dependencies?

mikhailshilkov commented 5 years ago

I might be wrong but you might mean something else by zipping? I compare the deployment methods; the final deployment artifact is the same. Don't you mean something like webpack and tree shaking to reduce the size of the package? And yes, that was a Hello World from my side for that test. But that shouldn't matter.

rene78 commented 5 years ago

Hmmm... maybe I have a general misconception there. All I know is that I first wrote my functions (node.js with "Mongoose" as dependency) on the Azure portal with massive cold start times. Then I used the "Azure Functions" extension in VS Code. This extension automatically compresses the files (I suppose...) and sets RUN_FROM_PACKAGE=1, which improved cold start massively. Thus I wrote the message above.

ahmetsyildirim commented 5 years ago

Hi Mikhail, Thanks for the great article. In my case I have a timer trigger based Azure Function which runs a console app (.exe) inside. With my experience, size of the console app ( .exe and .dll files) and where it is located also affects the cold start time.

I don't have certatin metrics but I discovered that, If you have additional files in the same folder where your function.json sits (generally D:\home\site\wwwroot\), then the cold start takes longer.

Not sure, but I suspect that Azure Function host is trying to parse all the files under the path "D:\home\site\wwwroot\" during the cold start.

mikhailshilkov commented 5 years ago

Yes, I think it's a valid observation. Any increase in the package deployment size adds up.

murraybauer commented 4 years ago

What about premium blob performance to host the zip? How much is the cold start related to IO performance?

mikhailshilkov commented 4 years ago

I haven't tried premium, but standard Blob Storage is already pretty fast, several 10s of milliseconds at most. So I wouldn't expect a significant impact. I do not know why external zip adds several 100s of milliseconds to the cold start time.

pmonte commented 4 years ago

Do you know if there is a way to warm up the new instance before traffic is redirect to it when a consumption plan decides to scale up? i.e. something like this https://docs.microsoft.com/it-it/azure/azure-functions/functions-bindings-warmup?tabs=csharp for consumption plan

mikhailshilkov commented 4 years ago

As far as I know, such a feature doesn't exist.

MingLu8 commented 4 years ago

Hi Mikhail

Great article! Could you please provide some details on the zip file sizes and number of files in the zip for both C# and nodejs function apps.

Thanks

mikhailshilkov commented 4 years ago

Sorry for the slow response, somehow I missed your comment.

For the basic experiments, all deployment packages are effectively "Hello World" -- so the package size is minimal (1 KB for Node and I think ~3 MB for .NET zipped).

For the "Does Package Size Matter" section I used Node.js apps with higher number of NPM dependencies. You can see the exact dependencies: large is 14 MB zipped, and extra large is 35 MB zipped.

georgesymonds commented 4 years ago

Hi Mikhail,

First off, excellent article! Your results have encouraged me to move from PowerShell to C# for my Azure Functions development.

I had a question regarding the ability to compile C# functions as ReadyToRun binaries. Have you experimented with this at all, and if so, is there a noticeable difference in cold startup times?

mikhailshilkov commented 4 years ago

I haven't tried ReadyToRun yet, I should definitely add it to my tests, thanks for the reminder!

ThomasKeralla commented 4 years ago

Hi Mikhail. Great article, even though much have changed since you published. How did you identify the id of the function app when there is no context object as in AWS to get it from?

mikhailshilkov commented 4 years ago

Responded to your other comment regarding the ID: https://github.com/mikhailshilkov/mikhailio-hugo/issues/6#issuecomment-673092366

much have changed since you published

What do you think has changed since April? I can run the tests again if so.

mdarefull commented 4 years ago

Hello @mikhailshilkov, great article!

Consider Azure has already one server allocated and ready to run our function app. Will we experience a cold start when the amount of concurrent requests forces Azure to allocate a new server? Does this mean then that the warmup technique keeps just one server "alive", so it won't solve these scenarios?

mikhailshilkov commented 4 years ago

Yes to both. Cold starts would happen on any new allocated servers, and "warming" only keeps one instance.

pmonte commented 4 years ago

In my experience warming up is even more complicated and a real headache. Let's take a simple Azure Function on a Consumption plan with just one function .cs file. Let's call it Warmer.cs. It contains two methods:

public class WarmerFunction
    {
        [FunctionName("WarmUp")]
        public void WarmUp([TimerTrigger("0 */5 * * * *")] TimerInfo timer)
        {
            try
            {
                // some code, for example access DB via EF.
            }
            catch
            {
            }
        }

        [FunctionName("Pixel")]
        public FileContentResult Track([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Pixel")] HttpRequest req)
        {
            try
            {
                // exactly same code in WarmUp above
            }
            catch
            {
            }

            //return empty gif
            const string clearGif1X1 = "R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
            return new FileContentResult(Convert.FromBase64String(clearGif1X1), "image/gif");
        }
    }

I would expect that the GET to /Pixel is always warm. Unfortunately it is not, here it is a screenshot from Monitor pane in Azure Portal: image

Please be assured that WarmUp is running fine every 5 minutes (double checked).

So, to me, it looks like even if you warm up not only the plan, not only the function but down to the same .cs file, same namespace it is not enough. Does this mean that you should actually warm up every single method? Do you have any experience or feedback about this?

sadgit commented 3 years ago

Yes, you are right.

So, it's quite common to add a function like this to any Function App with HTTP functions:

[FunctionName("Warmer")]
public static void WarmUp([TimerTrigger("0 */15 * * * *")]TimerInfo timer)
{
    // Do nothing
}

We have experienced significant delay in first hits of various dependencies. I am about to make my warm-up hit my Cosmos connection and maybe do some other read-only tasks. Just to initialize any connection factories or singleton dependencies.

For premium plans there is now a warm-up trigger Azure Functions warm-up trigger

'Note that the warmup trigger is only called during scale-out operations, not during restarts or other non-scale startups.'

sadgit commented 3 years ago

@pmonte - you should look at creating a lazy or a singleton for the Pixel services - that way they will be preserved between calls. Some libraries can be very expensive to re-heat on every call.

chearmstrong commented 3 years ago

@mikhailshilkov Thanks for pointing me to your follow up post on cold starts. 👍 Have you (or anyone else) compared "run from package" + Webpack (single .js file, tree shaking, minification) vs. "run from package" without that? I can see you cover package size and "run from package" in your blog post, but it looks like separate things. Wondering if combining both will give better results.

See https://github.com/Azure/azure-functions-nodejs-worker/issues/340

shockstate commented 3 years ago

Is it possible that a TimerTrigger function doesn't trigger if the function app goes to sleep? Shouldn't warm up a server when it is time?

mikhailshilkov commented 3 years ago

It should not be possible. Scale Controller is aware of the timer trigger and should boot up an instance on a timer hit. Any miss like that is probably a bug somewhere when a Scale Controller doesn't know about the trigger.

shockstate commented 3 years ago

It should not be possible. Scale Controller is aware of the timer trigger and should boot up an instance on a timer hit. Any miss like that is probably a bug somewhere when a Scale Controller doesn't know about the trigger.

What about if it's in an App Service Plan that is not "Always On"? Should that still be the correct behaviour? I've read about it and seems that this would be the case in Consumption mode but maybe this changes in the free app service plan? Thanks for your response

mikhailshilkov commented 3 years ago

That might be the case, I'm not exactly sure about this scenario.

anil-rug commented 3 years ago

Hi @mikhailshilkov , Do you know how to induce a cold start to the Azure Functions. I am performing some benchmarking and would need the function to always have a cold start when the executed.

mdarefull commented 3 years ago

@anil-rug: A cold start occurs when Azure determines the function is no longer needed and deallocates it. The next time a request goes through Azure has to allocate resources and instantiate the function back, this process is similar to the cold starts that occur on a server when you hit the application after a deployment or after a while.

I don't think you can induce a cold start per-se. Probably the best you could do is restart the function app, but I'm not 100% convinced Azure would be deterministic in the way it handles that restart.

anil-rug commented 3 years ago

Thanks for the clarification. I tried restarting and redeploying the functions and they ran pretty quickly implying that the functions were still warm. I was able to do this exercise using AWS Lambdas by making a fake lambda update and the Lambda would have a cold start. I believe in Azure Functions as the functions run with WEBSITE_RUN_FROM_PACKAGE, the concept of how the function is allocated resources and dropped is quite vague :).

ngoquoc commented 2 years ago

Hi @mikhailshilkov , thanks for the great article. Do you maybe have any plan to update the test against Azure Function runtime v4, and C# 6?

mdarefull commented 2 years ago

Hi @mikhailshilkov, I've just wanted to share with you, after ~2 year of having discovered this article, how much I've referenced it as part of my work and with discussions with my peers.

I wanted to ask you if you have had the chance to compare using Linux Vs. Windows for hosting our app (.NET mainly). From a cold start perspective, it might seem Linux should be a better option than Windows but I wonder how many other differences could there be. I think memory overhead is lower on 32bit apps than on 64. i.e.: Smaller serverless apps will consume considerably less memory, but AFAIK Linux deployments only support 64bits. I think there are also some build tuning that you can apply when targeting Windows in .NET that you cannot for Linux.

Thoughts?

mikhailshilkov commented 2 years ago

There is a section on "Windows vs. Linux" - do you mean you want it to be extended further?

mdarefull commented 2 years ago

@mikhailshilkov: To write an article about "Windows vs. Linux" where is included more comparison points other than just Cold Starts. Ex.: Memory consumption, build optimization, performance, costs.

ChristianWeyer commented 1 year ago

Hey mate @mikhailshilkov :-)

are you planning to add information for ReadyToRun and also NativeAOT to the article (and to your tests)? Especially for C#/.NET with the latest .NET 7 runtime.

Thanks!

Cheers, Christian

mikhailshilkov commented 1 year ago

Hey @ChristianWeyer great to hear from you!

These blog posts are long due an update but it's a bit hard to find time for it. Thank you for a nag though!

ChristianWeyer commented 1 year ago

Hey @ChristianWeyer great to hear from you!

These blog posts are long due an update but it's a bit hard to find time for it. Thank you for a nag though!

BTW @mikhailshilkov : is the source code & tooling you use for the tests & benchmark also open source and documented?

ChristianWeyer commented 1 year ago

It surely would be nice to also have the Warmuptrigger for the Premium plan included in the comparison: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-warmup?tabs=isolated-process&pivots=programming-language-csharp

mikhailshilkov commented 1 year ago

is the source code & tooling you use for the tests & benchmark also open source and documented?

Yes, they are in https://github.com/mikhailshilkov/cloudbench