The all-in-one SSH/SFTP desktop client for GPU servers.
Terminal, file transfers, and real-time CPU · RAM · Disk · GPU telemetry (NVIDIA / AMD / Intel / Apple Silicon) — in a single native window.
Working on a remote GPU box usually means juggling an SSH client, an SFTP tool, and a second terminal running watch nvidia-smi. GpuTerm replaces all three. Connect once and get an xterm.js terminal, a drag-and-drop SFTP browser, and a live telemetry bar that polls CPU, memory, disk, logged-in users, and every GPU on the host — NVIDIA, AMD, Intel, or Apple Silicon, on Linux, macOS, and Windows remotes alike — over its own SSH channel, so monitoring never blocks your shell.
Status: beta. Download the latest prerelease from the Releases page or build from source below.
- Full PTY terminal powered by xterm.js and Rust
ssh2 - Multiple concurrent sessions — each keeps its own terminal, scrollback, and SFTP path; click a connected profile in the sidebar to switch
- ProxyJump — tunnel through a saved profile as a bastion (per-key-type host verification along the way)
- Password, private key (with passphrase), and SSH agent authentication
- UTF-8 safe streaming — multibyte characters (한글, 日本語, emoji) survive chunked reads
- MOTD and early output are buffered and replayed, never lost to connection races
- Automatic remote PTY resize and SSH keepalive
- Side-by-side remote/local panels with drag-and-drop upload & download
- Streaming 1 MiB chunked transfers with a progress queue and per-file cancellation
- Downloads are written to a temporary file and atomically renamed — no partial files ever
- Overwrite confirmation, delete, mkdir, and a native OS folder picker
- Resizable split between terminal and SFTP panes (persisted across launches)
- Bottom status bar polling CPU, RAM, disk, logged-in users, and NVIDIA, AMD (ROCm), Intel, and Apple Silicon GPUs every 1–10 s
- Click any section for a draggable, resizable detail popover: per-core CPU usage, top processes, VRAM/power/temperature per GPU, full mount list
- Pop any detail view out into its own OS window — it refreshes independently and closes with its session
- Telemetry runs on a dedicated SSH connection (per session) with automatic reconnect and exponential backoff
- Non-NVIDIA hosts gracefully fall back to system-only metrics
- Passwords live in memory only — never written to disk
- Trust-on-first-use host key prompt with SHA-256 fingerprint; mismatches block the connection
- Restrictive Tauri Content Security Policy in production and development
Grab the installer for your OS from the latest release (.msi/.exe, .dmg, .deb/.AppImage).
Prerequisites: Node.js ≥ 20, npm ≥ 10, Rust stable, and the Tauri prerequisites for your OS.
Per-OS prerequisite details
Windows
- Visual Studio Build Tools 2022 with the Desktop development with C++ workload
- WebView2 Runtime (preinstalled on Windows 10/11)
- Git for Windows
- Strawberry Perl (
winget install StrawberryPerl.StrawberryPerl) — required to compile the vendored OpenSSL that backs the SSH library
macOS
xcode-select --installLinux (Debian/Ubuntu)
sudo apt update
sudo apt install -y libwebkit2gtk-4.1-dev build-essential curl wget file \
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-devgit clone https://github.com/fortranmentis/GPUTERM.git
cd GPUTERM
npm install
# Run the desktop app in development mode
npm run tauri:dev
# Package a distributable build (output: src-tauri/target/release/bundle)
npm run tauri:build
npm run devstarts the Vite frontend alone — useful for layout work, but SSH/SFTP/telemetry require the full Tauri app.
- Create a profile — enter host, port, username, and a password or private key path in the sidebar. Press New to start a fresh profile, Save to keep it.
- Connect — on first contact GpuTerm shows the server's SHA-256 host key fingerprint and asks for confirmation before trusting it. Connect as many servers as you like; connected profiles show a green dot, and clicking one switches the whole view to that session.
- Work — type in the terminal, drag files between the SFTP panels, and watch live metrics in the bottom bar. Click CPU / RAM / Disk / GPU / Users for detail popovers you can drag around, resize, or pop out into separate windows with the ↗ button.
SFTP transfer details
- Drop multiple files at once; each becomes an independent queue item with progress, status, and error reporting.
- Running transfers can be canceled individually from the queue.
- If the target file exists, GpuTerm asks before overwriting.
- The last local directory is remembered across launches.
- Directory drag-and-drop is detected but not yet transferred (see Roadmap).
Telemetry configuration
- Interval: 1, 2 (default), 5, or 10 seconds — detail popovers poll on the same cadence.
- Mode: GPU + System, GPU only, or System only.
- Ignore FS: comma-separated filesystem types hidden from the disk summary (default:
tmpfs,devtmpfs,squashfs,proc,sysfs,cgroup,cgroup2,overlay). The disk popover can temporarily reveal them. - Mount points are prioritized
/→/home→/data→/mnt*→/media*→ others; disks ≥ 80% are flagged warning, ≥ 90% critical.
Remote commands executed for telemetry
All metrics come from standard tools over SSH — nothing is installed on the server.
| Section | Linux | macOS | Windows |
|---|---|---|---|
| CPU | /proc/stat, /proc/loadavg, /proc/cpuinfo, nproc, lscpu |
sysctl (brand, cores, P/E split, loadavg), top -l 2 |
Win32_Processor, Win32_PerfRawData_PerfOS_Processor (CIM) |
| Memory | /proc/meminfo |
sysctl hw.memsize, vm_stat, vm.swapusage |
Win32_OperatingSystem, Win32_PageFileUsage (CIM) |
| Disk | df -P -T -B1 |
df -P -k + mount |
Win32_LogicalDisk (fixed drives) |
| Users | who |
who |
quser |
| GPU | nvidia-smi (NVIDIA), rocm-smi --json (AMD/ROCm), xpu-smi / intel_gpu_top (Intel) — auto-detected |
ioreg -c IOAccelerator (Apple GPU utilization, no root needed) |
nvidia-smi (NVIDIA, full metrics); WDDM GPU performance counters for AMD/Intel (utilization + VRAM) |
| Top processes | ps -eo … --sort=-%cpu / --sort=-rss |
ps -Ao … -r / -m |
Get-Process (two-sample CPU delta) |
Commands run with a 3-second timeout on a dedicated SSH connection (10 s on Windows to absorb PowerShell start-up). Windows commands are batched into a single PowerShell 5.1 invocation per poll and sent as -EncodedCommand, so they work with either cmd.exe or PowerShell as the OpenSSH default shell — nothing is installed and no admin rights are required. GpuTerm detects the remote OS and available GPU tools per host and shows a vendor tag on every card; intel_gpu_top needs root or CAP_PERFMON, and Apple GPU power/temperature would need root powermetrics, so they show as n/a. If no GPU source is present, the GPU section reports unavailable while everything else keeps working.
┌───────────────────────────── Tauri window ─────────────────────────────┐
│ React 19 + TypeScript + Zustand + xterm.js │
│ invoke() ──────────────► Tauri commands (Rust) │
│ listen() ◄────────────── terminal-output · remote-telemetry · │
│ sftp-progress · terminal-closed │
├────────────────────────────────────────────────────────────────────────┤
│ Rust backend (ssh2 / libssh2) │
│ • Terminal – PTY shell, dedicated connection per session │
│ • Telemetry – own connection, auto-reconnect with backoff │
│ • SFTP ops – pooled per-session "operations" connection │
│ • Bulk transfer – dedicated connection per file, cancellable │
└────────────────────────────────────────────────────────────────────────┘
Long-running work is isolated: blocking SSH I/O runs on spawn_blocking threads so the UI never freezes, and each concern (shell / telemetry / transfers) fails independently.
Data locations (%APPDATA%\GpuTerm on Windows, ~/Library/Application Support/GpuTerm on macOS, ~/.config/GpuTerm on Linux):
| File | Contents |
|---|---|
sessions.json |
Session profiles — host, port, username, key path only |
known_hosts.json |
Approved SHA-256 host key fingerprints |
app_settings.json |
UI preferences such as the last local SFTP directory |
Passwords and private key contents are never written to any of these files.
npm run test # frontend tests (Vitest)
cargo test --manifest-path src-tauri/Cargo.toml # backend tests
npm run build # TypeScript + Vite production buildProject layout
src/ React frontend
components/ TerminalPane, SftpBrowser, RemoteTelemetryBar, popovers…
stores/ Zustand stores (session, transfers)
utils/ Shared formatters, terminal buffer, disk priority
src-tauri/src/ssh/ Rust backend
terminal.rs PTY shell + UTF-8 safe reader
system_monitor.rs Telemetry loop + parsers
resource_details.rs On-demand CPU/RAM/GPU detail collection
sftp.rs Transfers, cancellation, SFTP commands
session.rs Connections, host keys, profiles, connection pool
| Symptom | Check |
|---|---|
tauri:dev fails on Windows |
VS Build Tools 2022 (C++ workload) + WebView2 Runtime installed, then restart the terminal |
cargo not found |
Install via rustup, reopen the terminal (%USERPROFILE%\.cargo\bin on PATH) |
| SSH auth fails | Verify host/port/user/credentials; confirm the server allows the auth method |
| Host key mismatch | Verify the server fingerprint out-of-band, then remove the stale entry from known_hosts.json |
| GPU shows unavailable | Confirm a GPU tool is installed (nvidia-smi, rocm-smi, xpu-smi, or intel_gpu_top); other metrics still work regardless |
- Keyboard-interactive SSH authentication is not implemented
- Recursive directory upload/download and transfer resume are not implemented
known_hosts.jsonuses SHA-256 fingerprints, not the OpenSSH known_hosts format- Telemetry supports Linux, macOS (Apple Silicon included), and Windows remotes; Apple GPU power/temperature and per-core CPU usage need root
powermetricsand are not shown - GPU monitoring uses
nvidia-smi,rocm-smi,xpu-smi,intel_gpu_top, macOSioreg, or Windows WDDM performance counters (AMD support on Linux currently targetsrocm-smi) - Windows remotes: requires Windows PowerShell 5.1+ (preinstalled); load averages don't exist and show as n/a; AMD/Intel GPUs report utilization and dedicated VRAM only (no power/temperature, needs Windows 10 1709+ with a WDDM 2.x driver); process owners and GPU process command lines need elevation and fall back to n/a / process names;
quseris missing on Home editions, so the Users section stays empty there; hybrid iGPU+dGPU hosts show both cards (counters are attributed by adapter LUID from the DirectX registry, falling back to a positional heuristic if that key is unavailable)
Issues and pull requests are welcome — please run the test suites above before submitting.
MIT © GpuTerm contributors. Built with Tauri, React, xterm.js, and ssh2; third-party licenses remain with their authors.