Skip to content

Commit e8bbc97

Browse files
authored
Merge pull request #593 from Nicell/lute
Add Lute runtime
2 parents 235a367 + af633f1 commit e8bbc97

35 files changed

Lines changed: 432 additions & 2 deletions

frameworks/lute/Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
ARG LUTE_VERSION=1.0.1-nightly.20260421
2+
3+
FROM buildpack-deps:curl AS bin
4+
5+
RUN apt-get update && apt-get install -y --no-install-recommends unzip \
6+
&& rm -rf /var/lib/apt/lists/*
7+
8+
ARG LUTE_VERSION
9+
ARG TARGETARCH
10+
11+
RUN ARCH=$(echo "${TARGETARCH:-amd64}" | sed -e 's/arm64/aarch64/' -e 's/amd64/x86_64/') \
12+
&& curl -fsSL "https://github.com/luau-lang/lute/releases/download/v${LUTE_VERSION}/lute-linux-${ARCH}.zip" --output lute.zip \
13+
&& unzip lute.zip \
14+
&& chmod +x lute
15+
16+
FROM debian:stable-slim
17+
18+
RUN apt-get update \
19+
&& apt-get install -y --no-install-recommends ca-certificates libssl3 \
20+
&& rm -rf /var/lib/apt/lists/*
21+
22+
COPY --from=bin /lute /usr/local/bin/lute
23+
24+
WORKDIR /usr/src/app
25+
26+
COPY server.luau serve.luau ./
27+
28+
ENV LUTE_UNBUFFERED=1
29+
30+
EXPOSE 8080 8081
31+
32+
ENTRYPOINT ["lute", "server.luau"]

frameworks/lute/meta.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"display_name": "lute",
3+
"language": "Luau",
4+
"type": "production",
5+
"engine": "lute",
6+
"description": "Lute standalone Luau runtime",
7+
"repo": "https://github.com/luau-lang/lute",
8+
"enabled": true,
9+
"tests": [
10+
"baseline",
11+
"pipelined",
12+
"limited-conn",
13+
"json",
14+
"json-tls",
15+
"upload",
16+
"echo-ws"
17+
],
18+
"maintainers": ["nicell"]
19+
}

frameworks/lute/serve.luau

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
local server = require("@lute/net/server")
2+
local fs = require("@std/fs")
3+
local json = require("@std/json")
4+
5+
local TEXT_HEADERS = { ["Content-Type"] = "text/plain" }
6+
local JSON_HEADERS = { ["Content-Type"] = "application/json" }
7+
local NOT_FOUND = { status = 404, body = "", headers = TEXT_HEADERS }
8+
local UPGRADE_FAILED = { status = 400, body = "Upgrade failed", headers = TEXT_HEADERS }
9+
local PIPELINE_OK = { body = "ok", headers = TEXT_HEADERS }
10+
11+
local dataset: any = nil
12+
local datasetLen = 0
13+
14+
local function buildJson(count: number, m: number): string
15+
local items = table.create(count)
16+
for i = 1, count do
17+
local src = dataset[i]
18+
items[i] = {
19+
id = src.id,
20+
name = src.name,
21+
category = src.category,
22+
price = src.price,
23+
quantity = src.quantity,
24+
active = src.active,
25+
tags = src.tags,
26+
rating = src.rating,
27+
total = src.price * src.quantity * m,
28+
}
29+
end
30+
return json.serialize({ count = count, items = items })
31+
end
32+
33+
local function handle(req, srv)
34+
local path = req.path
35+
local method = req.method
36+
37+
if path == "/ws" then
38+
if srv:upgrade(req) then
39+
return
40+
end
41+
return UPGRADE_FAILED
42+
end
43+
44+
if path == "/baseline11" then
45+
local a = tonumber(req.query.a) or 0
46+
local b = tonumber(req.query.b) or 0
47+
if method == "POST" then
48+
local c = tonumber(req.body) or 0
49+
return { body = tostring(a + b + c), headers = TEXT_HEADERS }
50+
end
51+
return { body = tostring(a + b), headers = TEXT_HEADERS }
52+
end
53+
54+
if path == "/pipeline" then
55+
return PIPELINE_OK
56+
end
57+
58+
if path == "/upload" and method == "POST" then
59+
return { body = tostring(#req.body), headers = TEXT_HEADERS }
60+
end
61+
62+
if string.sub(path, 1, 6) == "/json/" then
63+
local count = tonumber(string.sub(path, 7))
64+
if count and count >= 0 and count <= datasetLen then
65+
local m = tonumber(req.query.m) or 1
66+
return { body = buildJson(count, m), headers = JSON_HEADERS }
67+
end
68+
return NOT_FOUND
69+
end
70+
71+
return NOT_FOUND
72+
end
73+
74+
local wsHandlers = {
75+
message = function(ws, message)
76+
ws:send(message)
77+
end,
78+
}
79+
80+
return {
81+
serve = function()
82+
dataset = json.deserialize(fs.readFileToString("/data/dataset.json")) :: any
83+
datasetLen = #dataset
84+
85+
server.serve({
86+
hostname = "0.0.0.0",
87+
port = 8080,
88+
reuseport = true,
89+
handler = handle,
90+
websocket = wsHandlers,
91+
})
92+
93+
if fs.exists("/certs/server.crt") and fs.exists("/certs/server.key") then
94+
server.serve({
95+
hostname = "0.0.0.0",
96+
port = 8081,
97+
reuseport = true,
98+
tls = {
99+
certfilename = "/certs/server.crt",
100+
keyfilename = "/certs/server.key",
101+
},
102+
handler = handle,
103+
websocket = wsHandlers,
104+
})
105+
end
106+
end,
107+
}

frameworks/lute/server.luau

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
local vm = require("@lute/vm")
2+
local task = require("@std/task")
3+
local system = require("@std/system")
4+
5+
local threadCount = system.threadCount()
6+
7+
for _ = 1, threadCount do
8+
task.spawn(vm.create("./serve").serve)
9+
end
10+
11+
print(`Application started ({threadCount} server threads).`)

site/data/baseline-4096.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,26 @@
568568
"status_4xx": 0,
569569
"status_5xx": 0
570570
},
571+
{
572+
"framework": "lute",
573+
"language": "Luau",
574+
"rps": 2565216,
575+
"avg_latency": "1.60ms",
576+
"p99_latency": "3.27ms",
577+
"cpu": "5711.6%",
578+
"memory": "132MiB",
579+
"connections": 4096,
580+
"threads": 64,
581+
"duration": "5s",
582+
"pipeline": 1,
583+
"bandwidth": "293.48MB/s",
584+
"input_bw": "198.16MB/s",
585+
"reconnects": 0,
586+
"status_2xx": 12826081,
587+
"status_3xx": 0,
588+
"status_4xx": 0,
589+
"status_5xx": 0
590+
},
571591
{
572592
"framework": "mark",
573593
"language": "PHP",

site/data/baseline-512.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,26 @@
568568
"status_4xx": 0,
569569
"status_5xx": 0
570570
},
571+
{
572+
"framework": "lute",
573+
"language": "Luau",
574+
"rps": 2539880,
575+
"avg_latency": "201us",
576+
"p99_latency": "532us",
577+
"cpu": "5953.6%",
578+
"memory": "101MiB",
579+
"connections": 512,
580+
"threads": 64,
581+
"duration": "5s",
582+
"pipeline": 1,
583+
"bandwidth": "290.66MB/s",
584+
"input_bw": "196.20MB/s",
585+
"reconnects": 0,
586+
"status_2xx": 12699400,
587+
"status_3xx": 0,
588+
"status_4xx": 0,
589+
"status_5xx": 0
590+
},
571591
{
572592
"framework": "mark",
573593
"language": "PHP",

site/data/current.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"date": "2026-04-22",
2+
"date": "2026-04-23",
33
"cpu": "AMD Ryzen Threadripper PRO 3995WX 64-Cores",
44
"cores": "64",
55
"threads": "128",
@@ -10,7 +10,7 @@
1010
"docker": "29.3.0",
1111
"docker_runtime": "runc",
1212
"governor": "performance",
13-
"commit": "89a6d12a",
13+
"commit": "a69ab556",
1414
"tcp": {
1515
"lo_mtu": "1500",
1616
"congestion": "cubic",

site/data/echo-ws-16384.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,25 @@
176176
"status_4xx": 0,
177177
"status_5xx": 0
178178
},
179+
{
180+
"framework": "lute",
181+
"language": "Luau",
182+
"rps": 2650618,
183+
"avg_latency": "6.13ms",
184+
"p99_latency": "8.70ms",
185+
"cpu": "5590.9%",
186+
"memory": "388MiB",
187+
"connections": 16384,
188+
"threads": 64,
189+
"duration": "5s",
190+
"pipeline": 1,
191+
"bandwidth": "18.26MB/s",
192+
"reconnects": 0,
193+
"status_2xx": 13253092,
194+
"status_3xx": 0,
195+
"status_4xx": 0,
196+
"status_5xx": 0
197+
},
179198
{
180199
"framework": "node-websocket",
181200
"language": "JS",

site/data/echo-ws-4096.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,25 @@
176176
"status_4xx": 0,
177177
"status_5xx": 0
178178
},
179+
{
180+
"framework": "lute",
181+
"language": "Luau",
182+
"rps": 2999367,
183+
"avg_latency": "1.36ms",
184+
"p99_latency": "2.23ms",
185+
"cpu": "5859.7%",
186+
"memory": "169MiB",
187+
"connections": 4096,
188+
"threads": 64,
189+
"duration": "5s",
190+
"pipeline": 1,
191+
"bandwidth": "20.02MB/s",
192+
"reconnects": 0,
193+
"status_2xx": 14996838,
194+
"status_3xx": 0,
195+
"status_4xx": 0,
196+
"status_5xx": 0
197+
},
179198
{
180199
"framework": "node-websocket",
181200
"language": "JS",

site/data/echo-ws-512.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,25 @@
176176
"status_4xx": 0,
177177
"status_5xx": 0
178178
},
179+
{
180+
"framework": "lute",
181+
"language": "Luau",
182+
"rps": 3108882,
183+
"avg_latency": "164us",
184+
"p99_latency": "325us",
185+
"cpu": "5824.0%",
186+
"memory": "97MiB",
187+
"connections": 512,
188+
"threads": 64,
189+
"duration": "5s",
190+
"pipeline": 1,
191+
"bandwidth": "20.75MB/s",
192+
"reconnects": 0,
193+
"status_2xx": 15544413,
194+
"status_3xx": 0,
195+
"status_4xx": 0,
196+
"status_5xx": 0
197+
},
179198
{
180199
"framework": "node-websocket",
181200
"language": "JS",

0 commit comments

Comments
 (0)