Profiler Usage Guide
This guide covers the Screeps profiler functionality, including how to use it, the memory retention policy, and external archival.
Overview
The profiler is a CPU performance monitoring tool that tracks the execution time of decorated functions. It stores data in Memory.profiler and provides console commands for analysis.
Enabling the Profiler
The profiler is enabled at build time via the PROFILER_ENABLED environment variable:
1 | # Build with profiler enabled (default) |
The profiler auto-starts on the first tick when enabled. You can verify its status via the Screeps console:
1 | Profiler.status() // Returns "Profiler is running" or "Profiler is stopped" |
Console Commands
Access the profiler through the Profiler global in the Screeps console:
| Command | Description |
|---|---|
Profiler.start() |
Start collecting profiler data |
Profiler.stop() |
Stop collecting data |
Profiler.status() |
Check if profiler is running |
Profiler.output() |
Print CPU usage summary to console |
Profiler.clear() |
Clear all collected data |
Memory Retention Policy
To prevent unbounded memory growth, the profiler implements a retention policy that limits the number of tracked functions.
Configuration
1 | // packages/bot/src/main.ts |
How It Works
- Periodic Check: Every 100 ticks, the retention policy checks
Memory.profiler.data - Entry Count: If entries exceed
MAX_PROFILER_ENTRIES(500), pruning occurs - Priority Retention: Entries are sorted by total CPU time (descending)
- Pruning: The least significant entries (lowest CPU time) are removed
- Logging: Pruning events are logged:
"Profiler retention: pruned N entries, kept 500"
Why 500 Entries?
- Typical bot has 100-300 profiled functions
- 500 entries provide ample room for all significant functions
- Prevents memory bloat during extended operation (24+ hours)
- Minimizes serialization overhead per tick
External Archival
The monitoring workflow archives profiler data every 30 minutes to preserve historical data while keeping Memory lean.
Archive Script
1 | # Manual archival |
Archive Location
Archives are stored in reports/profiler/:
1 | reports/profiler/ |
Archive Contents
Each archive contains:
1 | { |
Monitoring Integration
The screeps-monitoring.yml workflow includes profiler management:
- Ensure Running:
ensure-profiler-running.ts- Verify profiler is active - Fetch Data:
fetch-profiler-console.ts- Get current profiler data - Archive Data:
archive-profiler-data.ts- Save and clear profiler data - Health Check:
check-profiler-health.ts- Validate profiler status
Health Check
The profiler health check (check-profiler-health.ts) reports:
- healthy: Profiler running, has data, data is fresh (<1 hour)
- warning: Profiler stopped, no data, or stale data
- error: Report missing, parse failure, or fetch error
Troubleshooting
Profiler Not Running
1 | // In console |
Or wait for the next deployment - auto-start is enabled by default.
Profiler Data Returns Undefined
If Memory.profiler.data returns undefined despite profiler being enabled:
Check build configuration: Ensure
PROFILER_ENABLEDis set correctly1
2
3
4
5# Build with profiler enabled (default)
yarn build
# Verify in console
Profiler.status() // Should return "Profiler is running"Verify Memory.profiler structure: The profiler should auto-initialize Memory
1
2
3// In console - check if structure exists
JSON.stringify(Memory.profiler)
// Expected: {"data":{},"total":0,"start":<tick>}Check for type mismatch: The build system uses string
"true"or"false"for__PROFILER_ENABLED__. If runtime comparisons fail, verify the build output:1
2
3# Check built output for correct conditionals
grep -A2 "ensureProfilerRunning" dist/main.js
# Should show `if (false)` when profiler is enabledRelated issue: #1499 - Fixed a type mismatch where
__PROFILER_ENABLED__was being interpreted as a boolean instead of a string, causing profiler data export to fail.
High Memory Usage
The retention policy should prevent this. If you see excessive Memory.profiler size:
- Check if retention policy is running (look for log messages)
- Manually clear:
Profiler.clear()followed byProfiler.start() - Wait for next monitoring workflow archival
Missing Historical Data
Check reports/profiler/archive-index.json for archive history. Archives are uploaded as workflow artifacts with 30-day retention.
Best Practices
- Let it run: Leave profiler enabled for continuous monitoring
- Check periodically: Use
Profiler.output()to review CPU hotspots - Archive before analysis: Archive data before major performance optimization
- Don’t over-decorate: Profile only significant functions to reduce overhead
Related Documentation
- Monitoring Baselines - Performance baseline management
- Stats Monitoring - General metrics monitoring
- Troubleshooting Telemetry - Debugging telemetry issues