Skip to content

Configuring VS Code and Cursor

This also applies to Cursor

Cursor is a fork of VS Code and uses the same Remote-SSH mechanism, so the same configuration described on this page applies to it as well.

This documentation is only useful if you plan to use VS Code to edit files stored in the cluster file system remotely. You should also check the docs in Remote Editing and specially the specific section related to how to configure the VS Code SSH plugin

Read this page before connecting VS Code to the cluster

Using VS Code is only allowed in the dedicated login node vscode.scicore.unibas.ch

The login nodes are a shared resource. Your home directory lives on a network filesystem (NFS) that is shared by every user on the cluster.

With its default settings, the VS Code Remote-SSH extension generates a very large amount of filesystem traffic against that NFS share: it installs ~300 MB of runtime into your home directory, continuously watches and re-scans your files, and indexes every Python environment it can find.

When dozens of users do this at once, the shared filesystem saturates and everybody’s login node becomes slow — including yours.

The settings on this page are mandatory. They take about five minutes to apply and will make the VS Code sessions noticeably faster for you and for every other user working in the same login node.

If you have already used VS Code before in the cluster, it’s recommended that you follow these steps before continuing with this documentation:

  • Close VS Code on your computer
  • Terminate all your running vscode processes on vscode.scicore.unibas.ch with
pkill -u $USER -9 -f .vscode-server
pkill -u $USER -9 -f .cursor-server
  • Delete your current config from the cluster filesystem executing rm -fr ~/.vscode-server/ and rm -fr ~/.cursor-server/ in any login node

Why VS Code is a problem in the cluster

VS Code’s remote development model is designed for a machine with a local/fast disk, not for a shared login node with a network home directory. Three things go wrong:

What VS Code does Why it hurts here
Installs ~/.vscode-server (node runtime, extensions, logs, state databases, IPC sockets) into $HOME Every one of those reads and writes crosses the network to the NFS server
Watches your workspace for file changes inotify does not work over NFS, so the watcher silently falls back to polling — repeatedly stat-ing thousands of files
Indexes your Python environments (Pylance, Jupyter) A single conda environment is ~100 000 small files. Indexing it over NFS is brutal

Multiply that by every concurrent VS Code user and the result is the slow ls, slow cd and slow logins that you have probably already noticed.


Step 1 — Move the VS Code server off NFS

This is the single most important change on this page. By default VS Code installs its server into ~/.vscode-server, which is on NFS. We want it on the login node’s local disk instead.

On your own machine (not the cluster), open the VS Code Settings JSON:

  • Press f1 (or ctrl+shift+p (Windows) / cmd+shift+p (Mac))
  • Run Preferences: Open User Settings (JSON)

Add the following, replacing USERNAME with your cluster username:

settings.json (on your local machine)
{
    "remote.SSH.serverInstallPath": {
        "vscode.scicore.unibas.ch": "/scratch/vscode/USERNAME"
    },
    "remote.SSH.connectTimeout": 120
}

Adjust the host name vscode.scicore.unibas.ch if needed

The key pointing to “/scratch/vscode/USERNAME” (“vscode.scicore.unibas.ch” above) must match exactly the Host alias you use in your ~/.ssh/config to connect to the cluster. If you customized the host alias of “vscode.scicore.unibas.ch” to be hpc, for example, then the configuration line above should change to "hpc": "/scratch/vscode/USERNAME", replacing USERNAME with your cluster username.

Then, once, SSH to the vscode login node from your terminal and create the following directory on the scratch folder:

# Local machine terminal
ssh USERNAME0000@vscode.scicore.unibas.ch
# VS Code login node
mkdir -p /scratch/vscode/$USER
chmod 700 /scratch/vscode/$USER
ln -s /scratch/vscode/$USER/.vscode-server ~/.vscode-server
ln -s /scratch/vscode/$USER/.cursor-server ~/.cursor-server

Local disk is not backed up and not shared

/scratch is per node and may be purged at any time. Never put anything you care about there. VS Code will simply reinstall its server if the directory disappears.


Step 2 — Tame the file watcher and the indexers

Still on your local machine, in the same settings.json, add:

settings.json (on your local machine)
{
    "files.watcherExclude": {
        "**/.git/objects/**": true,
        "**/.git/subtree-cache/**": true,
        "**/node_modules/**": true,
        "**/.conda/**": true,
        "**/conda/**": true,
        "**/miniconda3/**": true,
        "**/venv/**": true,
        "**/.venv/**": true,
        "**/site-packages/**": true,
        "**/__pycache__/**": true,
        "**/.mypy_cache/**": true,
        "**/.pytest_cache/**": true,
        "**/data/**": true,
        "**/results/**": true
    },
    "search.followSymlinks": false,
    "search.exclude": {
        "**/node_modules": true,
        "**/site-packages": true,
        "**/data": true,
        "**/results": true
    },
    "python.analysis.indexing": false,
    "python.analysis.userFileIndexingLimit": 0,
    "python.analysis.autoSearchPaths": false,
    "git.autofetch": false,
    "git.autorefresh": false,
    "telemetry.telemetryLevel": "off",
    "extensions.autoUpdate": "off",
    "extensions.autoCheckUpdates": false
}

What each group does:

  • files.watcherExclude — stops VS Code polling directories that never change in ways you care about. Add your own large data directories.
  • search.followSymlinks: false — prevents a full-text search from wandering out of your project and across the whole filesystem via a symlink.
  • python.analysis.* — stops Pylance from walking every Python environment on the system. You keep syntax checking and completion for files you actually open; you lose “go to definition” into third-party libraries you have not opened.
  • git.autofetch / git.autorefresh — stops a git status (and possibly a network fetch) firing every few seconds against a repository on NFS.
  • extensions.autoUpdate — stops extensions being silently re-downloaded and re-unpacked into your home directory in the background.

Step 3 — Keep your workspace small

Open the project, not your home directory

Never do File → Open Folder on /home/USERNAME.

VS Code will try to watch and index everything you own. Open the specific project directory you are working on: ~/projects/my-analysis, not ~.

Other habits that help a lot:

  • Close the remote window when you stop working. A forgotten VS Code window keeps polling all night. Use File → Close Remote Connection, don’t just close your laptop lid.
  • Don’t open more remote windows than you need. Each one starts its own set of extension host processes.
  • Keep large datasets out of the workspace tree, or add them to files.watcherExclude as shown above.

I don’t want these settings on my local projects

The configuration in Step 2 is written into your User Settings, so it applies to every VS Code window you open — local ones included. If you also use VS Code for work that is unrelated to the cluster, you may not want git.autofetch disabled or Pylance indexing turned off everywhere.

Two supported ways to scope the settings to your cluster work only. Both work; pick whichever fits your habits.

remote.SSH.* always stays in local User Settings

remote.SSH.serverInstallPath and remote.SSH.connectTimeout are read by your local VS Code before the connection is made, so they cannot live on the server. They are already host-scoped (serverInstallPath is keyed by host name), so leaving them in User Settings is harmless.

Option A — A dedicated “scicore” profile

A profile is a named bundle of settings, extensions and UI state. Settings put in a profile only apply to windows using that profile.

  1. File → Preferences → Profiles → Create Profile…
  2. Name it scicore. Choose Empty Profile, or copy from your current one.
  3. With the scicore profile active, run Preferences: Open User Settings (JSON) and paste the Step 2 block there.
  4. Connect to vscode.scicore.unibas.ch. In that remote window, select the profile via File → Preferences → Profiles → scicore.

VS Code remembers the profile per folder/workspace, so the next time you open that same remote folder it comes back with the scicore profile already applied. Your other projects keep your normal settings.

Extensions too

A profile also controls which extensions are enabled. An empty scicore profile with only Python + Jupyter installed means fewer extension hosts running on the login node — which is exactly what we want.

Option B — Put the settings on the server

Settings can also live on the cluster side, next to the code they apply to.

Per project — create .vscode/settings.json inside the project directory on the cluster. This is the best place for the excludes that are really properties of the project (**/data/**, **/results/**):

~/projects/my-analysis/.vscode/settings.json (on the cluster)
{
    "files.watcherExclude": {
        "**/.git/objects/**": true,
        "**/node_modules/**": true,
        "**/.conda/**": true,
        "**/venv/**": true,
        "**/.venv/**": true,
        "**/site-packages/**": true,
        "**/__pycache__/**": true,
        "**/.mypy_cache/**": true,
        "**/.pytest_cache/**": true,
        "**/data/**": true,
        "**/results/**": true
    },
    "search.followSymlinks": false,
    "search.exclude": {
        "**/site-packages": true,
        "**/data": true,
        "**/results": true
    },
    "python.analysis.indexing": false,
    "python.analysis.userFileIndexingLimit": 0,
    "python.analysis.autoSearchPaths": false,
    "git.autofetch": false,
    "git.autorefresh": false
}

You have to repeat this in every project — but you can commit it to the repository, which means your collaborators get it for free.

For every project on the cluster at once — use the machine settings file, which applies to all windows connected to that host. From a VS Code terminal on the login node, run Preferences: Open Remote Settings (SSH: vscode.scicore.unibas.ch), or write the file directly:

mkdir -p /scratch/vscode/$USER/data/Machine
$EDITOR /scratch/vscode/$USER/data/Machine/settings.json

Paste the same JSON block as above.

Machine settings live on /scratch and can be purged

If you followed Step 1, the machine settings file sits under /scratch/vscode/$USER/data/Machine/, which is not backed up and is wiped when the node is cleaned. Keep a copy somewhere safe and re-push it after a server reinstall:

ssh vscode.scicore.unibas.ch \
    'mkdir -p /scratch/vscode/$USER/data/Machine && cat > /scratch/vscode/$USER/data/Machine/settings.json' \
    < scicore-machine-settings.json

Caveat: settings that cannot be scoped by machine, project or profile

telemetry.telemetryLevel, extensions.autoUpdate and extensions.autoCheckUpdates are application-scoped and can only be set in the settings file from the Default profile. They are ignored in project and machine settings files (VS Code greys them out). Set them in your local User Settings, as neither Option A nor Option B can override them.


What happens if I ignore this

We monitor per-user I/O and CPU on the login nodes. Sessions that generate sustained, excessive load will be throttled automatically, and repeat offenders will have their processes terminated without warning. This is not a punishment — a single misconfigured VS Code session can measurably degrade the login node for dozens of other people.

If you get throttled, work through this page and reconnect.


Complete reference configuration

For convenience, here is everything from steps 1 and 2 in a single block. Merge it into your local User Settings (JSON) and change USERNAME and the host name. If you would rather not have these settings apply to your local projects, see I don’t want these settings on my local projects.

settings.json (on your local machine)
{
    "remote.SSH.serverInstallPath": {
        "vscode.scicore.unibas.ch": "/scratch/vscode/USERNAME"
    },
    "remote.SSH.connectTimeout": 120,
    "files.watcherExclude": {
        "**/.git/objects/**": true,
        "**/.git/subtree-cache/**": true,
        "**/node_modules/**": true,
        "**/.conda/**": true,
        "**/conda/**": true,
        "**/miniconda3/**": true,
        "**/venv/**": true,
        "**/.venv/**": true,
        "**/site-packages/**": true,
        "**/__pycache__/**": true,
        "**/.mypy_cache/**": true,
        "**/.pytest_cache/**": true,
        "**/data/**": true,
        "**/results/**": true
    },
    "search.followSymlinks": false,
    "search.exclude": {
        "**/node_modules": true,
        "**/site-packages": true,
        "**/data": true,
        "**/results": true
    },
    "python.analysis.indexing": false,
    "python.analysis.userFileIndexingLimit": 0,
    "python.analysis.autoSearchPaths": false,
    "git.autofetch": false,
    "git.autorefresh": false,
    "telemetry.telemetryLevel": "off",
    "extensions.autoUpdate": false,
    "extensions.autoCheckUpdates": false
}

Troubleshooting

How do I check it worked?

After reconnecting, run this in the VS Code terminal:

[ "$(readlink ~/.vscode-server)" = "/scratch/vscode/$USER/.vscode-server" ] && echo ok || echo wrong - this should be a symlink
ls -d /scratch/vscode/$USER/.vscode-server && echo "OK - on local disk"
[ "$(readlink ~/.cursor-server)" = "/scratch/vscode/$USER/.cursor-server" ] && echo ok || echo wrong - this should be a symlink
ls -d /scratch/vscode/$USER/.cursor-server && echo "OK - on local disk"

If ~/.vscode-server or ~/.cursor-server still exists from a previous session, delete it and create a symlink:

rm -rf ~/.vscode-server
rm -rf ~/.cursor-server
ln -s /scratch/vscode/$USER/.vscode-server ~/.vscode-server
ln -s /scratch/vscode/$USER/.cursor-server ~/.cursor-server

This may take several minutes — it contains tens of thousands of files, which is precisely the point.

Connection hangs at Checking .log and .pid for a running server

This is the classic symptom of .vscode-server sitting on NFS: the lock check blocks on the network filesystem and never returns. Apply Step 1, then remove the old directory:

rm -rf ~/.vscode-server
Connection worked yesterday and now fails

Stale server state, often after a node reboot cleared /scratch, or after a VS Code update. Remove the server directory and reconnect:

rm -rf /scratch/vscode/$USER/.vscode-server
Unable to watch for file changes in this large workspace (ENOSPC)

You have opened too large a folder. Open a narrower directory (Step 3) and check your files.watcherExclude covers your data directories.

Note that files.watcherExclude is known not to apply reliably to paths outside your workspace — the real fix is to not open those paths.

I disabled indexing and lost go to definition in libraries

That is the trade-off. If you need it for a specific project, re-enable it in that project’s .vscode/settings.json only — never globally:

.vscode/settings.json (in the project, on the cluster)
{ "python.analysis.indexing": true }

Please turn it off again when you are done.

My settings are not being applied in the remote window

Check which layer is winning. Run Preferences: Open Settings (UI), search for the setting, and look at the tab bar (User / Remote / Workspace) — the active tab shows where the effective value comes from. More specific layers override less specific ones:

User < Remote (Machine) < Workspace < Folder

If you are using a profile (Option A), also confirm the right profile is active for the window: the profile name is shown in the bottom-left gear menu.