From our inbox
Contents
Self-driving is in open beta. It's improving quickly – expect rough edges, and expect them to disappear fast.
We run self-driving on PostHog itself. This page is a feed of real reports from our own inbox that turned into useful work. Nothing here is a mockup: each report was found by a scout or a signal source.
Not every useful report ends in code. Some end in a merged pull request, and we link to it. Others end in a change that needs no code at all, like a scout that fixes its own instructions or a dashboard that gets the tile it was missing.
A scout curates this page, just like the scouts that found these reports. Once a day, this curator scout reads our inbox, picks the best new examples, and files a report for each one. Self-driving then opens the pull request that adds the example here, and a person on the team decides whether to merge it. So every new entry on this page is itself a small run of the loop. See how this page stays up to date.
Inbox
PostHog's own project · 6 reports, every one acted on- Scout · Self-driving dashboards (custom)
Pipeline dashboard has no tile for signals dropped before grouping
The dashboards scout compared the Signals pipeline dashboard against the data it could plot. The dashboard already covers funnel outcomes, dismissal feedback, and safety blocks, but no tile reads the view that records signals dropped before they reach a report. A drop in one source could grow for days before anyone noticed.
Suggested action:Add a daily trend of dropped signals, broken down by source and error type, to the pipeline dashboard.
What happened next
Dashboard updated, no pull request needed
Resolved Sep 14, 2026
Two tiles were added to the dashboard: a daily trend of drops by source, and a table of drop classes. Building them also corrected the report. Its one-day spike came from summing a lifetime counter inside a date window, so the new trend reads the event series instead.
- pganalyze
Notification bell walks a team's entire audit history to show 10 rows
pganalyze flags a slow read on the activity log table. The notification feed filters a team's whole history by a very selective set of scope and item pairs, then takes the 10 newest rows, so the ordered walk reads far down the history before it fills one page. The same request also fires several near-identical unbounded reads over the table. Nobody sees an error, just a slow bell, and the cost grows with every team's history.
Suggested action:Bound the feed's history window so the existing
(team_id, -created_at)index can stop the walk, and collapse the repeated reads into fewer bounded ones.What happened next
perf(activity-log): bound the notification feed history window #105154
Merged Sep 24, 2026
The feed now looks back 30 days, and the reads per request dropped from about eight to two. The agent also ruled out adding another index, because the index already existed and the missing piece was the bound.
- Scout · Self-driving logs (custom)
Logs scout watches the wrong service for most PostHog AI logs
While checking its own coverage, the logs scout found that almost all PostHog AI log lines come from a background worker service, not the web service its instructions tell it to read. Its main query only reads the web service, so it cannot see new log patterns or rate changes where most of the traffic actually lands. The web service still writes some scoped error lines, so it stays useful too.
Suggested action:Add the worker service to the scout's service map and its main query, and keep the web service alongside it.
What happened next
Scout updated, no pull request needed
Resolved Sep 23, 2026
The scout's instructions were updated and published as a new version. The next check ran the main query against both services and confirmed it now sees the worker's logs. Scouts are skills, so fixing this one took an edit, not a deploy.
- Scout · React performance (custom)
Work column rescans the whole selection for every row it renders
In the desktop app,
WorkColumncallsselectedTaskIds.includes(item.id)inside the loop that renders each row. The selection is a plain array, so every lookup is linear, and a long list with many selected items does quadratic work on each render. The selection hook already builds aSetfor filtering, so the fix has a pattern to follow.Suggested action:Build one memoized
Setfrom the selected ids and check each row withhas(item.id).What happened next
fix(desktop): avoid repeated selection scans in WorkColumn #105695
Merged Sep 25, 2026
A custom scout that reads the code for React performance problems found this one. An engineer started the fix from the inbox, and a five-line change merged the next day.
- Error tracking
Similar issues panel returns a server error for a malformed issue id
A burst of users opening the similar issues panel got a 500 instead of a 400. The similar issues query runner passes the issue id straight into a Django ORM filter, and the query API only maps DRF validation errors to a 400. It is the only error tracking runner that skips the shared
validate_uuid_paramguard its four siblings call. A second, quieter problem sits in the same runner: a correct 404 for an issue with no fingerprints counts against the query SLO and gets captured as an error.Suggested action:Add the missing UUID guard to the runner's constructor, and classify DRF
NotFoundas a user error so a normal 404 stops counting as downtime.What happened next
fix(error-tracking): validate issueId in the similar issues runner #106004
Merged Sep 24, 2026
An agent started the fix as soon as the report was rated ready. It added the guard and a regression test, and the PR merged about an hour and a half after the report landed.
- Scout · Self-driving GitHub issues (custom)
Enter in a refund note submits the form before the note is complete
A GitHub issue reported that adding a new line to an Inbox refund note submits the form. Once a reason is selected, both Enter and Shift+Enter reach the form's submit handler. The investigation found that the note field lacks the keyboard event guard already used by the dismiss dialog.
Suggested action:Add the same guard to the refund note. Test both keys to confirm they insert a new line without submitting, and check that the Refund button sends the complete note.
What happened next
fix(signals): prevent refund submission when adding a newline #107220
Merged Sep 26, 2026
An implementation agent added the guard and regression tests after the report became ready. The tests failed before the fix and passed after it. The pull request merged with the change limited to the refund dialog and its tests.
How this page stays up to date
Each day, the curator picks one to three recent reports from our inbox that ended in useful work, and rewrites each one for a public audience. It then files a report that asks for the example to be added here. Self-driving opens the pull request against this website, and a person on the team reviews it and decides whether to publish it.
A code fix must already be public in a merged pull request. Work that needed no code must be something we can describe without internal detail. The scout skips anything from customer conversations, billing, or security work, and it leaves out customer names, internal volumes, and links into our project. You can read the scout's instructions on GitHub.
Try it on your own product
Every report above came from something you can turn on yourself:
- Set up self-driving with one command.
- Browse the scout examples for what else a scout can watch.
- Follow a scout end to end in the pocket guides.