Running the IDE Where the Code Lives: An Architecture Note on JetBrains Remote Development
Split IntelliJ into a headless backend on an SSH host and a thin local client: sizing, trust boundaries, operational checks, and when to pick a different design.
14 Sept 2026, 22:07 UTC

Large IntelliJ-platform projects punish small machines. A full indexing run can pin a laptop's CPU, builds compete with the IDE for memory, and some teams can't keep source code on personal hardware at all. JetBrains Remote Development splits the IDE so the expensive half runs where the code already lives: a headless backend on a remote SSH host holds the project, indexes and toolchain, while a thin client on your workstation only draws the UI. The install is the easy part — whether the setup lasts depends on treating the remote host as stateful developer infrastructure, not a disposable VM.
How the split works
IntelliJ-platform IDEs — IntelliJ IDEA, PyCharm, GoLand, WebStorm and others — can run as two cooperating processes. The backend is the IDE without a UI: it opens the project, maintains its indexes (the searchable model the IDE builds over your code), and runs inspections, completions, VCS operations and run configurations. The JetBrains Client is the local app that renders editors, the terminal view and the debugger UI. JetBrains Gateway is the entry point that connects to a host over SSH and installs or starts a matching backend.
What crosses the network is UI state, not code: input events travel upstream, rendered editor state travels downstream, inside the SSH connection. Source files, indexes, build outputs and the SDK stay on the host.
Requirements
- A persistent, SSH-reachable host. Linux is the best-documented path; support for other host operating systems varies by release, so check current documentation.
- Sizing for indexing and builds, not just the code — a host that feels fine idle can still fall over on first project open.
- The toolchain on the host: JDK or interpreters, build tools, package-repository credentials. The backend cannot use your laptop's tools.
- SSH key-based authentication for each developer's own account.
- A backend version matched to the client. Gateway normally downloads a matching backend; pin versions explicitly if you install backends manually or restrict host network access.
- A license where applicable. Terms depend on the IDE edition and have changed over time — confirm current terms before rollout.
The smallest suitable design
Start with one dedicated host per developer, persistent storage for the project and IDE caches, a backend installed through Gateway, and a network surface limited to SSH with key authentication. Shared multi-tenant hosts are a later optimization: until per-user isolation and resource limits are proven, one developer per host removes noisy neighbors, shared credentials and cross-project leakage.
Define the connection once in ~/.ssh/config on the developer machine so Gateway and your terminal use the same path. Substitute your own host, user and key:
# ~/.ssh/config on the developer machine
Host jb-dev-1
HostName jb-dev-1.example.internal
User alice
IdentityFile ~/.ssh/id_ed25519_jb
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 4
IdentitiesOnly forces the listed key rather than whatever the SSH agent offers, keeping authentication predictable. ServerAliveInterval sends a keepalive every 30 seconds and declares the connection dead after four missed replies — roughly two minutes — so a broken link fails visibly instead of hanging silently behind NAT or a firewall.
Smoke-test the path from your workstation before opening Gateway. These are read-only commands; a normal account on the host is enough:
ssh jb-dev-1 'nproc && free -h && df -h .'
Expected result: the CPU count, memory and free disk you actually provisioned — if the numbers don't match, fix the host before blaming the IDE. Keep the private key readable only by your user (chmod 600), and don't share one account across developers: the SSH key is the root of trust for everything below.
For sizing, start conservative — for a single mid-sized service, 4 vCPU, 8 GB RAM and fast SSD storage is a common floor — and treat the first full indexing run as the real test. Watch memory and swap on the host while it runs: if the host swaps or the backend is killed by the kernel's out-of-memory handler, add memory before concluding the network is the problem.
Trust and data boundaries
The trust model is simple: whoever holds the SSH key controls the host and everything on it. Source, indexes and build outputs live on the host; the client keeps only UI state. That is usually the property compliance teams want, but it inverts laptop risk — the host must now be hardened, backed up and access-controlled like any server holding source code.
Two supply-chain details deserve deliberate decisions. The backend itself: Gateway downloads IDE binaries onto the host, so pin the version and mirror downloads internally on restricted networks. And plugins: install them deliberately and keep them compatible with the backend — an incompatible plugin can prevent the backend from starting at all.
The host is stateful in a way a laptop is not. Work that exists only on the host — uncommitted changes, unpushed branches — is lost with it. Push early and back up the host's storage.
Operational checks before onboarding a team
- Latency. If ping is allowed, measure round-trip time from the workstation; otherwise an
sshconnection's setup time is a rough proxy. As a rule of thumb, tens of milliseconds feel fine and past roughly 100 ms most people notice typing lag — set your own threshold by editing on the host for an hour before committing. - Backend health and logs. The backend writes its own logs on the host — an
idea.logunder the user's JetBrains cache tree; the exact path varies by version. Find it before you need it. - Resource headroom. Run one full indexing pass while watching CPU, memory and disk on the host. Undersized hosts fail exactly here.
- Version match. After any update, confirm client and backend report the same build; mismatched pairs are a common cause of sessions that won't start.
- A full smoke test: run a build from the terminal view, pull and push via VCS, and run and debug one test — before the second developer joins, not after.
Failure modes and what they look like
| Symptom | Likely cause | First check |
|---|---|---|
| Typing feels laggy | Round-trip latency | Measure RTT; compare with the threshold you set |
| Client disconnects, work resumes on reconnect | Network drop — backend state persists on the host | Keepalives configured; backend process still alive on the host |
| Backend dies during first indexing | Out of memory on an undersized host | Host memory and swap during indexing; backend log |
| Session won't start after an update | Client/backend version mismatch or incompatible plugin | Backend log; pin versions, remove recently added plugins |
| Nothing connects at all | SSH path broken | Plain ssh from a terminal: key, account, firewall |
The asymmetry that matters: a network drop interrupts you but destroys nothing — the backend keeps project state on the host and you reattach when the link returns. Total loss of SSH access blocks all work, though. Keepalives make failures visible, and a second way into the host (a provider console, a bastion) is cheap insurance.
When this design is the wrong one
- Sustained high latency or unreliable links. If the team's threshold can't be met, no tuning fixes typing feel.
- Compliance rules about where code may reside. If the host's location or tenancy is unacceptable, the split doesn't help.
- Ephemeral hosts without persistent volumes. IDE caches are the hidden cost: without persistent storage, every new host re-indexes the project from scratch, which can make remote development slower than local.
- Heavy local tooling. GPUs, attached hardware, USB-tethered devices — a thin client reaches none of it. A local IDE with remote builds and test execution is often the better pattern: only code sync and build output cross the network, and the IDE stays local and responsive.
Limitations and how to verify the result
This note describes Remote Development as it behaves in recent IntelliJ-platform releases. Exact menu names, download mechanics, supported host operating systems and licensing differ between versions and have changed over time; verify against the current JetBrains documentation for Remote Development and Gateway before rollout, and confirm licensing for your IDE edition rather than assuming it.
A practical verification before anyone depends on it: reproduce the setup on a single test VM. Connect through Gateway, then confirm the split is real — the workstation holds only the client, while a process listing and disk usage on the host show the project, indexes and toolchain. Run one full indexing pass while watching the host's resources, then spend an hour editing, running and debugging through the client. If latency, memory and the smoke test all pass your thresholds, the design holds; if not, the failure modes above point at which one to fix first.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.