How Python 3.15's built-in profiler reveals the hidden hotspots in a web app
Simon Willison used Python 3.15's new sampling profiler and GPT-6 to map exactly where his web-edit app spends its CPU time.

A new profiler lands in Python 3.15
Python 3.15 ships with a built-in sampling profiler in the profiling.sampling module, removing the need for third-party tools just to see where a program is spending its time. Simon Willison put it to work on web-edit, his open-source Python web editing application, and the results painted a surprising picture of the app's CPU habits.
Flame graphs and heatmaps made easy
To create the actual visualisations, Willison handed the task to GPT-6 running inside the Codex coding assistant. The request was straightforward: generate a flame graph and a source-level heatmap for the web-edit app under a realistic editing workload. The resulting diagrams show thick bands of CPU activity concentrated in a single function, and a colour overlay on the source code pinpointing exactly which lines are the hottest.
Mixed line endings are the biggest drag
The profiler recorded 15,296 CPU stacks during a busy editing session. By far the dominant hotspot was preserve_endings, a routine responsible for keeping the original line-ending style (Unix LF, Windows CRLF, or older Mac CR) intact when files are saved 1. That function alone appeared in 64.8 percent of all sampled stacks. Inside it, the heavy lifting was done by SequenceMatcher.find_longest_match, which chewed up 38.3 percent of the leaf samples — the final functions on each call path .
Sampling every thread matters
One of the most important practical lessons from the exercise is that sampling across all threads is essential. A staggering 95.1 percent of the recorded stacks came from a background worker thread managed by AnyIO, a concurrency library. A profile limited to the main thread would have almost entirely missed the app's real CPU cost 1. Willison's demo shows both approaches side by side, making the difference impossible to ignore.
Why this matters for Python developers
The Python 3.15 profiler is now part of the standard library, which means anyone running a recent Python version can get flame graphs and source heatmaps without installing extra packages. Combined with AI coding assistants like Codex, the barrier to creating professional-quality performance visualisations has dropped dramatically — a developer can describe the goal in plain language and get production-ready diagrams back. For anyone maintaining a Python web app, the takeaway is simple: check your line-ending preservation code first, and make sure your profiler is looking at every thread.
Key facts
- Python 3.15 includes a built-in sampling profiler in the profiling.sampling module
- The preserve_endings function accounted for 64.8% of 15,296 recorded CPU stacks
- 95.1% of profiles came from an AnyIO worker thread, not the main thread
- GPT-6 in Codex was used to generate the flame graph and heatmap visualisations
- SequenceMatcher.find_longest_match contributed 38.3% of leaf CPU samples
Sources
- Research: Profiling web-edit with Python 3.15: flame graphs and source heatmaps — simonwillison.net


