scalene
CLAUDE.md14k starsChanged 4 years agoApache-2.0View on GitHub
Scalene is a high-performance CPU, GPU, and memory profiler for Python with AI-powered optimization proposals. It runs significantly faster than other Python profilers while providing detailed performance information. See the paper docs/osdi23-berger.pdf for technical details on Scalene's design. Key features: - CPU, GPU (NVIDIA/Apple), and memory profiling - AI-powered optimization suggestions (OpenAI, Anthropic, Azure, Amazon Bedrock, Gemini, Ollama) - Web-based GUI and CLI interfaces - Jupyter notebook support via magic commands (%scrun, %%scalene) - Line-by-line profiling with low overhead -…
- Reads credentials
- Installs packages
We split this CLAUDE.md into the rules it gives an agent
26 rules. About 0 are common, 6 are distinctive, and 20 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
20
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 196
Always use abstract
dismodule categories: when possible: dis.hasjabs (absolute jump opcodes), dis.hasjrel (relative jump opcodes), … - Very specific: line 198
When checking jump direction (forward vs backward), use instr.argval (which dis resolves to an absolute offset) and compare against …
- Very specific: line 229
Use autocomplete="one-time-code" on password/API key inputs to prevent browsers from offering to save them:
- Distinctive: line 249
Use CSS classes to show/hide provider-specific fields:
- Very specific: line 264
Add class persistent to inputs that should be saved/restored from localStorage:
- Very specific: line 272
When standalone=False (default): Assets are referenced as local files (e.g., <script src="jquery-3.6.0.slim.min.js">)
- Very specific: line 273
When standalone=True: All assets are embedded inline (JS/CSS as text, images as base64)
- Distinctive: line 288
When importing submodules, be explicit:
- Very specific: line 307
test_nested_package_relative_import.py: - Import handling tests - Distinctive: line 334
When testing port availability, never use hardcoded ports - they may already be in use on CI runners:
- Very specific: line 358
Add default value in scalene_arguments.py:
- Very specific: line 364
Add argument in scalene_parseargs.py:
- Distinctive: line 392
Import the new module
- Very specific: line 393
Add case in sendPromptToService() switch statement
- Very specific: line 396
Add option to #service select dropdown
- Distinctive: line 397
Add provider section with API key input, model selector, etc.
- Very specific: line 398
Add CSS for .newprovider-fields visibility
- Very specific: line 401
Add provider to toggleServiceFields() function
- Distinctive: line 402
Add refresh handler if dynamic model fetching is supported
- Very specific: line 403
Update getDefaultProvider() if env var support is needed
- Very specific: line 406
Add mapping in envKeyMap for new fields
- Very specific: line 409
Add the field and its environment variable(s) to ENV_API_KEY_VARIABLES
- Very specific: line 410
Add the field to EnvApiKeys / envApiKeyFields in persistence.ts
- Very specific: line 501
After profiling completes, Scalene prints instructions for viewing the profile:
- Very specific: line 512
Create a scalene.yaml file with options:
- Very specific: line 525
Use scalene run --help-advanced to see all options including:
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Scalene Development Guide
Project Overview
Scalene is a high-performance CPU, GPU, and memory profiler for Python with AI-powered optimization proposals. It runs significantly faster than other Python profilers while providing detailed performance information. See the paper docs/osdi23-berger.pdf for technical details on Scalene's design.
Key features:
- CPU, GPU (NVIDIA/Apple), and memory profiling
- AI-powered optimization suggestions (OpenAI, Anthropic, Azure, Amazon Bedrock, Gemini, Ollama)
- Web-based GUI and CLI interfaces
- Jupyter notebook support via magic commands (
%scrun,%%scalene) - Line-by-line profiling with low overhead
- Separates Python time from native/C time
Platform support: Linux, macOS, WSL 2 (full support); Windows (partial support)
Build & Test Commands
# Install in development mode
pip install -e .
# Run all tests
python3 -m pytest tests/
# Run tests for a specific Python version
python3.X -m pytest tests/
# Run linters
mypy scalene
ruff check scalene
# Run a single test file
python3 -m pytest tests/test_coverup_83.py -vProject Structure
Core Profiler Components (scalene/)
scalene_profiler.py- Main profiler class (Scalene). Entry point for profiling. Uses signal-based sampling for CPU profiling. Coordinates all profiling subsystems.scalene_statistics.py-ScaleneStatisticsclass. Collects and aggregates profiling data. Key types:ProfilingSample,MemcpyProfilingSample. UsesRunningStatsfor statistical aggregation.scalene_output.py- Profile output formatting for CLI/HTMLscalene_json.py-ScaleneJSONclass for JSON output formatscalene_analysis.py- Profile analysis logic
Entry Points
__main__.py- Entry point forpython -m scaleneprofile.py- Entry point for--on/--offcontrol of background profiling
Configuration & Arguments
scalene_config.py- Version info (scalene_version,scalene_date) and constants:SCALENE_PORT = 11235- Default port for web UINEWLINE_TRIGGER_LENGTH- Must matchsrc/include/sampleheap.hpp
scalene_arguments.py-ScaleneArgumentsclass (extendsargparse.Namespace) with all profiler options and their defaults defined inScaleneArgumentsDictscalene_parseargs.py-ScaleneParseArgs.parse_args()builds the argument parser.RichArgParserprovides colored help output (uses Rich on Python < 3.14, native argparse colors on 3.14+)
Signal Handling
scalene_signals.py- Signal definitions for CPU samplingscalene_signal_manager.py- Manages signal handlersscalene_sigqueue.py- Signal queue managementscalene_client_timer.py- Timer for periodic profiling
GPU Support
scalene_nvidia_gpu.py- NVIDIA GPU profiling viapynvmlscalene_apple_gpu.py- Apple GPU profiling (Metal)scalene_accelerator.py- Generic accelerator interfacescalene_neuron.py- AWS Neuron support
Memory Profiling
scalene_memory_profiler.py- Memory profiling logicscalene_leak_analysis.py- Memory leak detection (experimental,--memory-leak-detector)scalene_mapfile.py-ScaleneMapFilefor memory-mapped communication with native extensionscalene_preload.py- Sets upLD_PRELOAD/DYLD_INSERT_LIBRARIESfor native memory tracking
Jupyter Integration
scalene_magics.py- Jupyter magic commands (%scrunfor line mode,%%scalenefor cell mode)scalene_jupyter.py- Jupyter notebook support utilities
Replacement Modules (replacement_*.py)
These modules monkey-patch standard library functions to capture profiling data during blocking operations:
replacement_fork.py- Tracksos.fork()replacement_exit.py- Trackssys.exit()replacement_lock.py,replacement_mp_lock.py,replacement_sem_lock.py- Lock acquisition timingreplacement_thread_join.py,replacement_pjoin.py- Thread/process join timingreplacement_signal_fns.py- Signal function replacementsreplacement_poll_selector.py- I/O polling timingreplacement_get_context.py- Multiprocessing context
Utilities
runningstats.py-RunningStatsclass for online statistical calculations (mean, variance)scalene_funcutils.py- Function utilitiesscalene_utility.py- General utilitiessparkline.py- Sparkline generation for memory visualizationsyntaxline.py- Syntax-highlighted source code linesadaptive.py- Adaptive sampling logictime_info.py- Time measurement utilitiessorted_reservoir.py- Reservoir sampling for bounded-size sample collection
GUI (scalene/scalene-gui/)
Web-based GUI built with TypeScript, bundled with esbuild.
Core Files:
index.html.template- Jinja2 template for main GUI page (rendered byscalene_utility.py)scalene-gui.ts- Main TypeScript entry point, UI event handlers, initializationscalene-gui-bundle.js- Bundled JavaScript output (generated, do not edit directly)
AI Provider Modules:
openai.ts- OpenAI API integration (sendPromptToOpenAI,fetchOpenAIModels)anthropic.ts- Anthropic Claude API integrationgemini.ts- Google Gemini API integration (sendPromptToGemini,fetchGeminiModels)optimizations.ts- Provider dispatch logic, prompt generationpersistence.ts- localStorage persistence with environment variable fallbacks
Support Files:
launchbrowser.py- Opens browser to GUI (default port 11235)find_browser.py- Cross-platform browser detection
Vendored Assets (for offline support):
jquery-3.6.0.slim.min.js- jQuery (vendored locally, not loaded from CDN)bootstrap.min.css- Bootstrap 5.1.3 CSSbootstrap.bundle.min.js- Bootstrap 5.1.3 JS with Popperprism.css- Syntax highlighting stylesfavicon.ico- Scalene faviconscalene-image.png- Scalene logo
These assets are copied, with the page, into a fresh private (0700) temp directory that launchbrowser.py serves and deletes on exit, enabling the GUI to work in air-gapped/offline environments. Never serve the shared system temp dir itself.
Building the GUI:
npm --prefix scalene/scalene-gui run buildThe build script in scalene/scalene-gui/package.json invokes esbuild
with --minify --sourcemap --target=es2020. The minified bundle is what
gets checked in (≈1.1 MB vs ≈2.5 MB unminified). A build:dev variant
(no minification) is available for debugging.
Native Extensions (src/)
C++ code for low-overhead memory allocation tracking:
Headers (src/include/):
sampleheap.hpp- Sampling heap allocator. Key constantNEWLINEmust match Python config.memcpysampler.hpp- Interceptsmemcpyto track copy volumepywhere.hpp- Tracks Python file/line info for allocationssamplefile.hpp- File-based communication with Pythonsampler.hpp,poissonsampler.hpp,thresholdsampler.hpp- Sampling strategiesscaleneheader.hpp- Common header definitions
Sources (src/source/):
libscalene.cpp- Main native library (loaded viaLD_PRELOAD)pywhere.cpp- Python location tracking implementationget_line_atomic.cpp- Atomic line number accesstraceconfig.cpp- Trace configuration
Vendor Libraries (vendor/)
Heap-Layers/- Memory allocator infrastructure (by Emery Berger)printf/- Async-signal-safe printf implementation
Key Patterns
Python Version Compatibility
The codebase supports Python 3.8-3.14. Version-specific code uses:
if sys.version_info >= (3, 14):
# Python 3.14+ specific code
else:
# Older Python versionsType Annotation Compatibility (Python 3.8/3.9):
- Do NOT use
X | Yunion syntax in runtime-evaluated annotations (PEP 604 requires Python 3.10+). UseOptional[X]orUnion[X, Y]fromtypinginstead. - Do NOT use
list[X],dict[K, V],tuple[X, ...]in runtime-evaluated annotations (PEP 585 lowercase generics require Python 3.9+). UseList,Dict,Tuplefromtypingfor 3.8 support. - Adding
from __future__ import annotationsmakes all annotations strings (not evaluated at runtime), which allows modern syntax on older Python. However, this can break code that inspects annotations at runtime (e.g., dataclasses, pydantic). - The safest approach for this codebase: use
typing.Optional,typing.Union,typing.List,typing.Tuple,typing.Dictin all annotation positions that are evaluated at runtime (function signatures, variable annotations outsideif TYPE_CHECKINGblocks).
Python 3.13 Changes (dis module):
dis.Instruction.starts_linechanged fromint | None(line number) tobool- New
dis.Instruction.line_numberattribute (int | None) added for the actual line number - On Python < 3.13,
starts_lineis only set on the first instruction of each source line; use a line-tracking loop to propagate line numbers to subsequent instructions
Bytecode/Opcode Compatibility (dis module):
- Never match specific opcode names (e.g.,
JUMP_BACKWARD,JUMP_ABSOLUTE,POP_JUMP_IF_TRUE). Opcode names change across Python versions — for example, Python 3.10 while loops usePOP_JUMP_IF_TRUEfor backward jumps, Python 3.11+ usesJUMP_BACKWARD, andJUMP_ABSOLUTEwas removed in 3.12. - Always use abstract
dismodule categories when possible:dis.hasjabs(absolute jump opcodes),dis.hasjrel(relative jump opcodes),dis.hasconst,dis.hasname, etc. These are maintained by CPython and work across all versions. - For call detection, matching
opname.startswith("CALL")is acceptable since that prefix has been stable, but prefer opcode integer sets over name strings for hot paths. - When checking jump direction (forward vs backward), use
instr.argval(whichdisresolves to an absolute offset) and compare againstinstr.offset, rather than relying on opcode names to imply direction.
Python 3.14 Changes:
argparsenow has built-in colored help output (color=Trueparameter)RichArgParseruses Rich for colors on Python < 3.14, native argparse colors on 3.14+
Argument Parsing (scalene_parseargs.py)
class RichArgParser(argparse.ArgumentParser):
"""ArgumentParser that uses Rich for colored output on Python < 3.14."""
def __init__(self, *args, **kwargs):
if sys.version_info < (3, 14):
from rich.console import Console
self._console = Console()
else:
self._console = None
super().__init__(*args, **kwargs)The _colorize_help_for_rich() function applies Python 3.14-style colors using Rich markup:
usage:andoptions:→ bold blue- Program name → bold magenta
- Long options (
--foo) → bold cyan - Short options (
-h) → bold green - Metavars (
FOO) → bold yellow
GUI Patterns
Preventing Browser Password Prompts:
Use autocomplete="one-time-code" on password/API key inputs to prevent browsers from offering to save them:
<input type="password" id="api-key" autocomplete="one-time-code">Show/Hide Password Toggle:
function togglePassword(inputId: string, button: HTMLButtonElement): void {
const input = document.getElementById(inputId) as HTMLInputElement;
if (input.type === "password") {
input.type = "text";
button.textContent = "Hide";
} else {
input.type = "password";
button.textContent = "Show";
}
}Provider Field Visibility: Use CSS classes to show/hide provider-specific fields:
function toggleServiceFields(): void {
const service = (document.getElementById("service") as HTMLSelectElement).value;
// Hide all provider sections
document.querySelectorAll(".provider-section").forEach((el) => {
(el as HTMLElement).style.display = "none";
});
// Show selected provider section
const section = document.querySelector(`.${service}-fields`);
if (section) (section as HTMLElement).style.display = "block";
}Persistent Form Elements:
Add class persistent to inputs that should be saved/restored from localStorage:
<input type="text" id="api-key" class="persistent">The persistence.ts module handles save/restore automatically.
Standalone HTML Generation:
The generate_html() function in scalene_utility.py supports a standalone parameter:
- When
standalone=False(default): Assets are referenced as local files (e.g.,<script src="jquery-3.6.0.slim.min.js">) - When
standalone=True: All assets are embedded inline (JS/CSS as text, images as base64)
The Jinja2 template uses conditionals:
{% if standalone %}
<script>{{ jquery_js }}</script>
<style>{{ bootstrap_css }}</style>
{% else %}
<script src="jquery-3.6.0.slim.min.js"></script>
<link href="bootstrap.min.css" rel="stylesheet">
{% endif %}Module Imports
When importing submodules, be explicit:
# Correct - mypy can verify this
import importlib.util
importlib.util.find_spec(mod_name)
# Wrong - mypy error: Module has no attribute "util"
import importlib
importlib.util.find_spec(mod_name)Testing
Test Files (tests/)
test_coverup_*.py- Auto-generated coverage teststest_runningstats.py- Statistics tests (requireshypothesis)test_scalene_json.py- JSON output tests (requireshypothesis)test_nested_package_relative_import.py- Import handling tests
Test Dependencies
pip install pytest pytest-asyncio hypothesisRunning Tests Across Python Versions
for v in 3.9 3.10 3.11 3.12 3.13 3.14; do
python$v -m pytest tests/test_coverup_83.py -v
doneFlaky Smoketests
The smoketests in test/ can be flaky due to timing/sampling issues inherent to profiling:
- "No non-zero lines in X" - The profiler didn't collect enough samples. This happens when the test runs too quickly or signal delivery timing varies.
- "Expected function 'X' not returned" - A function wasn't sampled. Common with short-running functions.
These failures are usually timing-related and pass on re-run. They're more common on CI due to variable machine load.
Port Binding in Tests
When testing port availability, never use hardcoded ports - they may already be in use on CI runners:
# Bad - port 49200 might be in use
port = 49200
sock.bind(("", port))
# Good - find an available port first
port = find_available_port(49200, 49300)
if port is None:
return # Skip test if no ports available
sock.bind(("", port))CI/CD (.github/workflows/)
run-linters.yml- Runs mypy and ruff on Python 3.9-3.14tests.yml- Runs pytest on Python 3.9-3.14build-and-upload.yml- Build and publish to PyPI
Common Tasks
Adding a New CLI Option
- Add default value in
scalene_arguments.py:class ScaleneArgumentsDict(TypedDict, total=False): my_option: bool - Add argument in
scalene_parseargs.py:parser.add_argument( "--my-option", dest="my_option", action="store_true", default=defaults.my_option, help="Description of option", )
Adding a New AI Provider
- Create provider module (
scalene/scalene-gui/newprovider.ts):export async function sendPromptToNewProvider( prompt: string, apiKey: string ): Promise<string> { // API call implementation } export async function fetchNewProviderModels(apiKey: string): Promise<string[]> { // Optional: fetch available models from API } - Update
optimizations.ts:- Import the new module
- Add case in
sendPromptToService()switch statement
- Update
index.html.template:- Add option to
#serviceselect dropdown - Add provider section with API key input, model selector, etc.
- Add CSS for
.newprovider-fieldsvisibility
- Add option to
- Update
scalene-gui.ts:- Add provider to
toggleServiceFields()function - Add refresh handler if dynamic model fetching is supported
- Update
getDefaultProvider()if env var support is needed
- Add provider to
- Update
persistence.ts(for env var support):- Add mapping in
envKeyMapfor new fields
- Add mapping in
- Update
launchbrowser.py(for env var support):- Add the field and its environment variable(s) to
ENV_API_KEY_VARIABLES - Add the field to
EnvApiKeys/envApiKeyFieldsinpersistence.ts
- Add the field and its environment variable(s) to
- Rebuild the bundle:
npm --prefix scalene/scalene-gui run build
Environment Variable API Keys
With scalene view --api-keys-from-env (opt-in), the GUI prepopulates API
keys from environment variables:
| Element ID | Environment Variable | Provider |
api-key | OPENAI_API_KEY | OpenAI |
anthropic-api-key | ANTHROPIC_API_KEY | Anthropic |
gemini-api-key | GEMINI_API_KEY or GOOGLE_API_KEY | Gemini |
azure-api-key | AZURE_OPENAI_API_KEY | Azure OpenAI |
azure-api-url | AZURE_OPENAI_ENDPOINT | Azure OpenAI |
aws-access-key | AWS_ACCESS_KEY_ID | Amazon Bedrock |
aws-secret-key | AWS_SECRET_ACCESS_KEY | Amazon Bedrock |
aws-region | AWS_DEFAULT_REGION or AWS_REGION | Amazon Bedrock |
Flow:
scalene view --api-keys-from-envpasses the flag tolaunchbrowser.py, whose local server reads the env vars and serves them from memory at/env-api-keys.json(an empty object without the flag)loadEnvApiKeys()inpersistence.tsfetches that on page load (only when the page is served over HTTP), before persistent fields are restoredpersistence.tsuses env vars as fallbacks when localStorage is empty;prefillNonPersistentEnvFields()fills the non-persistent OpenAI key
Never embed credentials in the generated HTML. scalene-profile.html is
written to the working directory, copied to the system temp dir, and
--standalone files exist to be shared (#1095;
tests/test_html_credential_security.py enforces this). The endpoint answers
only requests whose Host is localhost:<port>/127.0.0.1:<port> (blocks DNS
rebinding) and whose Sec-Fetch-Site, if sent, is same-origin; it sends no
CORS headers. The flag is rejected with --cli, --html, and --standalone.
Updating Version
Edit scalene/scalene_config.py:
scalene_version = "X.Y.Z"
scalene_date = "YYYY.MM.DD"Dependencies
Key runtime dependencies:
rich- Terminal formatting and colorscloudpickle- Serializationpynvml- NVIDIA GPU support (optional)
See requirements.txt for full list.
CLI Structure
Scalene uses a verb-based CLI with two main subcommands:
# Profile a program (saves to scalene-profile.json by default)
scalene run [options] yourprogram.py
# View an existing profile
scalene view [options] [profile.json]Run Subcommand Options
scalene run prog.py # profile, save to scalene-profile.json
scalene run -o my.json prog.py # save to custom file
scalene run --cpu-only prog.py # profile CPU only (faster)
scalene run -c config.yaml prog.py # load options from config file
scalene run prog.py --- --arg # pass args to programView Subcommand Options
scalene view # open in browser
scalene view --cli # view in terminal
scalene view --html # save to scalene-profile.html
scalene view --standalone # save as self-contained HTML (all assets embedded)
scalene view myprofile.json # open specific profileProfile Completion Message
After profiling completes, Scalene prints instructions for viewing the profile:
Scalene: profile saved to scalene-profile.json
To view in browser: scalene view
To view in terminal: scalene view --cliThe filename is only included in the command if a non-default output file was used.
YAML Configuration
Create a scalene.yaml file with options:
outfile: my-profile.json
cpu-only: true
profile-only: "mypackage,utils"
cpu-percent-threshold: 5Load with: scalene run -c scalene.yaml prog.py
Advanced Options
Use scalene run --help-advanced to see all options including:
--profile-all- profile all code, not just the target program--profile-only PATH- only profile files containing these strings--profile-exclude PATH- exclude files containing these strings--profile-system-libraries- profile Python stdlib and installed packages (skipped by default)--gpu- profile GPU time and memory--memory- profile memory usage--stacks- collect stack traces--profile-interval N- output profiles every N seconds
Smoke Tests
Smoke tests in test/ use the new CLI syntax:
# test/smoketest.py
cmd = [sys.executable, "-m", "scalene", "run", "-o", str(outfile), *rest, fname]GitHub Workflows
Workflows in .github/workflows/ use the new CLI:
# Profile with interval, then view
- run: python -m scalene run --profile-interval=2 test/testme.py && python -m scalene view --cli
# Profile with module invocation
- run: python -m scalene run --- -m import_stress_test && python -m scalene view --cliSignal Handling
Scalene uses several Unix signals for profiling. The signal assignments are in scalene_signals.py:
| Signal | Purpose | Platform |
SIGVTALRM | CPU profiling timer (default) | Unix |
SIGALRM | CPU profiling timer (real time mode) | Unix |
SIGILL | Start profiling (--on) | Unix |
SIGBUS | Stop profiling (--off) | Unix |
SIGPROF | memcpy tracking | Unix |
SIGXCPU | malloc tracking | Unix |
SIGXFSZ | free tracking | Unix |
Signal Conflicts with Libraries
Libraries like PyTorch Lightning may also use these signals. The replacement_signal_fns.py module handles conflicts:
On Linux: Uses real-time signals (SIGRTMIN+1 to SIGRTMIN+5) for redirection. When user code sets a handler for a Scalene signal, their handler is redirected to a real-time signal. Calls to raise_signal() and kill() are also redirected transparently.
On macOS/other platforms: Uses handler chaining. Both Scalene's handler and the user's handler are called when the signal fires.
# Platform-specific signal handling
_use_rt_signals = sys.platform == "linux" and hasattr(signal, "SIGRTMIN")
if _use_rt_signals:
# Linux: redirect to real-time signals
rt_base = signal.SIGRTMIN + 1
_signal_redirects[signal.SIGILL] = rt_base
else:
# macOS: chain handlers
def chained_handler(sig, frame):
scalene_handler(sig, frame)
user_handler(sig, frame)Frame Line Number Can Be None (Python 3.11+)
In Python 3.11+, frame.f_lineno can be None in edge cases (e.g., during multiprocessing cleanup). Always use a fallback:
lineno = frame.f_lineno if frame.f_lineno is not None else frame.f_code.co_firstlinenoNative Extension Build Issues
C++ Standard Library Conflicts with vendor/printf
The vendor/printf/printf.h header defines macros that conflict with C++ standard library:
#define vsnprintf vsnprintf_
#define snprintf snprintf_This breaks std::vsnprintf in <string> and other headers. Fix: Include C++ standard headers BEFORE vendor headers in src/source/libscalene.cpp:
// Include C++ standard headers FIRST
#include <cstddef>
#include <string>
// Then vendor headers that define conflicting macros
#include <heaplayers.h> // Eventually includes printf.hProfiling Guide
See Scalene-Agents.md for detailed information about interpreting Scalene's profiling output, including Python vs C time, memory metrics, and optimization strategies.
Debugging Guide
See Scalene-Debugging.md for signal handler debugging, async profiling debugging, the profile output pipeline (three separate renderers!), and unbounded growth prevention patterns.
GUI Development Guide
See Scalene-GUI.md for adding new columns, Vega-Lite chart types, pie chart best practices (two-wedge rendering, rotating pies), and the chart rendering flow.
Trending
Less talk lately.about the whole repository
Who's talking about plasma-umass/scalene
- Emery Berger“Scalene: a high-performance, high-precision CPU+GPU+memory profiler for Python (PyCon US 2021)”YouTube · May 19, 2021 · 28k views
- Emery Berger“Python Performance Matters: Emery Berger | Adobe Tech Summit 2022”YouTube · May 31, 2022 · 1.1k views
- A Hacker News story“Scalene: A high-performance, high-precision CPU, GPU, memory profiler for Python”Hacker News · Oct 21, 2024 · 183 points
- Captain Python“Top 12 Python Libraries For 2021”YouTube · Jul 14, 2021 · 81 views
- A Hacker News story“Scalene: A high-performance, CPU, GPU, and memory profiler for Python”Hacker News · Jun 18, 2023 · 36 points
The biggest 5 of 78 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 78
Talked about on GitHub, Bluesky, the web, Hacker News, YouTube and Stack Overflow (78 times).
On GitHub · 50
- Jul 29, 2024`os.listdir` (and presumably other os functions) fails in the face of signals — awslabs/mountpoint-s33 reactions · 3 comments
- Dec 24, 2025chore(deps): update dependency scalene to v2 — aignostics/python-sdk1 reaction · 1 comment
- Dec 22, 2025chore(deps-dev): update scalene requirement from <2,>=1.5.55 to >=1.5.55,<3 — aignostics/python-sdk1 reaction · 4 comments
- Mar 3, 2024Package request: scalene — NixOS/nixpkgs1 reaction
- Oct 27, 2023Use profiler to identify which lines of Python in Zarr-Python take longest — zarr-developers/zarr-benchmark1 reaction
45 more on GitHub
- Sep 14, 2023📖 Explore the use of Scalene and other profiling tools — NCAR/geocat-comp1 reaction
- Nov 24, 2021Package scalene — conda-forge/staged-recipes1 reaction
- Oct 26, 2026chore(deps-dev): bump scalene from 2.3.0 to 2.4.0 — jakob1379/rich-card0 reactions · 2 comments
- Oct 26, 2026Update scalene requirement from >=2.0 to >=2.3.0 — MValentinaMercado/PEF0 reactions
- Sep 28, 2026build(deps-dev): update scalene requirement from >=1.5.31 to >=2.3.0 — DiogoRibeiro7/academic-presentations0 reactions · 1 comment
- Sep 25, 2026scalene: Add version 2.3.0 — riseproject-dev/python-wheels0 reactions · 1 comment
- Sep 25, 2026build(deps): bump the python-deps group with 26 updates — astrogilda/tsbootstrap0 reactions · 3 comments
- Sep 5, 2026Update scalene to v2.3.0 — conda-forge/scalene-feedstock0 reactions · 3 comments
- Jul 26, 2026build: bump scalene from 1.5.55 to 2.3.0 — luanfreitas5/previsao-churn-explicavel0 reactions
- Jul 14, 2026deps: bump scalene from 2.1.3 to 2.3.0 — ll7/robot_sf_ll70 reactions · 2 comments
- Jul 8, 2026Bump scalene from 1.5.33 to 2.3.0 — Trigyn-Intern/AI-recruiter-screening-system-0 reactions · 1 comment
- Jul 3, 2026chore(deps-dev): bump scalene from 2.2.1 to 2.3.0 — jacksonpradolima/coleman0 reactions · 2 comments
- Jun 18, 2026Bump scalene from 2.2.1 to 2.3.0 — afaulconbridge/wildcamtools0 reactions
- Jun 12, 2026fix(deps): update dependency scalene to v2 — atlanhq/atlan-mysql-app0 reactions · 8 comments
- Jun 3, 2026Bump the minor-and-patch group with 7 updates — CiottiGiorgio/timberborn-vibed-power-mix0 reactions
- Jun 1, 2026chore(deps): bump scalene from 2.1.4 to 2.3.0 — sindre-nistad/snake-oil0 reactions · 1 comment
- May 25, 2026chore(deps-dev): update scalene requirement from <2.0,>=1.5.0 to >=1.5.0,<3.0 — atlanhq/atlan-mysql-app0 reactions · 6 comments
- May 22, 2026chore(deps): bump scalene from 2.2.1 to 2.3.0 — jacksonpradolima/coleman0 reactions · 5 comments
- Apr 13, 2026deps-dev(deps-dev): update scalene requirement from >=1.5.49 to >=2.2.1 — dbsectrainer/nist_800_53_scanner0 reactions · 2 comments
- Apr 13, 2026Bump the development group with 7 updates — paulrobello/new_tui_project_template0 reactions · 1 comment
- Apr 13, 2026Bump the development group with 7 updates — paulrobello/new_cli_project_template0 reactions · 1 comment
- Apr 3, 2026chore(deps): update dependency scalene to v2.4.0 — shortlink-org/marketing0 reactions
- Apr 2, 2026Bump the minor-and-patch group with 6 updates — CiottiGiorgio/timberborn-vibed-power-mix0 reactions
- Apr 1, 2026chore(deps): bump scalene from 2.1.4 to 2.2.1 — sindre-nistad/snake-oil0 reactions · 1 comment
- Mar 23, 2026build(deps-dev): bump scalene from 2.1.4 to 2.2.1 — boscorat/bank_statement_parser0 reactions · 1 comment
- Mar 23, 2026deps(deps): bump scalene from 2.1.4 to 2.2.1 — ZachFlint/Intellicrack0 reactions · 3 comments
- Mar 18, 2026python3Packages.scalene: 1.5.55 -> 2.1.4 — NixOS/nixpkgs0 reactions · 1 comment
- Mar 1, 2026chore(deps): bump scalene from 2.1.2 to 2.1.4 — sindre-nistad/snake-oil0 reactions · 2 comments
- Feb 28, 2026chore(deps): update dependency scalene to v2.1.4 — shortlink-org/marketing0 reactions
- Feb 24, 2026performance profile using Scalene — mandiant/capa0 reactions · 3 comments
- Feb 16, 2026Bump scalene from 2.1.3 to 2.1.4 — boscorat/bank_statement_parser0 reactions · 1 comment
- Feb 1, 2026chore(deps): bump scalene from 2.1.2 to 2.1.3 — sindre-nistad/snake-oil0 reactions · 3 comments
- Jan 31, 2026chore(deps): bump scalene from 1.5.51 to 2.1.2 — sindre-nistad/snake-oil0 reactions · 1 comment
- Jan 26, 2026Bump scalene from 2.0.1 to 2.1.0 — boscorat/bank_statement_parser0 reactions · 1 comment
- Dec 29, 2025Bump scalene from 1.5.55 to 2.0.1 — boscorat/bank_statement_parser0 reactions · 1 comment
- Dec 28, 2025chore(deps): update dependency scalene to v2 — shortlink-org/marketing0 reactions
- Dec 25, 2025Bump scalene from 1.5.55 to 2.0.1 — neuron7x/Kuramoto-synchronization-model0 reactions · 4 comments
- Dec 22, 2025Bump scalene from 1.5.55 to 2.0.0 — boscorat/bank_statement_parser0 reactions · 1 comment
- Dec 3, 2025Bump the "python-sync" group with 1 updates across multiple ecosystems — Jelly-RDF/pyjelly0 reactions · 2 comments
- Nov 6, 2025reduce pydra overhead — nipype/pydra0 reactions · 2 comments
- Oct 18, 2025[UNEXPECTED BEHAVIOR] CPU cores underused — pyscf/pyscf0 reactions · 4 comments
- Oct 15, 2025python3Packages.scalene: 1.5.52 -> 1.5.55 — NixOS/nixpkgs0 reactions · 4 comments
- Sep 29, 2025build(deps): Bump scalene from 1.5.38 to 1.5.55 — spencerduncan/jimbot0 reactions · 1 comment
- Sep 9, 2025Refactors and code improvement. — eve-esa/data-processing0 reactions
- Sep 9, 2025profile code — eve-esa/data-processing0 reactions
On Bluesky · 8
- Nov 29, 2024“Scalene is a high-performance CPU, GPU and memory profiler for Python that does a number of things that other Python profilers do not and… — @bradneuberg.bsky.social4 likes and reposts · 1 reply
- Sep 1, 2023Bonjour et bon vendredi ! Pour bien terminer cette semaine de reprise, si vous cherchez à améliorer les performances de vos projets Python,… — @ponceto91.bsky.social4 likes and reposts
- Sep 16, 2025https://github.com/plasma-umass/scalene — @tom-doerr.bsky.social1 likes and repost
- Nov 29, 2024“It runs orders of magnitude faster than many other profilers while delivering far more detailed information. It is also the first profiler… — @bradneuberg.bsky.social1 likes and repost
- Oct 22, 2024Scalene: A high-performance, high-precision CPU, GPU, memory profiler for Python https://github.com/plasma-umass/scalene… — @hn100.atproto.rocks1 likes and repost
3 more on Bluesky
- Jan 26, 2026You can't be an expert in every ecosystem. Ask your agent for help. Instead of guessing, I asked: "I need to profile Python for CPU &… — @kweinmeister.bsky.social0 likes and reposts · 1 reply
- Aug 31, 2023🚀 Skyrocketing! 🚀 (200+ new stars) 📦 plasma-umass / scalene ⭐ 9,150 (+329) 🗒 JavaScript Scalene: a high-performance, high-precision… — @github-trending.bsky.social0 likes and reposts · 1 reply
- Aug 31, 2023🚀 Skyrocketing! 🚀 (200+ new stars) 📦 plasma-umass / scalene ⭐ 9,150 (+329) 🗒 JavaScript Scalene: a high-performance, high-precision… — @github-trending-js.bsky.social0 likes and reposts · 1 reply
On the web · 7
- Jan 29, 2026Many scalene debug warnings & extremely slow profiling — google.com
- Jan 18, 2024Provide more meaningful feedback when Scalene has a " ... — google.com
- Aug 22, 2023Scalene: a high-performance, high-precision CPU, GPU, ... — zenodo.org
- Jul 21, 2021Profiling python module #244 - plasma-umass/scalene — google.com
- Jun 16, 2021Add high level documentation for profiling a region of code ... — google.com
2 more on the web
- May 3, 2021Scalene CLI does not work with Django application ... — google.com
- Jan 9, 2020Support `console_scripts` · Issue #3 · plasma-umass/scalene — google.com
On Hacker News · 5
- Oct 21, 2024Scalene: A high-performance, high-precision CPU, GPU, memory profiler for Python183 points · 23 comments
- Jun 18, 2023Scalene: A high-performance, CPU, GPU, and memory profiler for Python36 points · 4 comments
- Feb 19, 2023Scalene: A Python CPU/GPU/memory profiler with optimization proposals15 points · 1 comment
- Jan 5, 2023Scalene: A Python memory profiler with AI-powered optimization proposals6 points
- Jan 2, 2023Scalene now incorporates AI-powered optimization suggestions4 points · 2 comments
On YouTube · 4
- May 19, 2021Scalene: a high-performance, high-precision CPU+GPU+memory profiler for Python (PyCon US 2021) — Emery Berger28k views
- May 31, 2022Python Performance Matters: Emery Berger | Adobe Tech Summit 2022 — Emery Berger1.1k views
- Jul 14, 2021Top 12 Python Libraries For 2021 — Captain Python81 views
- Sep 2, 2023plasma-umass/scalene - Gource visualisation — Gourcer20 views
On Stack Overflow · 4
- Oct 30, 2022How do I profile a Python script?8 votes
- Jan 14, 2022Workaround to successfully profile python script using scalene profiler on macOS? Just forget it and use machine with Windows or Linux?2 votes · 1 answer
- Feb 27, 2023Scalene: An exception of type UnicodeEncodeError1 vote
- May 25, 2023What does Scalene profiler tools "peak" memory mean?0 votes
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

