Back to blog
2026-07-08 Thijs Creemers

Release: v1.0.1-alpha-39

This is primarily a performance release. Every hot-path change was benchmarked with criterium before it landed. It also adds a way to refresh a project’s framework-owned AGENTS.md after an upgrade, and fixes a handful of latent correctness bugs.

Changed: performance, tier 1 — compiled validators and protocol logging

  • Malli validators compiled once. m/validate / m/explain with a raw schema re-parse the schema and rebuild the predicate on every call — measured 8.6–9.9× overhead. All 121 static-schema call sites across 43 files (login, per-request handlers, per-WebSocket-message :pre checks) now use m/validator / m/explainer defs compiled at namespace load. boundary.core.validation memoizes compilation for schema-as-argument callers, and the scaffolder emits compiled validators in generated modules.

  • Reflective logging removed. boundary-platform’s reflective `(.info logger …) interop — fired on enter and leave of every request — is replaced with ILogger protocol calls, measured ~90× per call. warn-on-reflection is now enabled in those namespaces.

Changed: performance, tier 2 — single-pass conversion, caching, batching

  • boundary-platform: DB result keys are converted snake→kebab in the next.jdbc builder-fn (once per result set) instead of a second full per-row rebuild — ~1.7× on 100-row results.

  • boundary-admin: entity config and table metadata are cached in the long-lived SchemaRepository — previously every admin page issued 2×N information_schema queries.

  • boundary-platform: static-resource middleware no longer does a classloader lookup on every request; duplicate param parsing dropped in favour of reitit’s parameters-middleware.

  • boundary-i18n: resolve-markers uses a structural-sharing transform that returns original nodes when nothing changed — 82.4µs → 25.0µs (3.3×) on a 50-row table page.

  • boundary-audience / boundary-user: N+1 write patterns batched into chunked multi-row INSERTs and execute-batch! — a 50k-user audience drops from ~100k statements to ~102.

Changed: performance, tier 3 — CSRF fast paths, cached secrets, throttled heartbeat

  • boundary-platform: http-csrf-protection short-circuits before any binding/cookie work when CSRF is disabled (the default); correlation ids use ThreadLocalRandom instead of the contended shared SecureRandom; version headers are built once at wrap time.

  • boundary-user: the JWT signing secret is resolved from the environment once per process instead of a System/getenv call on every sign/verify.

  • boundary-jobs: the worker Redis heartbeat is throttled to :heartbeat-interval-ms (default 5000 ms) instead of a round-trip per loop iteration.

Added: boundary agents update

boundary agents update (and the generated bb agents:update task) refreshes the framework-owned sections of a project’s AGENTS.md after a Boundary upgrade. The marker-delimited blocks are re-rendered from the installed CLI’s template and spliced in place; everything outside the markers — team notes, custom sections — is left untouched. --check exits 1 when the file is stale, for CI.

Fixed

  • boundary-platform: PostgreSQL session settings (statement_timeout, TimeZone=UTC, ApplicationName) now reach every pooled connection via JDBC URL properties — the previous SET statements only affected the one connection that ran them, leaving the statement-timeout guard unset on the rest of the pool.

  • build: the uberjar silently omitted 13 libraries because build.clj hardcoded 9 source dirs; the list now derives from deps.edn :paths, so new libs are packaged automatically.

  • boundary-email / boundary-external: the Attachment schema used :bytes, which is not in Malli’s default registry — validation threw on every call (latent until validators were compiled at load). Fixed to bytes?.

  • boundary-user: find-active-users-by-role, find-users-created-since and find-users-by-email-domain ran unbounded ORDER BY … DESC with no LIMIT; all three now default to the platform’s max-pagination-limit (1000).

Version alignment

All libraries bumped to v1.0.1-alpha-39 to maintain lockstep versioning.

Upgrade

Re-run the installer to pick up the latest release:

curl -fsSL https://get.boundary-app.org | bash

No migration required. Backward compatible — the performance changes preserve existing signatures, return values and security semantics.