Skip to main content

Performance Profiling

Profiling helps identify performance bottlenecks in the Meteor build tool and application. This guide covers built-in profilers and profiling techniques from the Meteor source code.

Built-in Profiler (METEOR_PROFILE)

Meteor includes a built-in profiler activated with the METEOR_PROFILE environment variable.

Basic Usage

The value is interpreted as a threshold in milliseconds:
This reports all calls taking more than 1ms.

Adjusting Threshold

Higher thresholds show only slower operations:

Understanding Output

You’ll see reports like:

Reading the Report

  • Top-down listing - Hierarchical call structure
  • Dotted lines - Entries with child entries
  • Time - Total cumulative time of all calls
  • Number in parentheses - Call count
  • Other entries - Time not accounted for by instrumented children

Key Metrics

Important sections to watch:
  • ProjectContext prepareProjectForBuild - Overall preparation time
  • _initializeCatalog - Package catalog loading
  • _resolveConstraints - Package version resolution
  • bundler.readJsImage - Loading compiled packages
  • ImportScanner#_readFile - File scanning and reading

Inspector Profiling (METEOR_INSPECT)

Meteor includes advanced profiling using Node.js’s inspector module, generating .cpuprofile files.

Basic Usage

Specify which functions to profile:

Profile Multiple Functions

Available Functions

Complete list for METEOR_INSPECT:
  • bundler.bundle
  • compiler.compile
  • Babel.compile
  • _readProjectMetadata
  • initializeCatalog
  • _downloadMissingPackages
  • _saveChangeMetadata
  • _realpath
  • package-client

Configuration Options

Context identifier:
Output directory:
Default: ./profiling Sampling interval:
Lower values = more detail, more memory usage. Maximum profile size:
Default: 2000 MB. Prevents out-of-memory errors.

Complete Example

Viewing Profile Results

Chrome DevTools

  1. Open Chrome DevTools (F12)
  2. Go to “Performance” or “Profiler” tab
  3. Click “Load Profile”
  4. Select the .cpuprofile file

Discoveryjs cpupro

Open-source interactive CPU profile viewer: Online:
  1. Visit https://discoveryjs.github.io/cpupro/
  2. Drag and drop your .cpuprofile file
  3. Explore the interactive visualization
Locally:
Advantages over Chrome DevTools:
  • Better handling of large profiles
  • More flexible filtering
  • Advanced search capabilities
  • Multiple visualization modes
  • Ability to compare profiles

Memory Optimization

Increasing Memory Limit

Inspector profiling consumes more memory:

Memory Considerations

  • Inspector profiling uses more memory than standard profiler
  • Large profiles (>2GB) automatically truncated
  • Consider METEOR_INSPECT_MAX_SIZE to limit memory usage
  • Use standard profiler for quick analysis

When to Use Each Profiler

Use METEOR_PROFILE when:

  • Quick performance check needed
  • General analysis of build times
  • Identifying obvious bottlenecks
  • Low memory environment
  • CI/CD performance monitoring

Use METEOR_INSPECT when:

  • Deep analysis required
  • Complex performance issues
  • Specific bottleneck investigation
  • Visual analysis needed
  • Comparing multiple builds

Instrumenting Code

Add profiling annotations to your own code:

Wrap Functions

Wrap Methods

Timed Blocks

Conditional Profiling

For packages loaded into the tool:

Performance Considerations

Unreported Work

Not covered by standard reports:
  • App start-up time
  • File watcher creation after rebuild

Caching Impact

Multiple cache layers affect timing:
  • Built packages and plugins
  • Compiler plugin results (including old file versions)
  • Linker output
  • Server program (for client-only changes)
  • Constraint solver results
Rebuild Timings:
  • Initial build: Slowest (cold cache)
  • First rebuild: Faster (warm cache)
  • Second rebuild: Even faster (fully warm)

Release vs Checkout

Performance differences: Release Mode:
  • Faster startup
  • Pre-built core packages
  • Efficient constraint solving
Checkout Mode:
  • Recompiles core packages
  • Large number of watched files
  • Extra delay after rebuild
  • Useful for tool development

Hardware and OS Impact

Disk Speed:
  • SSDs much faster than HDDs
  • Impacts cache read/write times
Operating System:
  • Mac/Linux: Fast file operations, symlinks, atomic renames
  • Windows: Slower file operations, no symlinks, rename = copy
  • Virus scanners can block/delay operations

Profiling Specific Areas

CSS Minification

CSS processing can take 500ms to several seconds:
Watch for:
  • CSS parsing time
  • CSS generation time
  • Source map generation

Constraint Solving

Watch for:
  • _resolveConstraints time
  • Package database queries
  • Logic solver invocations

File Watching

Watch for:
  • File watcher creation
  • File scanning operations
  • WatchSet merging

Import Scanning

Watch for:
  • ImportScanner#_readFile
  • File reading operations
  • SHA1 hashing

Comparing Performance

Before/After Optimization

  1. Baseline profile:
  2. Apply optimization
  3. New profile:
  4. Compare times for specific operations

Using meteor profile

Compare build performance:
This provides detailed timing for:
  • Prepare project
  • Build app
  • Individual build steps

Debugging with node-inspector

For interactive debugging:
Or break on first line:
Custom port:

Debugging Test Apps

Use different port to avoid collision with main tool.

Common Performance Issues

Large “other” Time

If you see:
Large “other” indicates missing instrumentation. Add more Profile calls to narrow down.

Source Map Generation

Noticeable time spent building source maps:
  • Consider more efficient use of source-map library
  • Look at Webpack’s optimizations

Linker Cache Writes

Large files taking seconds to write:
  • Watch files.writeFileAtomically calls
  • May appear outside top level (async)
  • Consider cleaning up old cache files

Package Server Updates

Slow “Updating package catalog…”:
  • Can take 5+ seconds
  • Sometimes much longer
  • Consider local package mirror

Best Practices

  1. Use appropriate profiler - METEOR_PROFILE for quick checks, METEOR_INSPECT for deep dives
  2. Set reasonable thresholds - Start with 100ms, adjust as needed
  3. Profile production builds - Different performance characteristics
  4. Clear caches first - For accurate cold-start measurements
  5. Profile multiple runs - Account for variability
  6. Watch for GC - Times can be inflated by garbage collection
  7. Consider hardware - SSD vs HDD, OS differences
  8. Instrument custom code - Add Profile calls to your plugins
  9. Compare apples to apples - Same cache state, same environment
  10. Document findings - Share results with team

Interpreting Results

Good Performance Indicators

  • Most time in actual work (compile, bundle)
  • Minimal “other” time
  • Efficient cache usage
  • Fast constraint solving

Red Flags

  • Large “other” sections
  • Repeated work (cache misses)
  • Slow file operations
  • Long constraint solving
  • Excessive file scanning