llrt Documentation

LLRT (Low Latency Runtime) is an experimental, lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless...

8,776 stars Rust Rust 1 file ยท ~13,320 tokens
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy llrt on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name llrt --restart always awslabs/llrt:latest

File: README.md

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?)

Configure Lambda functions to use LLRT

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.

Option 2: Use a layer

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

Option 3: Package LLRT in a container image

See our AWS SAM example or:

dockerfile
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" ]

Option 4: AWS SAM

The following example project sets up a lambda
instrumented with a layer containing the llrt runtime.

Option 5: AWS CDK

You can use cdk-lambda-llrt construct library to deploy LLRT Lambda functions with AWS CDK.

ts
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 browser platform and mark included @aws-sdk packages as external.

Testing & ensuring compatibility

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

  • Useful for validating specific modules and functions in isolation
  • Allow focused testing of individual components

End-to-End (E2E) Tests

  • Validate overall compatibility with AWS SDK and WinterTC compliance
  • Test the integration between all components
  • Confirm expected behavior from end-user perspective
  • For more information about the E2E Tests and how to run them, see here.

Web Platform Tests (WPT)

  • Useful for validating LLRTโ€™s behavior against standardized browser APIs and runtime expectations
  • Ensure compatibility with web standards and cross-runtime environments
  • Help verify alignment with WinterTC and broader JavaScript ecosystem
  • For setup instructions and how to run WPT in LLRT, see here.

Test runner

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.

Compatibility matrix

[!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.

Using node_modules (dependencies) with LLRT

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

shell
esbuild index.js --platform=browser --target=es2023 --format=esm --bundle --minify --external:@aws-sdk --external:@smithy

Rollup

javascript
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"],
};

Webpack

javascript
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,
        },
      }),
    ],
  },
};

Using AWS SDK (v3) with LLRT

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 โœ”๏ธŽ
@aws-sdk/client-firehose โœ”๏ธŽ
@aws-sdk/client-glue โœ”๏ธŽ
@aws-sdk/client-kinesis โœ”๏ธŽ
@aws-sdk/client-opensearch โœ”๏ธŽ
@aws-sdk/client-opensearchserverless โœ”๏ธŽ
Application integration no-sdk std-sdk full-sdk
@aws-sdk/client-eventbridge โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-scheduler โœ”๏ธŽ
@aws-sdk/client-sfn โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-sns โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-sqs โœ”๏ธŽ โœ”๏ธŽ
Business applications no-sdk std-sdk full-sdk
@aws-sdk/client-ses โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-sesv2 โœ”๏ธŽ
Compute services no-sdk std-sdk full-sdk
@aws-sdk/client-auto-scaling โœ”๏ธŽ
@aws-sdk/client-batch โœ”๏ธŽ
@aws-sdk/client-ec2 โœ”๏ธŽ
@aws-sdk/client-lambda โœ”๏ธŽ
Containers no-sdk std-sdk full-sdk
@aws-sdk/client-ecr โœ”๏ธŽ
@aws-sdk/client-ecs โœ”๏ธŽ
@aws-sdk/client-eks โœ”๏ธŽ
@aws-sdk/client-servicediscovery โœ”๏ธŽ
Databases no-sdk std-sdk full-sdk
@aws-sdk/client-dynamodb โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-dynamodb-streams โœ”๏ธŽ
@aws-sdk/client-elasticache โœ”๏ธŽ
@aws-sdk/client-rds โœ”๏ธŽ
@aws-sdk/client-rds-data โœ”๏ธŽ
Developer tools no-sdk std-sdk full-sdk
@aws-sdk/client-xray โœ”๏ธŽ โœ”๏ธŽ
Front-end web and mobile services no-sdk std-sdk full-sdk
@aws-sdk/client-amplify โœ”๏ธŽ
@aws-sdk/client-appsync โœ”๏ธŽ
@aws-sdk/client-location โœ”๏ธŽ
Machine Learning (ML) and Artificial Intelligence (AI) no-sdk std-sdk full-sdk
@aws-sdk/client-bedrock โœ”๏ธŽ
@aws-sdk/client-bedrock-runtime โœ”๏ธŽ
@aws-sdk/client-bedrock-agent โœ”๏ธŽ
@aws-sdk/client-bedrock-agent-runtime โœ”๏ธŽ
@aws-sdk/client-polly โœ”๏ธŽ
@aws-sdk/client-rekognition โœ”๏ธŽ
@aws-sdk/client-textract โœ”๏ธŽ
@aws-sdk/client-translate โœ”๏ธŽ
Management and governance no-sdk std-sdk full-sdk
@aws-sdk/client-appconfig โœ”๏ธŽ
@aws-sdk/client-appconfigdata โœ”๏ธŽ
@aws-sdk/client-cloudformation โœ”๏ธŽ
@aws-sdk/client-cloudwatch โœ”๏ธŽ
@aws-sdk/client-cloudwatch-events โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-cloudwatch-logs โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-service-catalog โœ”๏ธŽ
@aws-sdk/client-ssm โœ”๏ธŽ โœ”๏ธŽ
Media no-sdk std-sdk full-sdk
@aws-sdk/client-mediaconvert โœ”๏ธŽ
Networking and content delivery no-sdk std-sdk full-sdk
@aws-sdk/client-api-gateway โœ”๏ธŽ
@aws-sdk/client-apigatewayv2 โœ”๏ธŽ
@aws-sdk/client-elastic-load-balancing-v2 โœ”๏ธŽ
Security, identity, and compliance no-sdk std-sdk full-sdk
@aws-sdk/client-acm โœ”๏ธŽ
@aws-sdk/client-cognito-identity โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-cognito-identity-provider โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-iam โœ”๏ธŽ
@aws-sdk/client-kms โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-secrets-manager โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-sso โœ”๏ธŽ
@aws-sdk/client-sso-admin โœ”๏ธŽ
@aws-sdk/client-sso-oidc โœ”๏ธŽ
@aws-sdk/client-sts โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/client-verifiedpermissions โœ”๏ธŽ
Storage no-sdk std-sdk full-sdk
@aws-sdk/client-efs โœ”๏ธŽ
@aws-sdk/client-s3 โœ”๏ธŽ โœ”๏ธŽ
Other bundled packages no-sdk std-sdk full-sdk
@aws-crypto โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/credential-providers โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/lib-dynamodb โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/lib-storage โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/s3-presigned-post โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/s3-request-presigner โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/util-dynamodb โœ”๏ธŽ โœ”๏ธŽ
@aws-sdk/util-user-agent-browser โœ”๏ธŽ โœ”๏ธŽ
@smithy โœ”๏ธŽ โœ”๏ธŽ

[!TIP]
LLRT now supports streaming SDK responses (since version 0.9). You can consume response bodies as streams or use the convenience methods:

javascript
const response = await client.send(command);

// Option 1: Stream the response body
for await (const chunk of response.Body) {
  // process chunk
}

// Option 2: Collect as string or bytes
const str = await response.Body.transformToString();
// or
const bytes = await response.Body.transformToByteArray();

Running TypeScript with LLRT

Same principle as dependencies applies when using TypeScript. TypeScript must be bundled and transpiled into ES2023 JavaScript.

[!NOTE]
LLRT will not support running TypeScript without transpilation. This is by design for performance reasons. Transpiling requires CPU and memory that adds latency and cost during execution. This can be avoided if done ahead of time during deployment.

Rationale

What justifies the introduction of another JavaScript runtime in light of existing options such as Node.js, Bun & Deno?

Node.js, Bun, and Deno represent highly proficient JavaScript runtimes. However, they are designed with general-purpose applications in mind. These runtimes were not specifically tailored for the demands of a Serverless environment, characterized by short-lived runtime instances. They each depend on a (Just-In-Time compiler (JIT) for dynamic code compilation and optimization during execution. While JIT compilation offers substantial long-term performance advantages, it carries a computational and memory overhead.

In contrast, LLRT distinguishes itself by not incorporating a JIT compiler, a strategic decision that yields two significant advantages:

A) JIT compilation is a notably sophisticated technological component, introducing increased system complexity and contributing substantially to the runtime's overall size.

B) Without the JIT overhead, LLRT conserves both CPU and memory resources that can be more efficiently allocated to code execution tasks, thereby reducing application startup times.

Limitations

There are many cases where LLRT shows notable performance drawbacks compared with JIT-powered runtimes, such as large data processing, Monte Carlo simulations or performing tasks with hundreds of thousands or millions of iterations. LLRT is most effective when applied to smaller Serverless functions dedicated to tasks such as data transformation, real time processing, AWS service integrations, authorization, validation etc. It is designed to complement existing components rather than serve as a comprehensive replacement for everything. Notably, given its supported APIs are based on Node.js specification, transitioning back to alternative solutions requires minimal code adjustments.

Building from source

  1. Clone code and cd to directory
text
git clone [email protected]:awslabs/llrt.git
cd llrt
  1. Install git submodules
text
git submodule update --init --checkout
  1. Install rust
text
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y
source "$HOME/.cargo/env"
  1. Install dependencies
text
# MacOS
brew install zig make cmake zstd node corepack

# Ubuntu
sudo apt -y install make zstd
sudo snap install zig --classic --beta

# Windows WSL2 (requires systemd to be enabled*)
sudo apt -y install cmake g++ gcc make zip zstd
sudo snap install zig --classic --beta

# Windows WSL2 (If Node.js is not yet installed)
sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
nvm install --lts

* See Microsoft Devblogs

  1. Install Node.js packages
text
corepack enable
yarn
  1. Install generate libs and setup rust targets & toolchains
text
make stdlib && make libs

[!NOTE]
If these commands exit with an error that says can't cd to zstd/lib,
you've not cloned this repository recursively. Run git submodule update --init to download the submodules and run the commands above again.

  1. Build binaries for Lambda (Per bundle type and architecture desired)
text
# for arm64, use
make llrt-lambda-arm64.zip
make llrt-lambda-arm64-no-sdk.zip
make llrt-lambda-arm64-full-sdk.zip
# or for x86-64, use
make llrt-lambda-x64.zip
make llrt-lambda-x64-no-sdk.zip
make llrt-lambda-x64-full-sdk.zip
  1. Build binaries for Container (Per bundle type and architecture desired)
text
# for arm64, use
make llrt-container-arm64
make llrt-container-arm64-no-sdk
make llrt-container-arm64-full-sdk
# or for x86-64, use
make llrt-container-x64
make llrt-container-x64-no-sdk
make llrt-container-x64-full-sdk
  1. Optionally build for your local machine (Mac or Linux)
text
make release
make release-no-sdk
make release-full-sdk

You should now have a llrt-lambda-arm64*.zip or llrt-lambda-x64*.zip. You can manually upload this as a Lambda layer or use it via your Infrastructure-as-code pipeline

Crypto and TLS Backend Options

LLRT supports multiple cryptographic backends for both the crypto module and TLS connections. These can be configured via Cargo features.

Crypto Provider Features

Feature Description
crypto-rust (default) Pure Rust crypto using RustCrypto crates
crypto-ring Ring-only crypto (limited algorithm support)
crypto-ring-rust Ring for hashing/HMAC, RustCrypto for everything else
crypto-graviola Graviola-only crypto (limited algorithm support)
crypto-graviola-rust Graviola for hashing/HMAC/AES-GCM, RustCrypto for everything else
crypto-openssl OpenSSL-based crypto

TLS Backend Features

Feature Description
tls-ring (default) rustls with ring crypto
tls-aws-lc rustls with AWS-LC crypto (optimized for AWS)
tls-graviola rustls with graviola crypto
tls-openssl OpenSSL for TLS

Building with Different Backends

bash
# Default (crypto-rust + tls-ring)
cargo build --release

# Using AWS-LC for TLS
cargo build --release --no-default-features --features "macro,tls-aws-lc"

# Using OpenSSL for both crypto and TLS
cargo build --release --no-default-features --features "macro,crypto-openssl,tls-openssl"

# Using Graviola for both crypto and TLS
cargo build --release --no-default-features --features "macro,crypto-graviola-rust,tls-graviola"

Running Lambda emulator

Please note that in order to run the example you will need:

  • Valid AWS credentials via a ~/.aws/credentials or via environment variables.
bash
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=YYY
export AWS_REGION=us-east-1
  • A DynamoDB table (with id as the partition key) on us-east-1
  • The dynamodb:PutItem IAM permission on this table. You can use this policy (don't forget to modify ):
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "putItem",
      "Effect": "Allow",
      "Action": "dynamodb:PutItem",
      "Resource": "arn:aws:dynamodb:us-east-1:<YOUR_ACCOUNT_ID>:table/quickjs-table"
    }
  ]
}

Start the lambda-server.js in a separate terminal

text
node lambda-server.js

Then run llrt:

text
make run

Environment Variables

`LLRT_ASYNC_HOOKS=value`

When using asynchronous hooks, the hooking function inside QuickJS is activated. This is disabled by default as there is concern that it may have a significant impact on performance.

By setting this environment variable to 1, the asynchronous hook function can be enabled, allowing you to track asynchronous processing using the async_hooks module.

`LLRT_EXTRA_CA_CERTS=file`

Load extra certificate authorities from a PEM encoded file

`LLRT_GC_THRESHOLD_MB=value`

Set a memory threshold in MB for garbage collection. Default threshold is 20MB

`LLRT_HTTP_VERSION=value`

Extends the HTTP request version. By default, only HTTP/1.1 is enabled. Specifying '2' will enable HTTP/1.1 and HTTP/2.

`LLRT_LOG=[target][=][level][,...]`

Filter the log output by target module, level, or both (using =). Log levels are case-insensitive and will also enable any higher priority logs.

Log levels in descending priority order:

  • Error
  • Warn | Warning
  • Info
  • Debug
  • Trace

Example filters:

  • warn will enable all warning and error logs
  • llrt_core::vm=trace will enable all logs in the llrt_core::vm module
  • warn,llrt_core::vm=trace will enable all logs in the llrt_core::vm module and all warning and error logs in other modules

`LLRT_NET_ALLOW="host[ ...]"`

Space-delimited list of hosts or socket paths which should be allowed for network connections. Network connections will be denied for any host or socket path missing from this list. Set an empty list to deny all connections

`LLRT_NET_DENY="host[ ...]"`

Space-delimited list of hosts or socket paths which should be denied for network connections

`LLRT_NET_POOL_IDLE_TIMEOUT=value`

Set a timeout in seconds for idle sockets being kept-alive. Default timeout is 15 seconds

`LLRT_PLATFORM=value`

Used to explicitly specify a preferred platform for the Node.js package resolver. The default is browser. If node is specified, "node" takes precedence in the search path. If a value other than browser or node is specified, it will behave as if "browser" was specified.

`LLRT_REGISTER_HOOKS=file`

If you want to enable a hooking mechanism that is mostly compatible with Node.js's module.registerHooks(), specify the js file name in this environment variable.

We provide a concrete example in example/register-hooks.

[!NOTE]
This environment variable is only effective when running on AWS Lambda.
When using the LLRT CLI, hook files must be specified using the --import option instead of this environment variable.

`LLRT_SDK_CONNECTION_WARMUP=1`

Initializes TLS connections in parallel during function init which significantly reduces cold starts due. Enabled by default, can be disabled with value 0 or false

`LLRT_TLS_VERSION=value`

Set the TLS version to be used for network connections. By default only TLS 1.2 is enabled. TLS 1.3 can also be enabled by setting this variable to 1.3

Benchmark Methodology

Although Init Duration reported by Lambda is commonly used to understand cold start impact on overall request latency, this metric does not include the time needed to copy code into the Lambda sandbox.

The technical definition of Init Duration (source):

For the first request served, the amount of time it took the runtime to load the function and run code outside of the handler method.

Measuring round-trip request duration provides a more complete picture of user facing cold-start latency.

Lambda invocation results (ฮป-labeled row) report the sum total of Init Duration + Function Duration.

Security

See CONTRIBUTING for more information.

License

This library is licensed under the Apache-2.0 License. See the LICENSE file.


File: example/llrt-sam/README.md

llrt-sam

This is a sample SAM project with LLRT instrumentation on a lambda via a lambda layer

  • hello-world - Code for the application's Lambda function written in TypeScript.
  • template.yaml - A template that defines the application's AWS resources.

The application uses several AWS resources, including Lambda functions and an AWS Lambda Layer. These resources are defined in the template.yaml file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code.

If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit.
The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started.

Deploy the sample application

The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API.

To use the SAM CLI, you need the following tools.

To build and deploy your application for the first time, run the following in your shell:

bash
sam build
sam deploy --guided

The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts:

  • Stack Name: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name.
  • AWS Region: The AWS region you want to deploy your app to.
  • Confirm changes before deploy: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes.
  • Allow SAM CLI IAM role creation: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the CAPABILITY_IAM value for capabilities must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass --capabilities CAPABILITY_IAM to the sam deploy command.
  • Save arguments to samconfig.toml: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run sam deploy without parameters to deploy changes to your application.

You can find your API Gateway Endpoint URL in the output values displayed after deployment.

Use the SAM CLI to build and test locally

Build your application with the sam build command.

bash
llrt-sam$ sam build

The SAM CLI installs dependencies defined in hello-world/package.json, compiles TypeScript with esbuild, creates a deployment package, and saves it in the .aws-sam/build folder.

Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the events folder in this project.

Run functions locally and invoke them with the sam local invoke command.

bash
llrt-sam$ sam local invoke HelloWorldFunction

Add a resource to your application

The application template uses AWS Serverless Application Model (AWS SAM) to define application resources. AWS SAM is an extension of AWS CloudFormation with a simpler syntax for configuring common serverless application resources such as functions, triggers, and APIs. For resources not included in the SAM specification, you can use standard AWS CloudFormation resource types.

Fetch, tail, and filter Lambda function logs

To simplify troubleshooting, SAM CLI has a command called sam logs. sam logs lets you fetch logs generated by your deployed Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug.

NOTE: This command works for all AWS Lambda functions; not just the ones you deploy using SAM.

bash
llrt-sam$ sam logs -n HelloWorldFunction --stack-name llrt-sam --tail

You can find more information and examples about filtering Lambda function logs in the SAM CLI Documentation.

Cleanup

To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following:

bash
sam delete --stack-name llrt-sam

Resources

See the AWS SAM developer guide for an introduction to SAM specification, the SAM CLI, and serverless application concepts.

Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: AWS Serverless Application Repository main page


File: example/llrt-sam-container-image/README.md

llrt-sam-oci

This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders.

  • hello-world - Code for the application's Lambda function and Project Dockerfile.
  • events - Invocation events that you can use to invoke the function.
  • hello-world/tests - Unit tests for the application code.
  • template.yaml - A template that defines the application's AWS resources.

The application uses several AWS resources, including Lambda functions and an API Gateway API. These resources are defined in the template.yaml file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code.

Deploy the sample application

The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API.

To use the SAM CLI, you need the following tools.

To build and deploy your application for the first time, run the following in your shell:

bash
sam build
sam deploy --guided

The first command will build a docker image from a Dockerfile and then the source of your application inside the Docker image. The second command will package and deploy your application to AWS, with a series of prompts:

  • Stack Name: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name.
  • AWS Region: The AWS region you want to deploy your app to.
  • Confirm changes before deploy: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes.
  • Allow SAM CLI IAM role creation: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the CAPABILITY_IAM value for capabilities must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass --capabilities CAPABILITY_IAM to the sam deploy command.
  • Save arguments to samconfig.toml: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run sam deploy without parameters to deploy changes to your application.

You can find your API Gateway Endpoint URL in the output values displayed after deployment.

Use the SAM CLI to build and test locally

Build your application with the sam build command.

bash
llrt-sam-oci$ sam build

The SAM CLI builds a docker image from a Dockerfile and then installs dependencies defined in hello-world/package.json inside the docker image. The processed template file is saved in the .aws-sam/build folder.

  • Note: The Dockerfile included in this sample application uses npm install by default. If you are building your code for production, you can modify it to use npm ci instead.

Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the events folder in this project.

Run functions locally and invoke them with the sam local invoke command.

bash
llrt-sam-oci$ sam local invoke HelloWorldFunction --event events/event.json

The SAM CLI can also emulate your application's API. Use the sam local start-api to run the API locally on port 3000.

bash
llrt-sam-oci$ sam local start-api
llrt-sam-oci$ curl http://localhost:3000/

The SAM CLI reads the application template to determine the API's routes and the functions that they invoke. The Events property on each function's definition includes the route and method for each path.

yaml
Events:
  HelloWorld:
    Type: Api
    Properties:
      Path: /hello
      Method: get

Add a resource to your application

The application template uses AWS Serverless Application Model (AWS SAM) to define application resources. AWS SAM is an extension of AWS CloudFormation with a simpler syntax for configuring common serverless application resources such as functions, triggers, and APIs. For resources not included in the SAM specification, you can use standard AWS CloudFormation resource types.

Fetch, tail, and filter Lambda function logs

To simplify troubleshooting, SAM CLI has a command called sam logs. sam logs lets you fetch logs generated by your deployed Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug.

NOTE: This command works for all AWS Lambda functions; not just the ones you deploy using SAM.

bash
llrt-sam-oci$ sam logs -n HelloWorldFunction --stack-name llrt-sam-oci --tail

You can find more information and examples about filtering Lambda function logs in the SAM CLI Documentation.

Unit tests

Tests are defined in the hello-world/tests folder in this project. Use NPM to install the Mocha test framework and run unit tests from your local machine.

bash
llrt-sam-oci$ cd hello-world
hello-world$ npm install
hello-world$ npm run test

Cleanup

To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following:

bash
sam delete --stack-name llrt-sam-oci

Resources

See the AWS SAM developer guide for an introduction to SAM specification, the SAM CLI, and serverless application concepts.

Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: AWS Serverless Application Repository main page


File: llrt_modules/README.md

LLRT Modules

LLRT Modules is a meta-module of rquickjs modules that can be used independantly of LLRT (Low Latency Runtime). They aim to bring to quickjs APIs from Node.js and WinterTC. You can use this meta-module, but each module is also a unique crate.

LLRT (Low Latency Runtime) is a lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless applications.

Usage

The package is not available in the crate registry yet, but you can clone the repo and import it as a local path.

Use this script to set everything up:

bash
cd your_project_dir
git clone https://github.com/awslabs/llrt.git

cd llrt
npm i
make js

Each module has a feature flag, they are all enabled by default but if you prefer to can decide which one you need.
Check the Compability matrix for the full list.

toml
[dependencies]
llrt_modules = { path = "llrt/llrt_modules", default-features = true } # load from local path
rquickjs = { version = "0.11", features = ["full-async"] }
tokio = { version = "1", features = ["full"] }

Once you have enable a module, you can import it in your runtime.

[!NOTE]
Some modules currently require that you call an init function before they evaluated.

rust
use llrt_modules::buffer;
use rquickjs::{async_with, context::EvalOptions, AsyncContext, AsyncRuntime, Error, Module};


#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Error> {
    let runtime = AsyncRuntime::new()?;
    let context = AsyncContext::full(&runtime).await?;

    async_with!(context => |ctx| {
        buffer::init(&ctx)?;
        let (_module, module_eval) = Module::evaluate_def::(ctx.clone(), "buffer")?;
        module_eval.into_future::<()>().await?;

        let mut options = EvalOptions::default();
        options.global = false;
        if let Err(Error::Exception) = ctx.eval_with_options::<(), _>(
            r#"
            import { Buffer } from "node:buffer";
            Buffer.alloc(10);
            "#,
            options
        ){
            println!("{:#?}", ctx.catch());
        };

        Ok::<_, Error>(())
    })
    .await?;

    Ok(())
}

Using ModuleBuilder makes it even simpler.

rust
use llrt_modules::module_builder::ModuleBuilder;
use rquickjs::{async_with, context::EvalOptions, AsyncContext, AsyncRuntime, Error, Module};


#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Error> {
    let runtime = AsyncRuntime::new()?;

    let module_builder = ModuleBuilder::default();
    let (module_resolver, module_loader, global_attachment) = module_builder.build();
    runtime.set_loader((module_resolver,), (module_loader,)).await;

    let context = AsyncContext::full(&runtime).await?;

    async_with!(context => |ctx| {
        global_attachment.attach(&ctx)?;

        let mut options = EvalOptions::default();
        options.global = false;
        if let Err(Error::Exception) = ctx.eval_with_options::<(), _>(
            r#"
            import { Buffer } from "node:buffer";
            Buffer.alloc(10);
            "#,
            options
        ){
            println!("{:#?}", ctx.catch());
        };

        Ok::<_, Error>(())
    })
    .await?;

    Ok(())
}

Compatibility matrix

[!NOTE]
Only a fraction of the Node.js APIs are supported. Below is a high level overview of partially supported APIs and modules.

Node.js LLRT Modules Feature Crate
abort โœ”๏ธŽ โœ”๏ธŽ๏ธ abort llrt_abort
assert โœ”๏ธŽ โš ๏ธ assert llrt_assert
async_hooks โœ”๏ธŽ โš ๏ธ async-hooks llrt_async_hooks
buffer โœ”๏ธŽ โš ๏ธ buffer llrt_buffer
child process โœ”๏ธŽ โš ๏ธ child-process llrt_child_process
console โœ”๏ธŽ โš ๏ธ console llrt_console
crypto โœ”๏ธŽ โš ๏ธ crypto llrt_crypto
dgram โœ”๏ธŽ โš ๏ธ dgram llrt_dgram
dns โœ”๏ธŽ โš ๏ธ dns llrt_dns
events โœ”๏ธŽ โš ๏ธ events llrt_events
exceptions โœ”๏ธŽ โš ๏ธ exceptions llrt_exceptions
fetch โœ”๏ธŽ โš ๏ธ fetch llrt_fetch
fs/promises โœ”๏ธŽ โš ๏ธ fs llrt_fs
fs โœ”๏ธŽ โš ๏ธ fs llrt_fs
intl โœ”๏ธŽ โš ๏ธ N/A llrt_intl
navigator โœ”๏ธŽ โš ๏ธ navigator llrt_navigator
net โœ”๏ธŽ โš ๏ธ net llrt_net
os โœ”๏ธŽ โš ๏ธ os llrt_os
path โœ”๏ธŽ โš ๏ธ path llrt_path
perf hooks โœ”๏ธŽ โš ๏ธ perf-hooks llrt_perf_hooks
stream (lib) N/A โœ”๏ธŽ N/A llrt_stream
string_decoder โœ”๏ธŽ โœ”๏ธŽ string_decoder llrt_string_decoder
timers โœ”๏ธŽ โš ๏ธ timers llrt_timers
process โœ”๏ธŽ โš ๏ธ process llrt_process
temporal โœ”๏ธŽ โš ๏ธ N/A llrt_temporal
tty โœ”๏ธŽ โš ๏ธ tty llrt_tty
url โœ”๏ธŽ โš ๏ธ url llrt_url
util โœ”๏ธŽ โš ๏ธ util llrt_util
zlib โœ”๏ธŽ โš ๏ธ zlib llrt_zlib
Other modules โœ”๏ธŽ โœ˜ N/A N/A

โš ๏ธ = partially supported

License

This module is licensed under the Apache-2.0 License.