1. Python & JS 2. Go 3. C# & Java
I couldn't find any data on Rust.
The understanding at the time was that Python & JS runtimes are built-in, so the interpreter is "already running" Go is the fastest of compiled languages, but just can't beat the built-in runtimes. C# and Java were poorest as they're spinning up a larger runtime that's more optimized for long-running throughput.
https://docs.aws.amazon.com/lambda/latest/dg/best-practices....
https://medium.com/the-theam-journey/benchmarking-aws-lambda...
https://epsagon.com/development/aws-lambda-programming-langu...
https://read.acloud.guru/comparing-aws-lambda-performance-of...
Of course, benchmarks like this only go so far. Use as a starting point for your own evaluation; not as an end-all-be-all.
Laughs in data science.
> a 5 second boot time for a longer-lived service is acceptable.
Not every application can tolerate the occasional 5-second-long request. Just because Python can cold boot "hello world" 3 seconds faster than Go doesn't mean that's going to hold in the real world.
Using data science tooling in a lambda seems iffy, especially ones that are not production ready. And good luck getting such libraries in go.
Python cold booting an interpreter 3 seconds faster than Go is a big deal, especially if your target execution time is <50ms and you've got a large volume of invocations, and are not being silly and importing ridiculously heavy dependencies into a lambda for no reason other than to make a strange point about Python being unsuitable for something nobody should be doing.
Lambdas cold-start during requests. So the unlucky request that triggers a cold start eats that cold start.
> Using data science tooling in a lambda seems iffy, especially ones that are not production ready.
Nonsense, there are a lot of lambdas that just load, transform, and shovel data between services using pandas or whathaveyou. Anyway, don't get hung up on data science; it was just an example, but there are packages across the ecosystem that behave poorly at startup (usually it's not any individual package taking 1-2s but rather a whole bunch of them scattered across your dependency tree that take 100+ms).
> And good luck getting such libraries in go.
Go doesn't have all of the specialty libraries that Python has, but it has enough for the use case I described above.
> Python cold booting an interpreter 3 seconds faster than Go is a big deal, especially if your target execution time is <50ms and you've got a large volume of invocations
According to https://mikhail.io/serverless/coldstarts/aws/languages/, Go takes ~450ms on average to cold start which is still up a bit from Python's ~250ms. To your point, if you're just slinging boto calls (and a lot of lambdas do just this!) and you care a lot about latency, then Python is the right tool for the job.
> not being silly and importing ridiculously heavy dependencies into a lambda for no reason other than to make a strange point about Python being unsuitable for something nobody should be doing.
Not every lambda is just slinging API requests--some of them actually have to do things with data. Maybe someone is transforming a bit of audio as part of a pipeline or doing some analysis on a CSV or something else. Latency probably matters to them, but they still have to import things to get their work done. And according to https://mikhail.io/serverless/coldstarts/aws/#does-package-s... (at least for JavaScript) just 35mb of dependencies (which will buy you half of a numpy iirc) causes cold start performance to go from ~250ms to 4000ms.
My rule of thumb (based on some profiling) is that for every 30mb of Python dependency, the equivalent Go binary grows by 1mb, moreover, it all gets loaded at once (as opposed to resolving each unique import to a location on disk, then parsing, compiling, and finally loading it). Lastly, Go programs are more likely to be "lazy"--that is, they only run the things they need in the main() part of the program whereas Python packages are much more likely to do file or network I/O to initialize clients that may or may not be used by the program.
The way I'm using lambda, I compile the lambda build image beforehand which contains the python packages already installed, and the only "time" restraint is that of the lambda spinning up itself.
If you ran e.g. "pip install -r requirements.txt" inside the lambda, then yes it would take time to install the packages.
Meanwhile in Go, dependencies are baked into the executable so there is no resolving of dependencies, and the analog to “module level code” (i.e., package init() functions) are discouraged and thus much less common and where they occur they don’t do as much work compared to the average Python package.
- Chris, Serverless@AWS
Edit: Bizarre. Seems like Go on lambda does actually have slower cold start than JS or Python. I wonder if its just that the binary is likely larger than the equivalent JS source code? https://levelup.gitconnected.com/aws-lambda-cold-start-langu...
I hadn't expected it either, but it loads node faster. Perhaps via some VM trick?
A more realistic benchmark would be parsing a 1kb protobuf blob and printing some random key from it.
(this would require importing a non-stdlib parser)
Without knowing how it's implemented, my guess is that they're conserving python/v8 processes, so that they're not cold-starting the interpreter on each lambda execution.
You can't [1] do the same thing for a Go binary, so they have to invoke a binary, which might involve running some scans against it first.
This leads to some pretty counterintuitive conclusions! If you want minimal latency (in Lambda!!), you really should be using JS/Python, I guess.
[1]: OK. Maybe you could. Go has a runtime after all, although it's compiled into the binary! I have never heard of anybody doing this, but I'd love to read something about it. :)
Dependencies for the dynamic languages matter A LOT! Take a look at what it'll cost you for requiring the AWS SDK in Node.js, for your cold starts https://theburningmonk.com/2019/03/just-how-expensive-is-the...
Personal benchmarks puts Rust as the most optimal language that I've tried to run on AWS Lambda so far.
Most of the time in Lambda is usually spent waiting for IO, which is slow in any language. If you’re using Lambda for heavy computation, that’s not a great choice.
On the other hand I heard legends about under 10ms Rust Lambdas.
I'm not questioning that 5 is a tenth of 50. I'm questioning the Rust speed :D