L lerd lerd-env/lerd v1.36.0…v1.37.0 ↗
ENGINEERING DIGEST · 2026-10-01 → 2026-10-19

v1.37.0

One request, followed all the way through

A request lerd serves while debug capture is on now carries one id from nginx to PHP to the browser, so it opens on a timeline of everything it ran, its page reports its own errors back, and an assistant reads it over MCP led by what went wrong. The site header learned fetch, pull, push and branch switching, with the installs and migrations a move needs offered and the database snapshotted first. Services sleep when nothing uses them, secrets can come from a manager without touching .env, and the dashboard dropped from over a gigabyte to under 100 MB on a busy machine.

183
commits
79
merged PRs
842
files
+41,762
insertions
−9,658
deletions
4
contributors
web UI 26% tests 22% cli 11% tui 10% docs 10% rest 21%
01

Request

FEATUI

Every captured event already wore a request id, but nothing outside PHP knew it. Now PHP answers with an X-Lerd-Rid header, nginx writes it into its access log and the page carries it, so a recent request opens on a timeline of everything it ran, laid out on the time nginx measured. #2150 #2161

ONE ID, FOUR PLACESwhile debug capture is on
nginx
access log
response time, FPM wait
──►
PHP
X-Lerd-Rid
queries, views, jobs, logs
──►
browser
page script
errors, console, fetches
──►
assistant
request tool
issues first
The strip above the timeline sums up what the request cost: response time, peak memory, the split between app and database, and how long it queued for a free FPM worker.
FEAT

Browser logs #2123 #2139

lerd browser-logs on injects a small script that reports uncaught errors, unhandled rejections, console messages and failed fetches, each tied to the request that served the page. Store presets add a frontend library's own events.

FEAT

A request tool that says what went wrong #2169

Over MCP an assistant lists recent requests and reads one, and its lenses action leads with N+1 and slow queries, then exceptions, error logs, failed HTTP calls, jobs and browser errors, each counted once.

FEATUI

Copy for agent #2170

The inspect dialog, a failing doctor check and an App logs entry copy a short prompt naming the MCP call that reads the full data, rather than a dump that goes stale or gets cut.

FEAT

The slowest request stays openable #2172 #2230

The slowest routes list spans seven days, but a bar could only open its request while its events were still in the buffer. The events of each route's slowest request are now kept aside, survive a restart and are let go once it stops being the slowest. A bar with nothing kept says why, and offers to turn capture on when it is off.

02

Git

FEATUI

Fetch, Pull and Push sit beside the worktree tabs whenever a branch tracks an upstream, a branch with none gets a Publish button, and the main checkout gets a branch switcher. Pull is fast-forward only and push is never forced. Switching or pulling first shows what the move brings in, and offers what it needs. #2177 #2180 #2182

A BRANCH SWITCHthe same review for a pull
1
Diff the two trees

The commits and files coming in, and any uncommitted file the move would overwrite, which holds it back.

2
Snapshot the database

Saved as branch-<name> for the branch being left, so a failed migration is one click from undone and coming back offers that copy. #2220

3
Run what the move needs

composer install, the project's JS install and the framework's migrate command, each ticked when the incoming changes call for it, with a warning when the target drops migrations.

03

Sleep

FEAT

Idle-suspend could already put a site's workers to sleep. With lerd idle services on it does the same for databases, caches and mail catchers once every site and worktree using them has gone quiet. #2008

A REQUEST TO A SLEEPING SITEheld, never redirected
request
waking vhost
held open
──►
services
start in parallel
every one the site uses
──►
app
real response
streamed back
A browser, an API client or a webhook never sees a waking page. Console commands, MCP calls and the databases tab wake what they need, and a pinned service stays up.
FEAT

Secrets from an env_provider, kept in tmpfs #2069

A project whose secrets live in a manager declares a command in .lerd.yaml, such as infisical export --format=dotenv. lerd runs it behind the host command consent gate and keeps the output in a 0600 file under $XDG_RUNTIME_DIR that PHP loads for web requests, workers and the CLI, so the values never touch .env or container storage. The docs carry commands for Infisical, Doppler, 1Password, Bitwarden, sops, Vault and AWS.

04

Lighter

REF

lerd-ui held the Debug window's events in memory, and every open tab streamed the whole buffer in and grouped it in the browser. The buffer is a SQLite file now, and each lens reads one page from it, grouped, searched and flagged in SQL. #2188

On a machine with a few busy sitesbeforeafter
lerd-ui memoryover 1 GBunder 100 MB
opening the Debug window, per tabover 20 MBunder 1 MB
times each page was mounted21
REF

A soft memory limit #2188

lerd-ui, the watcher, the tray and the MCP server aim at 64 MB unless GOMEMLIMIT says otherwise, so one large response no longer keeps a process several times its size for minutes.

FEAT

A buffer size you pick #2150

dumps.buffer holds between 3,000 and 20,000 events, 5,000 by default, and a running dashboard resizes in place.

REF

One daemon-reload, not one per worker #2167

Sleeping, waking, pausing and unlinking a site write every unit first and reload once.

05

Terminal

FEAT

The TUI is rebuilt around one sidebar and one main area, drawn in the terminal's own palette, and ctrl+p reaches every page, site, worktree, service, action and setting, matching words in any order. Destructive actions stay in the CLI. #2040

FEAT

DNS built into lerd #2146

lerd-dns was a dnsmasq container on Linux and a Homebrew dnsmasq on macOS. lerd dns-serve answers the TLD now, which drops the only image lerd built itself. An upgrade swaps it in with no sudo prompt.

FEATUI

Your editor #2122

Pick VS Code, Cursor, Zed, PhpStorm and others, installed ones first, or a custom command. One not on the PATH opens through its URL scheme, so a JetBrains IDE from Toolbox works.

FEAT

front_controller: true #2134

For apps that route their own .php URLs, like GLPI 11. Every .php request goes through index.php, and it travels in a committed .lerd.yaml.

FEATUI

Update all services #2202

Outdated services lead the grid with the version they move to, and one button updates each in turn, reporting every result.

FEAT

Server variables from the store #2194

nginx.fastcgi_params adds fastcgi_param lines to a site's PHP location, after the ones lerd sets, with {{root}} and {{public}}.

FEAT

Moving from MAMP #2159

A guide next to the Herd and Laragon ones, covering databases and what happens to .htaccess now that nginx serves the site.

06

Fixes

FIX

The fixed list covers bugs that shipped in 1.36.0 or earlier. Regressions introduced and fixed inside this cycle never reached anyone, so they are left out. Several of them passed silently: tests green, a status that read fine, a check that said unknown.

FIX

Pest's Chromium rejected lerd's certificates #2223

Chromium reads its own NSS store, so on a secured site with Vite running no script loaded, while text-only assertions and assertNoJavaScriptErrors stayed green.

FIX

The node audit on bun, pnpm and yarn #2221

The doctor always ran npm audit, which needs a package-lock.json. Each project is audited by its own package manager now.

FIX

A FrankenPHP site answered 502 #2191 #2111

Starting a worker re-rendered its vhost from the PHP-FPM template, and lerd start did not bring it back after a reinstall.

FIX

lerd's MySQL under a host AppArmor profile #2120

On Ubuntu or Debian with mysql-server installed, its profile attached to the mysqld in lerd's container too, which then could not read its config.

FIX

lerd rebuild took a custom container down #2195

It removed the running image before building the new one, while reporting success.

FIX

A worktree reinstalled every minute #2178

On npm 6 or Yarn 1 the marker the staleness check trusts is never written, so the watcher ran a clean install on every pass.