diff --git a/.github/benchmark/benchmark.jmx b/.github/benchmark/benchmark.jmx
new file mode 100644
index 0000000000..97aecff820
--- /dev/null
+++ b/.github/benchmark/benchmark.jmx
@@ -0,0 +1,327 @@
+
+
+
+
+
+ Parametrized LDAP benchmark. Admin bind is cached once per thread (Once Only Controller, labelled ADMIN_CONNECT, excluded from metrics). Data ops (ADD/SEARCH/COMPARE/MODIFY/DELETE/READD) reuse the cached admin connection. Entries use mail as the naming/searchable attribute (equality-indexed by default on BOTH OpenDJ and OpenLDAP); only mail + objectClass (both indexed on both servers) are stored, keeping the write cost symmetric. Every created value is unique: ADD uses a per-iteration counter, READD uses a UUID. The measured user authentication is a single bind/unbind (test=sbind, own connection) after MODIFY has set the userPassword.
+ false
+ true
+ false
+
+
+
+
+
+
+
+ continue
+
+ false
+ -1
+
+ ${__P(threads,200)}
+ ${__P(rampup,0)}
+ true
+ ${__P(duration,300)}
+
+
+
+
+
+ 1
+
+ 1
+ iter
+
+ true
+ false
+
+
+
+
+
+
+
+ ${__P(host,localhost)}
+ ${__P(port,1389)}
+ ou=People,${__P(basedn,dc=example\,dc=com)}
+ 2
+
+
+
+ false
+ false
+ 60000
+ false
+ false
+ ${__P(adminbinddn,cn=Directory Manager)}
+ ${__P(adminbindpw,password)}
+
+
+
+
+ bind
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+ false
+ false
+
+ false
+ false
+
+
+
+
+
+
+ add
+ mail=u_${__threadNum}_${iter}@test.com
+
+
+
+ mail
+ u_${__threadNum}_${iter}@test.com
+ =
+
+
+ objectClass
+ top
+ =
+
+
+ objectClass
+ locality
+ =
+
+
+ objectClass
+ extensibleObject
+ =
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 0
+ 0
+ mail:dn:objectClass
+ false
+ false
+
+ false
+ false
+
+
+
+
+
+
+ search
+
+ (mail=u_${__threadNum}_${iter}@test.com)
+
+
+
+
+
+
+
+
+ 2
+
+
+
+ false
+ false
+
+ false
+ false
+
+
+ mail=u_${__threadNum}_${iter}@test.com
+ mail=u_${__threadNum}_${iter}@test.com
+
+
+ compare
+
+
+
+
+
+
+
+
+ 2
+
+
+
+ false
+ false
+
+ false
+ false
+
+
+
+
+
+
+ modify
+ mail=u_${__threadNum}_${iter}@test.com
+
+
+
+ description
+ mod_${__threadNum}_${iter}
+ replace
+ =
+
+
+ userPassword
+ ${__P(benchpw,benchPass1)}
+ replace
+ =
+
+
+
+
+
+
+
+
+ ${__P(host,localhost)}
+ ${__P(port,1389)}
+ ou=People,${__P(basedn,dc=example\,dc=com)}
+ 2
+
+
+
+ false
+ false
+ 60000
+ false
+ false
+ mail=u_${__threadNum}_${iter}@test.com,ou=People,${__P(basedn,dc=example\,dc=com)}
+ ${__P(benchpw,benchPass1)}
+
+
+
+
+ sbind
+
+
+
+
+
+
+
+
+ 2
+
+
+
+ false
+ false
+
+ false
+ false
+
+
+
+
+
+
+ delete
+ mail=u_${__threadNum}_${iter}@test.com
+
+
+
+
+
+
+
+
+ 2
+
+
+
+ false
+ false
+
+ false
+ false
+
+
+
+
+
+
+ add
+ mail=u_${__UUID}@test.com
+
+
+
+ mail
+ u_${__UUID}@test.com
+ =
+
+
+ objectClass
+ top
+ =
+
+
+ objectClass
+ locality
+ =
+
+
+ objectClass
+ extensibleObject
+ =
+
+
+
+
+
+
+
+
+
diff --git a/.github/benchmark/people.ldif b/.github/benchmark/people.ldif
new file mode 100644
index 0000000000..d6a350093e
--- /dev/null
+++ b/.github/benchmark/people.ldif
@@ -0,0 +1,17 @@
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions copyright [year] [name of copyright owner]".
+#
+# Copyright 2026 3A Systems, LLC.
+dn: ou=People,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: People
diff --git a/.github/benchmark/summary.sh b/.github/benchmark/summary.sh
new file mode 100644
index 0000000000..b2b59f95b7
--- /dev/null
+++ b/.github/benchmark/summary.sh
@@ -0,0 +1,129 @@
+#!/usr/bin/env bash
+# The contents of this file are subject to the terms of the Common Development and
+# Distribution License (the License). You may not use this file except in compliance with the
+# License.
+#
+# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+# specific language governing permission and limitations under the License.
+#
+# When distributing Covered Software, include this CDDL Header Notice in each file and include
+# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+# Header, with the fields enclosed by brackets [] replaced by your own identifying
+# information: "Portions copyright [year] [name of copyright owner]".
+#
+# Copyright 2026 3A Systems, LLC.
+#
+# Render an LDAP benchmark comparison report (versions + per-operation table + QuickChart charts)
+# for two servers A and B to stdout โ intended to be appended to $GITHUB_STEP_SUMMARY. The report
+# is generic: server names, versions and images are all parameters, and benchmark-specific notes
+# are NOT included here (append them separately, e.g. `cat notes.md >> $GITHUB_STEP_SUMMARY`).
+#
+# Usage:
+# summary.sh \
+#
+#
+# The admin connection bind is labelled ADMIN_CONNECT in the plan and is intentionally
+# skipped here, so it never pollutes the per-operation comparison.
+set -euo pipefail
+
+A_NAME="${1:?server A name required}"
+A_JSON="${2:?server A statistics.json required}"
+A_VER="${3:-unknown}"
+A_IMG="${4:-}"
+B_NAME="${5:?server B name required}"
+B_JSON="${6:?server B statistics.json required}"
+B_VER="${7:-unknown}"
+B_IMG="${8:-}"
+
+A_COLOR="#4e79a7" # blue = server A
+B_COLOR="#f28e2b" # orange = server B
+
+# Operations to compare, in workflow order. ADMIN_CONNECT and Total are excluded.
+OPS=("ADD" "SEARCH" "COMPARE" "MODIFY" "BIND" "DELETE" "READD")
+
+# m