Hello everyone,
We would like to share some important updates to the threading framework in the IntelliJ Platform 2026.3.
This release focuses on major internal refactorings. Our efforts are directed at minimizing the impact on existing code, but nevertheless, there are some changes worth knowing about.
-
PSI syntax trees are now persistent (see IJPL-236269).
In the previous release (2026.2), we modified the internal representation of our PSI syntax trees to enable persistence (a.k.a. versioning). In this release (2026.3), we are enabling this functionality.
This is a major change, and it has several implications:- PSI syntax trees are now heavier due to the bookkeeping overhead for persistent structures. This overhead affects both memory usage and performance. We took a close look at scenarios where trees are heavily used, and in our benchmarks, performance degradation was almost nonexistent. However, if a plugin interacts with syntax trees in an asymptotically suboptimal way (i.e., processing trees in
O(n^2)time), the slowdown will be amplified by our changes. - The IDE is now able to work with a consistent snapshot of syntax trees without the read lock. The primary intended user of this functionality is the UI thread—we are moving towards eliminating the read/write lock from the UI thread, and having read-lock-free access to consistent syntax trees helps us achieve this without a significant rewrite of the existing business logic. If you are interested, you can explore
PsiVersioningService#freezePsiVersion.
- PSI syntax trees are now heavier due to the bookkeeping overhead for persistent structures. This overhead affects both memory usage and performance. We took a close look at scenarios where trees are heavily used, and in our benchmarks, performance degradation was almost nonexistent. However, if a plugin interacts with syntax trees in an asymptotically suboptimal way (i.e., processing trees in
-
We are prohibiting read lock access during editor painting (see IJPL-248910).
Our research has shown that the main reason for acquiring the read lock during painting is the need to access PSI trees. If your plugin falls into this category, consider using
PsiVersioningService#freezePsiVersionto avoid triggering the assertion.
Note that we do not intend to break existing functionality—the error is simply logged; no exception is thrown. -
edtWriteActionno longer blocks the UI thread (see IJPL-236701).This is a subtle but important change that might break some assumptions in tests. Note that it is still preferable to use the regular
writeAction, as it runs in the background. -
We have removed the write-intent lock from arrow key processing (see IJPL-231208).
This change is a battle test for persistent syntax trees. You are welcome to use
PsiVersioningService#freezePsiVersionif your functionality bound to arrow keys depends on having read access to PSI trees. -
The IDE is now resilient to thread starvation (see IJPL-214442).
For years, the IDE was plagued by a specific kind of deadlock—thread starvation. This problem is rooted in the Kotlin coroutines machinery, where the default CPU-bound thread pool can be exhausted by continuous blocking. We have patched the coroutines library so that the IDE can recover from thread starvation. Note that this is still logged as an error, and the underlying cause is still worth fixing.
Thank you for your attention!