Skip to main content
Tree-sitter is designed for high performance, but achieving optimal speed requires understanding its performance characteristics and following best practices.

Core Performance Principles

Incremental

Reuse unchanged subtrees during reparsing

Lazy

Create nodes only when accessed

Zero-copy

Reference source text instead of copying

Parsing Performance

Reuse Parser Instances

Don’t:
Do:
Creating a parser allocates internal buffers. Reusing parsers amortizes this cost.

Leverage Incremental Parsing

Incremental parsing is Tree-sitter’s superpower:
Performance impact:
  • Full parse: ~1-2ms for 1000 lines
  • Incremental parse: ~0.1-0.2ms for small edits
Speedup: 10-20x for typical edits

Set Parsing Limits

Prevent runaway parsing on pathological input:

Use Cancellation Flags

For responsive UIs, allow cancellation:

Query Performance

Reuse Query Objects

Don’t:
Do:

Reuse Query Cursors

Query cursors maintain internal state:
One cursor per thread is optimal. Cursors are NOT thread-safe.

Set Query Ranges

Limit query execution to relevant regions:
Impact: 5-10x speedup for large files when querying small regions.

Optimize Query Patterns

Specific patterns are faster:
Order patterns by specificity:

Use Pattern Indices

Filter matches by pattern:

Syntax Highlighting Performance

Reuse Highlighter

Configure Highlight Names

Limit recognized highlights:
Fewer highlights = faster matching.

Buffer HTML Output

Pre-allocate HTML buffer:
HtmlRenderer reserves 10KB by default (BUFFER_HTML_RESERVE_CAPACITY).

Limit Injection Depth

Language injections can nest deeply:

Tags Generation Performance

Reuse TagsContext

Batch Tag Queries

Process multiple files in parallel:

Optimize for Large Files

For files >10,000 lines:

Memory Management

Tree Copying

Copying trees is cheap (atomic refcount increment):

Node Lifetimes

Nodes borrow from the tree:

Avoid Leaking Parsers

Parsers must be explicitly deleted in C:
In Rust, Drop handles cleanup automatically.

Benchmarking

Measure Full Parse Speed

Measure Incremental Parse Speed

Measure Query Speed

Common Performance Pitfalls

❌ Creating Parsers in Hot Loops

❌ Not Using Incremental Parsing

❌ Compiling Queries Repeatedly

❌ Not Setting Query Ranges

❌ Deep Language Injection Nesting

Limit injection depth to prevent exponential slowdown.

Performance Targets

Typical performance on modern hardware (Intel i7, 2.5 GHz):
Actual performance varies by language grammar complexity and query patterns.

Profiling Tools

Rust Profiling

C Profiling

Chrome Tracing

For detailed timeline analysis:
Open trace-*.json in Chrome’s chrome://tracing.

Production Optimization Checklist

  • Single parser instance per thread
  • Incremental parsing for edits
  • Cancellation flags for long operations
  • Timeout limits set appropriately
  • Queries compiled once and cached
  • Query cursors reused
  • Query ranges set for visible regions
  • Patterns ordered by specificity
  • Trees copied for thread safety
  • No long-lived node references
  • Parsers properly deleted (C only)
  • Buffers pre-allocated for output
  • Separate parsers per thread
  • Separate query cursors per thread
  • Tree copies for parallel processing
  • No shared mutable state

Implementation

Understand internal architecture

Advanced Parsing

Learn advanced parsing techniques