AWSが公開したJavaScriptランタイムLLRTを試してみる

# What's？

AWSからJavaScriptのランタイムである「LLRT」が発表されたので、軽く試してみました。

https://www.publickey1.jp/blog/24/awsjavascriptllrtlow_latency_runtimeaws_lambda.html

# LLRT（Low Latency Runtime）

LLRT（Low Latency Runtime）のGitHubリポジトリーはこちら。

https://github.com/awslabs/llrt

LLRTはサーバーレス向けに設計されたJavaScriptランタイムとされていて、AWS Lambda上の他のJavaScriptランタイムと比べて10倍以上の高速な起動と最大2倍のコスト削減を実現するとされています。

> 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

現時点でのバージョンは0.1.6-betaで、評価目的の実験用パッケージという位置づけです。

Rustで実装され、JavaScriptエンジンとしてはQuickJSを使用してメモリの効率化と高速な起動を実現しているとしています。

> It's built in Rust, utilizing QuickJS as JavaScript engine, ensuring efficient memory usage and swift startup.

https://bellard.org/quickjs/

現時点でAWS Lambdaで使用する場合は、カスタムランタイムを使うか（推奨）、Lambdaレイヤーを使用することになるようです。

[LLRT / Configure Lambda functions to use LLRT](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#configure-lambda-functions-to-use-llrt)

使用できるAPIについては、Node.jsの一部をサポートしています。

> LLRT only support a fraction of the Node.js APIs.

[LLRT / Compatibility matrix](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#compatibility-matrix)

Node.jsの代替となることは目指しておらず、今後もすべてのAPIがサポートされる感じではなさそうです。

一部のAWS SDK for JavaScript v3のモジュールは、LLRTに組み込まれているようです。

[LLRT / Using AWS SDK (v3) with LLRT](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#using-aws-sdk-v3-with-llrt)

TypeScriptを直接実行する機能は持っていません。

[LLRT / Running TypeScript with LLRT](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#running-typescript-with-llrt)

Node.jsやBun、Denoといった他のランタイムとの違いは、JITを組み込まずランタイムを小さくし、起動時間を削減していることにあるようです。

[LLRT / Rationale](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#rationale)

一方で、実行時間の長い汎用的なアプリケーションには向かず、その場合はNode.jsやBun、Denoといったランタイムを使うことになるのでしょう。

よってサーバーレスで使うことに目的を絞り込んだランタイムと言えるでしょう。

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

[LLRT / Limitations](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#limitations)

AWS Lambdaのエミュレーター用のコードもついているみたいです。

[LLRT / Running Lambda emulator](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#running-lambda-emulator)

このファイルをダウンロードして使うようです。

https://github.com/awslabs/llrt/blob/v0.1.6-beta/lambda-server.js

今回は、JavaScriptランタイムとして簡単に試してみたいと思います。

# 環境

今回の環境はこちらです。

```shell
$cat /etc/os-release
NAME="Amazon Linux"
VERSION="2023"
ID="amzn"
ID_LIKE="fedora"
VERSION_ID="2023"
PLATFORM_ID="platform:al2023"
PRETTY_NAME="Amazon Linux 2023"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2023"
HOME_URL="https://aws.amazon.com/linux/"
BUG_REPORT_URL="https://github.com/amazonlinux/amazon-linux-2023"
SUPPORT_END="2028-03-15"


$ uname -srvmpio
Linux 6.1.72-96.166.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jan 17 00:42:52 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```

Amazon Linux 2023を使います。

# LLRTをインストールする

まずはLLRTをインストールします。

GitHubのReleasesから取得します。

https://github.com/awslabs/llrt/releases

```shell
$ curl -LO https://github.com/awslabs/llrt/releases/download/v0.1.6-beta/llrt-linux-x64.zip
$ unzip llrt-linux-x64.zip
```

バージョン。

```shell
$ ./llrt --version
LLRT (linux x64) 0.1.6-beta
```

ヘルプ。

```shell
$ ./llrt --help
LLRT (linux x64) 0.1.6-beta


Usage:
  llrt <filename>
  llrt -v | --version
  llrt -h | --help
  llrt -e | --eval <source>
  llrt compile input.js [output.lrt]
  llrt test <test_args>

Options:
  -v, --version     Print version information
  -h, --help        Print this help message
  -e, --eval        Evaluate the provided source code
  compile           Compile JS to bytecode and compress it with zstd:
                      if [output.lrt] is omitted, <input>.lrt is used.
                      lrt file is expected to be executed by the llrt version
                      that created it
  test              Run tests with provided arguments:
                      <test_args> -d <directory> <test-filter>

```

# LLRTを動かしてみる

では、簡単なプログラムを書いてLLRTを動かしてみます。

とりあえず、与えられたファイルパスを読み込んでコンソールに出力するコードを作成。

```javascript:hello.cjs
import fs from "fs/promises";

async function main() {
          const filePath = process.argv[2];

          const contents = (await fs.readFile(filePath)).toString("utf8");

          console.log(`fileName = ${filePath}`);
          console.log();
          console.log(`contents:\n${contents}`);
};

main();
```

`fs/promises`はサポートされているようです。

[LLRT / Compatibility matrix](https://github.com/awslabs/llrt/tree/v0.1.6-beta?tab=readme-ov-file#compatibility-matrix)

このソースコード自身を表示してみます。

```shell
$ ./llrt hello.cjs hello.cjs
fileName = hello.cjs

contents:
import fs from "fs/promises";

async function main() {
          const filePath = process.argv[2];

          const contents = (await fs.readFile(filePath)).toString("utf8");

          console.log(`fileName = ${filePath}`);
          console.log();
          console.log(`contents:\n${contents}`);
};

main();

```

動きました！

# おわりに

リポジトリーを見ると、AWS LambdaやCDKの例があります。TypeScriptで書かれていますが。

https://github.com/awslabs/llrt/tree/v0.1.6-beta/example

実装されているNode.jsのAPIは、ここを見るのがよさそうです。



ちょっと興味深いので、今後どうなっていくか見ておきたいですね。