LLRT (Low Latency Runtime) is a lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless applications. LLRT offers up to over 10x faster startup and up to 2x overall lower cost compared to other JavaScript runtimes running on AWS Lambda
It's built in Rust, utilizing QuickJS as JavaScript engine, ensuring efficient memory usage and swift startup.
[!WARNING] LLRT is an experimental package. It is subject to change and intended only for evaluation purposes.
LLRT - DynamoDB Put, ARM, 128MB:

Node.js 20 - DynamoDB Put, ARM, 128MB:

HTTP benchmarks measured in round trip time for a cold start (why?)
Download the last LLRT release from https://github.com/awslabs/llrt/releases
Choose Custom Runtime on Amazon Linux 2023 and package the LLRT bootstrap binary together with your JS code.
Choose Custom Runtime on Amazon Linux 2023, upload llrt-lambda-arm64.zip or llrt-lambda-x64.zip as a layer and add to your function
See our AWS SAM example or:
FROM --platform=arm64 busybox
WORKDIR /var/task/
COPY app.mjs ./
ADD https://github.com/awslabs/llrt/releases/latest/download/llrt-container-arm64 /usr/bin/llrt
RUN chmod +x /usr/bin/llrt
ENV LAMBDA_HANDLER "app.handler"
CMD [ "llrt" ]
The following example project sets up a lambda instrumented with a layer containing the llrt runtime.
You can use cdk-lambda-llrt construct library to deploy LLRT Lambda functions with AWS CDK.
import { LlrtFunction } from "cdk-lambda-llrt";
const handler = new LlrtFunction(this, "Handler", {
entry: "lambda/index.ts",
});
See Construct Hub and its examples for more details.
That's it 🎉
[!IMPORTANT] Even though LLRT supports ES2023 it's NOT a drop in replacement for Node.js. Consult Compatibility matrix and API for more details. All dependencies should be bundled for a
browserplatform and mark included@aws-sdkpackages as external.
The best way to ensure your code is compatible with LLRT is to write tests and execute them using the built-in test runner. The test runner currently supports Jest/Chai assertions. There are three main types of tests you can create:
Unit Tests
End-to-End (E2E) Tests
Web Platform Tests (WPT)
Test runner uses a lightweight Jest-like API and supports Jest/Chai assertions. For examples on how to implement tests for LLRT see the /tests folder of this repository.
To run tests, execute the llrt test command. LLRT scans the current directory and sub-directories for files that ends with *.test.js or *.test.mjs. You can also provide a specific test directory to scan by using the llrt test -d <directory> option.
The test runner also has support for filters. Using filters is as simple as adding additional command line arguments, i.e: llrt test crypto will only run tests that match the filename containing crypto.
[!NOTE] LLRT only support a fraction of the Node.js APIs. It is NOT a drop in replacement for Node.js, nor will it ever be. Below is a high level overview of partially supported APIs and modules. For more details consult the API documentation
| Node.js API | Node.js | LLRT |
|---|---|---|
| node:assert | ✔︎ | ✔︎️⚠️ |
| node:async_hooks | ✔︎ | ✔︎️⚠️ |
| node:buffer | ✔︎ | ✔︎️⚠️ |
| node:child_process | ✔︎ | ✔︎⚠️ |
| node:cluster | ✔︎ | ✘ |
| node:console | ✔︎ | ✔︎⚠️ |
| node:crypto | ✔︎ | ✔︎⚠️ |
| node:dgram | ✔︎ | ✘ |
| node:diagnostics_channel | ✔︎ | ✘ |
| node:dns | ✔︎ | ✔︎⚠️ |
| node:events | ✔︎ | ✔︎⚠️ |
| node:fs | ✔︎ | ✔︎⚠️ |
| node:fs/promises | ✔︎ | ✔︎⚠️ |
| node:http | ✔︎ | ✘⏱ |
| node:http2 | ✔︎ | ✘ |
| node:https | ✔︎ | ✘⏱ |
| node:inspector | ✔︎ | ✘ |
| node:inspector/promises | ✔︎ | ✘ |
| node:module | ✔︎ | ✔︎⚠️ |
| node:net | ✔︎ | ✔︎⚠️ |
| node:os | ✔︎ | ✔︎⚠️ |
| node:path | ✔︎ | ✔︎⚠️ |
| node:perf_hooks | ✔︎ | ✔︎⚠️ |
| node:process | ✔︎ | ✔︎⚠️ |
| node:querystring | ✔︎ | ✘ |
| node:readline | ✔︎ | ✘ |
| node:readline/promises | ✔︎ | ✘ |
| node:repl | ✔︎ | ✘ |
| node:sqlite | ✔︎ | ✘ |
| node:stream | ✔︎ | ✔︎* |
| node:stream/promises | ✔︎ | ✔︎* |
| node:stream/web | ✔︎ | ✔︎⚠️ |
| node:string_decoder | ✔︎ | ✔︎ |
| node:test | ✔︎ | ✘ |
| node:timers | ✔︎ | ✔︎⚠️ |
| node:tls | ✔︎ | ✘⏱ |
| node:tty | ✔︎ | ✔︎⚠️ |
| node:url | ✔︎ | ✔︎⚠️ |
| node:util | ✔︎ | ✔︎⚠️ |
| node:v8 | ✔︎ | ✘** |
| node:vm | ✔︎ | ✘ |
| node:wasi | ✔︎ | ✘ |
| node:worker_threads | ✔︎ | ✘ |
| node:zlib | ✔︎ | ✔︎⚠️ |
| LLRT API | Node.js | LLRT |
|---|---|---|
| llrt:codec | ✘ | ✔︎ |
| llrt:qjs | ✘ | ✔︎ |
| llrt:util | ✘ | ✔︎ |
| llrt:xml | ✘ | ✔︎ |
| Web Platform API | LLRT |
|---|---|
| COMPRESSION | ✘⏱ |
| CONSOLE | ✔︎⚠️ |
| DOM | ✔︎⚠️ |
| ECMASCRIPT | ✔︎⚠️ |
| ENCODING | ✔︎⚠️ |
| FETCH | ✔︎⚠️ |
| FILEAPI | ✔︎⚠️ |
| HR-TIME | ✔︎ |
| HTML | ✔︎⚠️ |
| STREAMS | ✔︎⚠️ |
| URL | ✔︎ |
| URLPATTERN | ✘⏱ |
| WASM-JS-API-2 | ✘ |
| WASM-WEB-API-2 | ✘ |
| WEBCRYPTO | ✔︎⚠️ |
| WEBIDL | ✔︎⚠️ |
| XHR | ✔︎⚠️ |
| Other features | LLRT |
|---|---|
| async/await | ✔︎ |
| esm | ✔︎ |
| cjs | ✔︎ |
| Intl | ✔︎⚠️ |
| Temporal | ✔︎⚠️ |
⚠️ = partially supported in LLRT
⏱ = planned partial support
* = Not native
** = The module.registerHooks() API allows you to emulate some functionality. See also example/register-hooks.
Since LLRT is meant for performance critical application it's not recommended to deploy node_modules without bundling, minification and tree-shaking.
LLRT can work with any bundler of your choice. Below are some configurations for popular bundlers:
[!WARNING] LLRT implements native modules that are largely compatible with the following external packages. By implementing the following conversions in the bundler's alias function, your application may be faster, but we recommend that you test thoroughly as they are not fully compatible.
| Node.js | LLRT |
|---|---|
| fast-xml-parser | llrt:xml |
esbuild index.js --platform=browser --target=es2023 --format=esm --bundle --minify --external:@aws-sdk --external:@smithy
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import terser from "@rollup/plugin-terser";
export default {
input: "index.js",
output: {
file: "dist/bundle.js",
format: "esm",
sourcemap: true,
target: "es2023",
},
plugins: [resolve(), commonjs(), terser()],
external: ["@aws-sdk", "@smithy"],
};
import TerserPlugin from "terser-webpack-plugin";
import nodeExternals from "webpack-node-externals";
export default {
entry: "./index.js",
output: {
path: "dist",
filename: "bundle.js",
libraryTarget: "module",
},
target: "web",
mode: "production",
resolve: {
extensions: [".js"],
},
externals: [nodeExternals(), "@aws-sdk", "@smithy"],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: 2023,
},
}),
],
},
};
LLRT includes many AWS SDK clients and utils as part of the runtime, built into the executable. These SDK Clients have been specifically fine-tuned to offer best performance while not compromising on compatibility. LLRT replaces some JavaScript dependencies used by the AWS SDK by native ones such as Hash calculations and XML parsing. V3 SDK packages not included in the list below have to be bundled with your source code. For an example on how to use a non-included SDK, see this example build script (buildExternalSdkFunction)
LLRT supports the following three bundles by default. Bundle types and suffixes are as follows.
| Bundle Type | Suffix | Purpose of Use |
|---|---|---|
| no-sdk | *-no-sdk | Suitable for workloads that do not use @aws-sdk. |
| std-sdk | (none) | Suitable for workloads that utilize the major @aws-sdk. |
| full-sdk | *-full-sdk | Suitable for workloads that utilize any @aws-sdk. |
The relationship between the supported packages for each bundle type is as follows.
| Analytics | no-sdk | std-sdk | full-sdk |
|---|---|---|---|
| @aws-sdk/client-athena |