<p>Every so often you build a feature and realize it was already there — latent in the architecture, just waiting for someone to expose it. Grove 0.7 is one of those. It adds a live timeline of every HTTP request your sites handle, and it needed almost no new plumbing to do it. Here's why, and how.</p><h2>Why: Grove is already standing in the doorway</h2><p>When you open <code>https://myapp.test</code>, the request doesn't go straight to your app. It goes to Grove first. Grove is the reverse proxy — it terminates TLS, matches the host to a site, and hands the request off to PHP-FPM, or a static file, or an upstream Vite/Docker process.</p><p>Which means Grove sees everything. Every method, every path, every status code, every millisecond — for every site, in every framework, whether it's Laravel, WordPress, a Node app behind a proxy, or a plain folder of HTML.</p><p>Tools like Laravel Telescope are wonderful, but they live inside one framework. You install a package, run a migration, and it watches that one app. Grove sits one layer lower, at the doorway all traffic passes through. So it can offer the same "what just happened?" answer for anything — with zero packages, zero migrations, and zero per-app setup.</p><p>That's the pitch: a zero-config request inspector for any local site.</p><h2>How: a ring buffer and one line in the proxy</h2><p>The whole feature is delightfully small. In the proxy handler — the function that already routes every request — Grove now notes four things when a request finishes: the method and path, the status it returned, and how long it took. That gets pushed into a bounded ring buffer that keeps the last 500 requests in memory.</p><p>Bounded and in-memory matters: it costs nothing at rest, never grows without limit, and nothing touches the disk. When you restart the daemon, the log starts fresh. It's a scratchpad, not a database.</p><p>Because the buffer is shared between the proxy and the daemon, both the CLI and the desktop app can read it live.</p><h3>On the command line</h3><pre><code class="language-text">$ grove requests
12:04:31.512  200  GET      8ms  blog     /
12:04:31.601  200  GET      3ms  blog     /build/assets/app.css
12:04:33.020  404  GET      1ms  blog     /favicon.ico
12:04:35.418  302  POST    24ms  blog     /login
12:04:35.482  200  GET     11ms  blog     /dashboard
</code></pre><p>Filter to one site, or widen the window:</p><pre><code class="language-text">$ grove requests blog --limit 100
</code></pre><p>And <code>--json</code> for scripting or piping into your own tools:</p><pre><code class="language-text">$ grove requests --json | jq '.data.requests[] | select(.status &gt;= 500)'
</code></pre><p>There's a quiet detail worth noticing: that 404 <code>/favicon.ico</code> and any 502s show up too. Grove records the responses it generates — a missing host, a stopped Docker container, a FastCGI hiccup — not just what your app returns. So when something breaks before it ever reaches your code, the timeline still tells you.</p><h3>In the desktop app</h3><p>The new Requests panel makes it live. It refreshes every second and reads like a heartbeat monitor for your local dev:</p><ul><li><p><strong>Status colours</strong> — 2xx green, 3xx blue, 4xx amber, 5xx (and hard errors) red. You spot a wall of red instantly.</p></li><li><p><strong>Slow requests highlighted</strong> — anything at or above 500ms is called out, so an N+1 or a sleepy endpoint jumps off the screen.</p></li><li><p><strong>A per-site filter</strong> — narrow to the app you're working on.</p></li><li><p><strong>A little stat line</strong> — how many requests are shown, the average latency, and the current error rate.</p></li></ul><p>Click <strong>Pause</strong> when you want to study a moment without it scrolling away; <strong>Live</strong> to resume.</p><p>It's the thing you reach for when you reload a page and something's off — a redirect loop, an asset 404ing, a call that's mysteriously slow — and you want to see it happen in real time without opening dev tools, tailing a log, or installing anything.</p><h2>The pattern behind it</h2><p>Grove 0.7 didn't add a subsystem. It surfaced one. The request timeline is a handful of lines in a place requests already flowed through, plus a small panel to make it visible. That's the whole shape of the thing.</p><p>It's also a preview of where Grove is heading: because it's the proxy and it owns your services, it's uniquely placed to answer questions no single-tool CLI can — and to do it for every site at once, for free.</p><pre><code class="language-text">$ grove requests
</code></pre><p>Grove auto-updates — after it relaunches, hit <strong>Tools → Restart daemon</strong>, open a site, reload, and watch the requests roll in. 🌱🌳</p><p>Next on the workbench: <code>grove.toml</code> + <code>grove up</code> — commit your project's PHP/Node/service requirements, and let a teammate go from <code>git clone</code> to a running, identical environment in one command.</p>