Rider's Out-of-Process Architecture: How a Separate ReSharper Backend Keeps the UI Responsive in Large Solutions
Rider's UI stays fast because analysis runs in a dedicated .NET process that communicates via the undocumented RD protocol, exchanging versioned snapshots and handling crashes gracefully.
13 Jul 2025, 13:59 UTC

Problem and Takeaway
When editing a solution with tens of thousands of files, the IDE can freeze while ReSharper performs type resolution, inspections, and refactorings. The practical takeaway is that Rider keeps the UI responsive by moving the heavy analysis work into a separate .NET process that communicates with the UI via an internal protocol.
Requirements
- Provide deep C#/VB.NET/F# analysis (type resolution, inspections, refactorings) inside an IntelliJ-based IDE.
- Keep the UI thread free to respond to user gestures.
- Support solutions exceeding 100k files.
- Allow the analysis engine to run with a 64-bit JVM heap, independent of the UI process.
Smallest Suitable Design
The minimal architecture consists of two processes:
- Frontend – the IntelliJ Platform (JVM) that handles editing, project model, VCS integration, and UI rendering.
- Backend – a .NET process that owns the semantic model (PSI), inspections, and refactorings.
They exchange immutable snapshots through the RD (ReSharper Distributed) protocol over a local pipe or socket. Neither process trusts the other's mutable state; reconciliation occurs via versioned snapshots and explicit invalidation messages.
Trust and Data Boundaries
The frontend is the authoritative source for file text, caret position, and user gestures. The backend is the authoritative source for semantic truth (symbols, types, diagnostics). This separation prevents race conditions and allows each side to operate with its own garbage collector and memory model.
Operational Checks
- Heartbeat pings – the frontend sends periodic pings to the backend; a missing ping indicates a stall.
- Solution-load events – RD events report progress when a solution is opened, allowing the UI to show a spinner.
- Telemetry – memory and CPU usage are displayed in Rider’s status bar, sourced from process-level metrics.
- Logging – the backend writes diagnostic logs to
~/Library/Logs/JetBrains/Rider<version>/resharper/for post-mortem analysis.
Failure Modes
- Backend crash – the frontend detects the termination, shows a “ReSharper host terminated” dialog, and offers to restart the backend while preserving open editors.
- Protocol version mismatch – startup aborts with a clear error message; the user must upgrade Rider or the backend plugin.
- Stale snapshot – if the frontend detects an out-of-date snapshot, it requests a full resync, which may cause a brief UI pause.
- Out-of-memory in backend – the process is recycled; transient analysis state is lost, resulting in temporary inspection flicker.
Conditions That Could Change the Design
- If inter-process communication overhead becomes unacceptable, Rider might move to an in-process architecture.
- Adoption of the Language Server Protocol (LSP) as the primary communication method could make the RD protocol obsolete.
- Shifting to a remote or cloud backend for thin-client scenarios would replace the local pipe with a networked service.
Concrete Configuration Example: Tuning the Backend Heap
Large solutions may exhaust the default 2 GB heap allocated to the ReSharper backend. The heap size can be increased via the resharper.x64.vmoptions file.
- Locate the file
resharper.x64.vmoptionsin the Rider configuration directory (e.g.,~/Library/Preferences/JetBrains/Rider<version>/options/). - Edit the file and add or modify the line:
-Xmx4g - Save the file and restart Rider.
- Verify the new heap limit in the Process Explorer (Help → Diagnostic Tools → Process Explorer). The
ReSharper.Hostprocess should now show a largerHeap Size.
Risk: setting the heap too high can cause the host to be killed by the OS if other processes consume excessive memory, leading to a forced restart of the backend and temporary loss of analysis state.
Verification Steps
- Open Rider and navigate to Help → Diagnostic Tools → Process Explorer. You should see two processes:
Rider64.exe(frontend) andReSharper.Host(backend). - Trigger a backend crash by launching a custom plugin that throws an unhandled exception (e.g.,
throw new Exception()) and confirm that the UI displays the restart dialog without closing open editor tabs. - Monitor the
resharper_*.logfiles while loading a large solution. Look for lines indicating “snapshot sent”, “snapshot received”, and “invalidation” messages to ensure the RD protocol is active. - Change the
-Xmxvalue inresharper.x64.vmoptions, restart Rider, and re-check the Process Explorer to confirm the updated heap limit.
Limitations and Practical Checks
- The RD protocol is internal, undocumented, and version-locked; third-party plugins cannot reliably speak it, limiting extensibility.
- A backend restart discards transient analysis state (e.g., incomplete type inference), causing a brief flicker of inspections as the backend rebuilds its model.
- Default backend heap (2 GB) may be insufficient for very large solutions; increasing
-Xmxis often required, but excessive values risk OOM kills. - File-system watches on network shares can desynchronize frontend and backend snapshots, leading to temporary inconsistencies.
Conclusion
Rider’s out-of-process architecture isolates the heavy lifting of C#/VB.NET/F# analysis from the UI, using versioned snapshots and a dedicated protocol to maintain responsiveness even in massive solutions. By monitoring process health, adjusting the backend heap, and understanding failure modes, developers can reliably leverage this design to keep the IDE snappy while benefiting from deep static analysis.