Files
Comfyui-Nodes-Stats/README.md
T
Ethanfel 5df56bc643 tools: add model-folder scan diagnostic
Standalone, read-only script that measures ComfyUI's boot-time model-folder
scan the same way folder_paths does (os.walk + getmtime per dir), ranks
folders by cost, detects network mounts and their actimeo/cache options, and
names the worst offender. Helps diagnose slow "scanning model folders" boots.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 11:13:48 +02:00

216 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ComfyUI Node Usage Stats
<p align="center">
<img src="docs/logo.svg" width="120" alt="Node Stats logo">
</p>
A ComfyUI custom node package that silently tracks which nodes, packages, and model files you actually use. Helps identify unused packages and models that are safe to remove — keeping your ComfyUI install lean.
## Features
- **Silent tracking** — hooks into every prompt submission, zero config needed
- **Node & model tracking** — tracks custom node packages and model files (checkpoints, VAEs, ControlNets, etc.) separately
- **Per-package classification** — packages are sorted into tiers based on usage recency
- **Per-model classification** — models grouped by type (checkpoints, vae, …) with the same recency tiers
- **Smart aging** — items gradually move from "recently unused" to "safe to remove" over time
- **Uninstall detection** — removed packages/models are flagged separately, historical data preserved
- **Expandable detail** — click any package to see individual node-level stats
- **One-click disable** — disable unused packages straight from the dialog via ComfyUI Manager (per-package or in bulk), reversible at any time
- **Non-blocking** — DB writes happen in a background thread, no impact on workflow execution
## Package Classification
Packages are classified into tiers based on when they were last used:
<table>
<tr>
<td><img src="docs/status_used.svg" width="18"> <b>Used</b></td>
<td>Actively used within the last month</td>
</tr>
<tr>
<td><img src="docs/status_unused_new.svg" width="18"> <b>Recently Unused</b></td>
<td>Not used yet, but tracking started less than a month ago — too early to judge</td>
</tr>
<tr>
<td><img src="docs/status_consider.svg" width="18"> <b>Consider Removing</b></td>
<td>Unused for 12 months — worth reviewing</td>
</tr>
<tr>
<td><img src="docs/status_safe.svg" width="18"> <b>Safe to Remove</b></td>
<td>Unused for 2+ months — confident removal candidate</td>
</tr>
<tr>
<td><img src="docs/status_uninstalled.svg" width="18"> <b>Uninstalled</b></td>
<td>Previously tracked but no longer installed — shown for reference</td>
</tr>
</table>
## Installation
```bash
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/ethanfel/Comfyui-Nodes-Stats.git
```
Restart ComfyUI. Tracking starts immediately and silently.
## Usage
### UI
Click the **Node Stats** button (bar chart icon) in the ComfyUI top menu bar. A dialog opens with two tabs:
**Nodes tab**
- Summary bar with counts for each classification tier
- Sections for each tier, sorted from most actionable to least
- Expandable rows — click any package to see per-node execution counts and timestamps
- **Disable** buttons on the "Safe to Remove" and "Consider Removing" tiers (see below)
### Disabling unused packages
When [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager) is installed, the
"Safe to Remove" and "Consider Removing" sections show a **Disable** button on each
package, plus a **Disable all** button per section. Disabling:
- Hands off to ComfyUI Manager, which moves the package into `custom_nodes/.disabled/`
- Is fully reversible — re-enable any package from ComfyUI Manager whenever you like
- Requires a ComfyUI restart to unload the package from the running session (a banner
with a **Restart ComfyUI** button appears after disabling)
If ComfyUI Manager is not installed, the disable buttons are hidden and stats work as before.
**Models tab**
- Summary bar with counts for each tier across all model types
- Sections per model type (checkpoints, vae, controlnet, …)
- Per-model table showing execution count, last used date, and status
### API
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/nodes-stats/packages` | GET | Per-package aggregated stats with classification |
| `/nodes-stats/usage` | GET | Raw per-node usage data |
| `/nodes-stats/models` | GET | Per-type model stats with classification |
| `/nodes-stats/reset` | POST | Clear all tracked data |
```bash
curl http://localhost:8188/nodes-stats/packages | python3 -m json.tool
```
<details>
<summary>Example response</summary>
```json
[
{
"package": "ComfyUI-Impact-Pack",
"total_executions": 42,
"used_nodes": 5,
"total_nodes": 30,
"last_seen": "2026-02-22T12:00:00+00:00",
"installed": true,
"status": "used",
"nodes": [
{
"class_type": "SAMDetectorCombined",
"package": "ComfyUI-Impact-Pack",
"count": 20,
"first_seen": "2026-01-01T00:00:00+00:00",
"last_seen": "2026-02-22T12:00:00+00:00"
}
]
},
{
"package": "ComfyUI-Unused-Nodes",
"total_executions": 0,
"used_nodes": 0,
"total_nodes": 12,
"last_seen": null,
"installed": true,
"status": "safe_to_remove",
"nodes": []
}
]
```
</details>
## How It Works
```
Queue Prompt ──> Prompt Handler ──> Extract class_types + prompt ──> Background Thread
┌───────────────────────────────┘
SQLite DB
usage_stats.db
┌─────────────┐
│ node_usage │ per-node counts & timestamps
│ prompt_log │ full node list per prompt
│ model_usage │ per-model counts & timestamps
└─────────────┘
GET /nodes-stats/packages ◄─────────┤
GET /nodes-stats/models ◄─────────┘
Merge DB data with installed
nodes/models, classify by recency
JSON response ──> UI Dialog (Nodes tab / Models tab)
```
1. Registers a prompt handler via `PromptServer.instance.add_on_prompt_handler()`
2. On every prompt submission, extracts `class_type` from each node and the full prompt dict
3. Offloads recording to a background thread (non-blocking)
4. Maps each class_type to its source package using `RELATIVE_PYTHON_MODULE`
5. Detects model file selections by introspecting each node's `INPUT_TYPES()` for folder-dropdown inputs, then resolves filenames via `folder_paths`
6. Upserts per-node and per-model counts and timestamps into SQLite
7. On stats request, merges DB data with current node registry / installed models and classifies by recency
## Data Storage
All data is stored in `<ComfyUI user dir>/nodes_stats/usage_stats.db` (survives extension reinstalls).
| Table | Contents |
|-------|----------|
| `node_usage` | Per-node: class_type, package, execution count, first/last seen |
| `prompt_log` | Per-prompt: timestamp, JSON array of all class_types used |
| `model_usage` | Per-model: filename, type, execution count, first/last seen |
Use `POST /nodes-stats/reset` to clear all data and start fresh.
## Slow ComfyUI boot? Diagnose the model-folder scan
If ComfyUI is slow to start at the "scanning model folders" / "Building node
definitions" stage, the cause is almost always model folders on a slow (often
network) filesystem: ComfyUI walks every registered model folder on each boot,
and that cache is in-memory only (lost on restart).
`tools/diagnose_model_scan.py` measures this the same way ComfyUI does and ranks
the folders by scan cost, flags network mounts and their `actimeo`/`cache`
options, and points at the worst offender. It is read-only.
```bash
cd /path/to/ComfyUI
python tools/diagnose_model_scan.py # 30s cap per folder
python tools/diagnose_model_scan.py --timeout 600 --warm # full timing + warm pass
```
Typical fix for network-mounted model folders (CIFS): raise the attribute-cache
timeout so the kernel keeps the listing warm across restarts, e.g.
`actimeo=3600,acdirmax=3600,acregmax=3600,cache=loose`.
## File Structure
```
__init__.py Entry point: prompt handler, API routes
mapper.py class_type → package mapping; model filename → type mapping
tracker.py SQLite persistence and stats aggregation
js/nodes_stats.js Frontend: menu button + stats dialog (Nodes/Models tabs)
tools/diagnose_model_scan.py Standalone: diagnose slow model-folder scans at boot
pyproject.toml Package metadata
tests/ Unit tests for tracker and mapper
```