diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
new file mode 100644
index 0000000..557ffa6
--- /dev/null
+++ b/.github/workflows/benchmark.yml
@@ -0,0 +1,50 @@
+name: Simple benchmarking
+
+on:
+ workflow_dispatch:
+ workflow_call:
+
+jobs:
+ tests:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ max-parallel: 1
+ matrix:
+ luceeVersion: [ 5.4/snapshot/jar, 6.0/snapshot/jar, 6.1/snapshot/jar, 6.1.0/snapshot/jar, 6.2/snapshot/jar ]
+ javaVersion: [ 11, 21 ]
+ exclude:
+ - luceeVersion: 5.4/snapshot/jar
+ javaVersion: 21
+ - luceeVersion: 6.0/snapshot/jar
+ javaVersion: 21
+ env:
+ luceeVersionQuery: ${{ matrix.luceeVersion }}
+ compile: ${{ github.event.inputs.compile }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Set up JDK ${{matrix.javaVersion}}
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{matrix.javaVersion}}
+ distribution: "temurin"
+ - name: Cache Maven packages
+ if: always()
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2
+ key: maven-cache
+ - name: Cache Lucee files
+ uses: actions/cache@v4
+ if: always()
+ with:
+ path: /home/runner/work/_actions/lucee/script-runner/main/lucee-download-cache
+ key: lucee-downloads
+ - name: Run Microbenches
+ uses: lucee/script-runner@main
+ with:
+ webroot: ${{ github.workspace }}/custom/benchmark
+ execute: /index.cfm
+ luceeVersionQuery: ${{ matrix.luceeVersion }}
+
diff --git a/custom/benchmark/Application.cfc b/custom/benchmark/Application.cfc
new file mode 100644
index 0000000..b517aaa
--- /dev/null
+++ b/custom/benchmark/Application.cfc
@@ -0,0 +1,3 @@
+component {
+ this.name="bench-runner";
+}
\ No newline at end of file
diff --git a/custom/benchmark/index.cfm b/custom/benchmark/index.cfm
new file mode 100644
index 0000000..201ffcf
--- /dev/null
+++ b/custom/benchmark/index.cfm
@@ -0,0 +1,34 @@
+
+ runs = server.system.environment.BENCHMARK_CYCLES ?: 10000;
+ arr = [];
+ systemOutput("Running hello world [#runs#] times", true);
+ ArraySet( arr, 1, runs, 0 );
+ s = getTickCount();
+
+ ArrayEach( function( item ){
+ InternalRequest(
+ url: "/tests/hello-world.cfm"
+ );
+ }, true );
+
+ time = getTickCount()-s;
+
+ function _logger( string message="", boolean throw=false ){
+ systemOutput( arguments.message, true );
+ if ( !FileExists( server.system.environment.GITHUB_STEP_SUMMARY ) ){
+ fileWrite( server.system.environment.GITHUB_STEP_SUMMARY, "#### #server.lucee.version# ");
+ fileAppend( server.system.environment.GITHUB_STEP_SUMMARY, server.system.environment.toJson());
+ }
+
+ if ( arguments.throw ) {
+ fileAppend( server.system.environment.GITHUB_STEP_SUMMARY, "> [!WARNING]" & chr(10) );
+ fileAppend( server.system.environment.GITHUB_STEP_SUMMARY, "> #arguments.message##chr(10)#");
+ throw arguments.message;
+ } else {
+ fileAppend( server.system.environment.GITHUB_STEP_SUMMARY, " #arguments.message##chr(10)#");
+ }
+
+ }
+
+ _logger( "Running hello world [#runs#] times, took #numberFormat(time)# ms, or #numberFormat(runs/(time/1000))# per second" );
+
\ No newline at end of file
diff --git a/custom/benchmark/tests/Application.cfc b/custom/benchmark/tests/Application.cfc
new file mode 100644
index 0000000..d49a9f5
--- /dev/null
+++ b/custom/benchmark/tests/Application.cfc
@@ -0,0 +1,3 @@
+component {
+ this.name="bench";
+}
\ No newline at end of file
diff --git a/custom/benchmark/tests/hello-world.cfm b/custom/benchmark/tests/hello-world.cfm
new file mode 100644
index 0000000..d809c0f
--- /dev/null
+++ b/custom/benchmark/tests/hello-world.cfm
@@ -0,0 +1,3 @@
+
+
+Hello, World!
\ No newline at end of file