# Welcome to Nuvolos

Nuvolos is a cloud platform that brings computation, data management, and collaboration together in a single browser-based environment. Everything runs in containerized [*Applications*](/concepts/applications) inside your own [*Instance*](/concepts/nuvolos-basic-concepts/organisational-hierarchy#instances), so there is nothing to install locally.

<div data-full-width="false"><figure><img src="/files/MPn3ixq2vY7riqris2nU" alt=""><figcaption></figcaption></figure></div>

### Core Capabilities at a Glance

Nuvolos is designed to support the full lifecycle of scientific and educational work:

<table data-header-hidden><thead><tr><th width="247"></th><th></th></tr></thead><tbody><tr><td><strong>Capability</strong></td><td><strong>Description</strong></td></tr><tr><td>Run <em>Applications</em></td><td>Launch RStudio, JupyterLab, MATLAB, VS Code, and more. Scale resources from single CPU to dedicated GPU nodes.</td></tr><tr><td>Manage Data</td><td>Store files on the <em>High-performance File System</em>, a dedicated <em>Large File Storage</em>, query the <em>Scientific Data Warehouse</em>, or attach add-on databases.</td></tr><tr><td>Version Your Work</td><td>Take <em>Snapshots</em> to create immutable, point-in-time records of files, tables, and configurations.</td></tr><tr><td>Distribute &#x26; Collaborate</td><td><em>Distribute</em> materials in one step. Work in parallel <em>Instances</em> and merge results when ready.</td></tr><tr><td>Automate Workflows</td><td>Use the CLI and Python API to script <em>Application</em> runs and build reproducible pipelines.</td></tr><tr><td>Control Costs</td><td>Track usage through resource pools, right-size applications, and use "resting" states to optimize spend.</td></tr></tbody></table>

### How to Use Our Documentation

To help you find exactly what you need, our content is organized into four modes:

* [Tutorials](/tutorials/tutorials-for-instructors): Learning-oriented guides that take you from zero to a meaningful result. Use these if you are a newcomer wanting to build confidence.
* [How-to Guides](/how-to-guides/common-workflows): Task-oriented instructions that answer "How do I do X?". Use these if you already know what you want to achieve.
* [Reference](/reference/applications): Information-oriented, technical descriptions. Use these when you need precise answers about APIs, commands, or specifications.
* [Concepts](/concepts/nuvolos-basic-concepts): Understanding-oriented discussions of design decisions and system relationships. Use these when you want to know "why" something works the way it does.

### Support and Administration

Beyond the core learning paths, we provide specialized sections for specific needs:

* [Troubleshooting](/troubleshooting/troubleshooting): Designed for "interrupt-driven" needs when you are stuck and need to get back to work fast. This covers login issues, application errors, and content problems.
* [Administration](/administration/user-account-management) & [Billing](/billing/pricing-structure): A dedicated area for PIs, IT staff, and Instructors. Here you can manage *Organization* settings, monitor NCU (*Nuvolos Compute Unit*) usage, and handle subscriptions.

#### Where to go next

* For tutorials and how-to guides tailored to your role, see [Getting Started › Choose your role](/getting-started/choose-your-role).
* If you would rather get oriented in the interface first, see [Getting Started › Find your way around](/getting-started/find-your-way-around) for a short tour of the Dashboard, breadcrumbs, sidebar, and Account & Settings menu.
* If a term on this page (*Space*, *Instance*, *NCU*, *Snapshot*, *Distribution*) is unfamiliar, see [Getting Started › Glossary](/getting-started/glossary).


# Choose your role

Nuvolos is designed for three primary audiences. Pick the path that matches your role to find your specific tutorials and how-to guides:

### 🎓 Instructors

Set up courses, distribute materials, manage assignments, and invite students.

* Tutorials
  * [Your first course on Nuvolos](/tutorials/tutorials-for-instructors/your-first-course-on-nuvolos)
  * [Running a data-heavy lab session](/tutorials/tutorials-for-instructors/running-a-data-heavy-lab-session)
  * [Reusing a course for the next term](/tutorials/tutorials-for-instructors/reusing-a-course-for-the-next-term)
* Guides
  * [Join an organisation](/how-to-guides/workflows-for-instructors/join-an-organisation) - accept an organisation-level invitation as Faculty or Manager so you can create your own courses.
  * [Create a new course](/how-to-guides/workflows-for-instructors/create-a-new-course) - set up a new course *Space* with name, description, and a starter *Application*.
  * [Add teaching material](/how-to-guides/workflows-for-instructors/add-teaching-material) - upload files into the *Master Instance* where you develop course content.
  * [Structure your course](/how-to-guides/workflows-for-instructors/best-practice-structuring-your-course) - choose the *Instance* layout that matches how students will work.
  * [Document your course](/how-to-guides/workflows-for-instructors/documenting-your-course) - use `README.md` files and embedded videos to introduce the course on its overview page.
  * [Invite students](/how-to-guides/workflows-for-instructors/invite-students) - send invitations so each student receives their own individual *Instance*.
  * [Invite teaching assistants and co-instructors](/how-to-guides/workflows-for-instructors/invite-tas) - invite colleagues as *Space Administrators* with full course management rights.
  * [Distribute teaching material](/how-to-guides/workflows-for-instructors/distribute-to-prospective-students) - push files, tables, or *Applications* from the *Master Instance* to every student.
  * [Set up group projects](/how-to-guides/workflows-for-instructors/setting-up-group-projects) - create per-group *Instances* in a separate group-work *Space*.
  * [Configure course tools and resources](/how-to-guides/workflows-for-instructors/configuring-student-applications) - manage *Applications* and resources for the entire cohort.
  * [GPU courses](/how-to-guides/workflows-for-instructors/courses-with-gpus) - enable GPU access, schedule lab sessions, or set up On-Demand GPU with *Credit* quotas.
  * [Assignments, grading, and feedback](/how-to-guides/workflows-for-instructors/setting-assignments) - create, distribute, grade, and hand back *Assignments*.
  * [Archiving your course](/how-to-guides/workflows-for-instructors/archiving-your-course) - manage the course archival lifecycle and access student work after archival.

### 📖 Students

Join a course, start *Applications*, and use *Snapshots* to save your work.

* Tutorials
  * [Your first Nuvolos session](/tutorials/tutorials-for-students/your-first-day-in-a-nuvolos-course)
  * [Submitting your first assignment](/tutorials/tutorials-for-students/submitting-your-first-assignment)
  * [Working on a group project](/tutorials/tutorials-for-students/working-on-a-group-project)
* Guides
  * [Accept a course invitation](/how-to-guides/workflows-for-students/join-a-course) - join a course by accepting the invitation email from your instructor.
  * [Find your course materials](/how-to-guides/workflows-for-students/find-your-course-materials) - locate the files, datasets, and *Applications* your instructor has distributed to you.
  * [Understand the course layout](/how-to-guides/workflows-for-students/understand-the-course-layout) - learn the difference between your personal *Instance* and the *Distributed Instance*.
  * [Use applications](/how-to-guides/workflows-for-students/start-an-application) - start and stop *Applications* like JupyterLab, RStudio, or VS Code.
  * [Work with files](/how-to-guides/workflows-for-students/work-with-files) - upload, download, edit, and organise files in your *Instance*.
  * [Complete and submit assignments](/how-to-guides/workflows-for-students/working-on-assignments) - work on *Assignments*, hand them in, and review instructor feedback.
  * [Save and recover work](/how-to-guides/workflows-for-students/snapshot-your-work) - take snapshots before major changes and restore previous states when needed.
  * [Collaborate and use special resources](/how-to-guides/workflows-for-students/working-with-a-gpu-in-a-course) - work in shared group *Instances* and use GPU access in your course.
  * [Working with archived courses](/how-to-guides/workflows-for-students/working-with-archived-courses) - access your work after a course is archived and restore from snapshots.
  * [Leaving a course](/how-to-guides/workflows-for-students/leaving-a-course) - remove yourself from a course while preserving your *Instance* and work.

### 🔬 Researchers

Create projects, manage data, run Applications, and collaborate with colleagues.

* Tutorials
  * [Your first research project](/tutorials/tutorials-for-researchers/your-first-research-project)
  * [From notebook to reproducible result](/tutorials/tutorials-for-researchers/from-notebook-to-reproducible-result)
  * [Reproducing a colleague's research project](/tutorials/tutorials-for-researchers/reproducing-a-colleagues-research-project)
* Guides
  * [Join an organization](/how-to-guides/workflows-for-researchers/join-an-organization) - accept an organisation-level invitation as Faculty or Manager so you can create your own projects.
  * [Create a research project](/how-to-guides/workflows-for-researchers/add-a-new-research-project) - set up a new research *Space* with the right visibility for your work.
  * [Join a research project](/how-to-guides/workflows-for-researchers/join-a-research-project) - accept an invitation to an existing project as *Space Administrator* or *Instance Editor*.
  * [Add material to the project](/how-to-guides/workflows-for-researchers/add-material-to-the-project) - bring files, code, and data into your project from local uploads, Git, or external storage.
  * [Create alternate approaches](/how-to-guides/workflows-for-researchers/create-alternate-approaches) - branch off into new *Instances* for parallel experimentation.
  * [Invite collaborators](/how-to-guides/workflows-for-researchers/invite-collaborators) - invite co-authors as *Space Administrators* or single-*Instance* contributors as *Instance Editors*.
  * [Invite an external reviewer](/how-to-guides/workflows-for-researchers/inviting-a-reviewer) - give a journal editor or reviewer an isolated copy of your work to inspect.
  * [Run analyses and applications](/how-to-guides/workflows-for-researchers/work-with-applications) - create, start, and stop *Applications* for your research.
  * [Set up a dataset](/how-to-guides/workflows-for-researchers/setting-up-a-dataset-on-nuvolos) - publish curated, vintaged data to a *Dataset Space*.
  * [Import data](/how-to-guides/workflows-for-researchers/importing-data-on-nuvolos) - bring external data into Nuvolos via uploads, downloads, mounts, or data pipelines.
  * [Database research workflow - Matlab & RStudio](/how-to-guides/workflows-for-researchers/a-complete-database-research-workflow-matlab-and-rstudio) - query the *Scientific Data Warehouse*, analyse in Matlab or RStudio, and write results back.
  * [GPU Computation](/how-to-guides/workflows-for-researchers/gpu-computation) - configure GPU sizes and install libraries for PyTorch, TensorFlow, or XGBoost.
  * [Scale and automate](/how-to-guides/workflows-for-researchers/scale-and-automate) - scale to HPC and automate workflows with the CLI or Python API.
  * [Preserve and share results](/how-to-guides/workflows-for-researchers/when-you-are-done-exporting) - export your project as a portable image and share snapshots with collaborators.


# Find your way around

Nuvolos mirrors the way computational research and teaching projects are organised: Organisations maintain projects, projects consists of various stages of workflows organised in working environments, and working environments consist of files, data, and software applications.&#x20;

The interface follows that same shape. Nuvolos consists of projects (*Spaces*), organised into *Organisations*, and projects contain working environments (*Instances*), which further have various *States*, containing files, data and applications.

Once you know the four navigation elements below, you can reach anything in the platform within a few clicks.

This page is a quick tour. For the conceptual model behind the hierarchy, see [The hierarchy and resource model](/concepts/nuvolos-basic-concepts/organisational-hierarchy). For the role-based view of what you can see and do at each level, see [Roles and permissions](/concepts/roles-secrets-and-identity/roles).

## The four navigation elements

Nuvolos provides four ways to move through the platform. You will use all of them, often in combination.

* **The Dashboard** - your starting point after logging in.
* **The breadcrumbs bar** - your position in the hierarchy
* **The sidebar** - actions available in the selected context. You can also change the context using the sidebar.
* **The Account & Settings menu** - your profile, secrets, API keys, and resource monitoring.

{% hint style="info" %}
The **breadcrumbs** have changed on 2026-07-08 - navigation is possible via the sidebar now.
{% endhint %}

### The Dashboard

The Dashboard is your starting point after logging in. It shows your recent activity and quick-access cards for your most-used Applications, in the context of the most recent *Organisation* you worked in.

You can return to the Dashboard at any time by clicking the **Nuvolos logo** in the top left corner.

### The breadcrumbs bar

The breadcrumbs bar at the top of the screen shows your current position in the hierarchy. When viewing an Instance, the breadcrumbs show **Organisation → Space → Instance → State**.

### **The sidebar**

The sidebar is a constant no matter where you are on Nuvolos. It always shows available actions on the **current context level** you are on in Nuvolos and also lets you navigate between contexts (such as switching a space, organisation or instance).

## **Finding what you need**

Most navigation in Nuvolos is a matter of selecting the right level in the sidebar. The patterns below cover the common cases.

### **Finding an Organisation**

You can only see *Organisations* for which you have accepted a valid invitation.

To find an *Organisation*, navigate first to the dashboard. Click the name of the currently selected organisation, and a filterable menu will appear with all possible choices. Scroll the list, or use the search field to filter. If you cannot find an expected *Organisation*, confirm that you have accepted the invitation email - see [Accepting an invitation](/how-to-guides/common-workflows/accepting-an-invitation).

### **Finding a Space**

You can only see *Spaces* where you have access to at least one Instance or you are a Space Administrator.

To find a *Space*:

* Make sure you are in the *Organisation* that contains the space.
* On the dashboard, in the *Recent spaces* menu, you can look at your latest projects, but also search and filter for others.
  * You can use the **Filters icon** next to the search bar at the top to filter by **Courses**, **Projects**, or **Datasets**.
* To see archived courses or resting projects/datasets, enable the **Archived** or **Resting** toggle. These Spaces appear with greyed-out text and are hidden by default.

When you select a *Space*, Nuvolos automatically opens an *Instance* for you: if you have access to the Master Instance it opens that, otherwise it opens the first Instance you have editor access to.

### **Finding an Instance**

You can only see Instances where you are an *Editor* or *Viewer, or* you can see all Instances if you are a *Space Administrator*.

To find an Instance:

* Navigate to the *Organisation* and *Space* in the sidebar or via the dashboard.
* In the context of a Space, click the current Instance name to bring out the context switching menu, notified by the `>` icon appearing on hover.
* Filter by name or click **View all instances** to see the full list.

### **Finding a State (Snapshot or current state)**

*States* represent points in time status within an Instance. The *Current State* is the live working version; *Snapshots* are immutable copies.

To find a state:

* Make sure you are in the desired context by navigating to an instance via the sidebar.
* In the context of an Instance, click the current Snapshot name to bring out the context switching menu, notified by the `>` icon appearing on hover.
* Click **View all snapshots** to open the full snapshot timeline view.

### **Finding an Application**

There are three ways to find an *Application*, depending on what you remember about it.

* **If you have used it recently**, the Dashboard shows your three most recent *Applications*.
* **If it is currently running**, click the desktop monitor icon in the top toolbar.
* **For the full list in an instance**, open the *Space and Instance* and click the *Applications* icon in the sidebar.

## **The Account & Settings menu**

The **Account & Settings** menu in the bottom left corner is your control panel for everything that is yours rather than belongs to a particular Nuvolos object. It contains:

* **Account Settings** - profile, environment variables, secrets, SSH keys, API access, Dropbox sync, table access, and Nuvolos Settings (date/time formatting, AI integrations).
* **Resources** - the resource monitoring dashboard, where you can track NCU consumption, storage usage, and Credit balance for the resource pools you have access to.

### Tasks

**Tasks and notifications** are available for review on the bell icon in the top right corner. The menu shows running and recent background tasks (for example, distributions, archive extractions) and pending role requests.


# Glossary

### Application

A containerised software tool - for example, JupyterLab, RStudio, VS Code, MATLAB, or Stata - that runs within a Nuvolos Instance. Applications include their full dependencies and can be distributed, snapshotted, and scaled. Most Applications can be customized by installing additional dependencies. See [Concepts › How Applications work](/concepts/applications).

### Application library files

One of the three persistent storage locations accessible in a Nuvolos Application.&#x20;

Shared across all users for a given Application in a given Instance. Used to store Application packages, libraries, and shared configuration. Alternatively referred to as the LIBRARY area. See [Reference › File storage](/reference/file-system-and-storage).

### Credit

A unit of measure for additional on-demand resources and professional services beyond those provided within the Nuvolos subscription itself. Credits can be purchased at any time provided you have a Nuvolos subscription. See [Billing › Subscription and Credits](/billing/pricing-structure).

### Distribution

In this documentation, distribution refers to the dedicated functionality in Nuvolos for sharing Nuvolos artefacts - code, data, files, Applications, and so forth.&#x20;

Distribution is a push operation: objects are first staged, then send them to other Instances, Spaces, or organisations. See [How distribution works](/concepts/distribution#distribution-the-push-mechanism) for a conceptual intro, or [How-to › Common Workflows › Distribution](/how-to-guides/common-workflows/object-distribution) for procedures.

### Distributed Instance

A special Instance that exists in every course Space alongside the Master Instance. It serves as the shared destination for content distributed at the Space level, making shared files, Applications, and other objects available to all members of the Space. The Distributed Instance is only relevant in teaching workflows - research and dataset Spaces do not have one.

### GPU computing

GPU stands for Graphics Processing Unit. In essence, it is the separate processor controlling and coordinating image processing. Because they rely on parallel operations, GPUs can be better than regular processors at certain high-end algorithmic tasks involving stream processing of large amounts of data. Nuvolos supports the use of state-of-the-art general purpose GPU computing for this purpose as an additional service purchasable with credits.&#x20;

### HPC (High Performance Computing)

The use of high-end computer clusters to solve complex computational challenges. Nuvolos supports interactive HPC use cases through credit-based Application sizes that allocate exclusive CPU, RAM, and GPU resources. HPC usage is paid for with Credits. See [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

### Identity provider

An identity provider (IdP) is a service that verifies online identities for 3rd party applications. For example, among many other things, Google is an identity provider - you can access many different websites not operated by Google only by logging in to your Google account. Many institutions, companies and universities also run their own IdP services for validating user identity.

Nuvolos is integrated with support for the following identity providers:

* Nuvolos (an IdP managed by Nuvolos)
* Google
* Institutions in the [eduGAIN ](https://edugain.org/)network

When you sign up to Nuvolos, you identify yourself via one of the above IdPs. For any subsequent login, you must use the same IdP to access your Nuvolos account.

### Included size

An Application size that runs on shared infrastructure and consumes Nuvolos Compute Units (NCUs) from your subscription. Self-service scaling is possible between 1 and 16 NCUs. Contrasted with Credit-based size. See [Reference › Applications](/reference/applications).

### Instance

A working environment within a Space, holding files, data, and Applications. Instances act as branches of a project, allowing experimentation with different data sources, Application configurations, or collaborators. Each Space has a Master Instance; course Spaces also have a Distributed Instance. See [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

### Large File Storage (LFS)

A persistent storage option in Nuvolos for cost-efficient handling of data above 100 GB. LFS is suitable for large, static files that do not need to be snapshotted or distributed. Purchased separately with Credits and attached per Space. See [Reference › Storage and file access](/reference/data-storage).

### Master instance

A master instance is the main instance in a space. In a single-user setup, it is generally the primary working environment of the space and serves as the main place where workflows are created and managed.

### NCU (Nuvolos Compute Unit)

The unit of measurement for regular (non-HPC) Application runs, and the unit of account used to define the Nuvolos subscription. One NCU equals 1 vCPU and 4 GB of RAM. See [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

### Organisation

In Nuvolos, the organisation is the highest level of the [organisational hierarchy](/concepts/nuvolos-basic-concepts/organisational-hierarchy). It represents the basic organisational unit through which a user interacts with our product, and is primarily used for access control purposes. See [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

### Resource Pool

A cost-centre unit used to manage and track budgets for computational resources, storage, and services. Resource pools are mapped to organisations, Spaces, or specific resources, and all usage is accounted against the pool's budget. See [Billing › Resource pools and budgets](/billing/resource-pools-and-budgets).

### Resting

A feature that reduces storage costs by moving data you do not currently need to a more affordable storage class. When a Space is not actively used for a set period, its data transitions from the high-performance Nuvolos Filesystem to resting storage. Resting is configured at the organisation level. See [Administration › Space and Instance management](/administration/space-management).

### Scientific Data Warehouse (SDW)

The integrated data warehouse where tabular data is stored on Nuvolos. The SDW uses Snowflake as the underlying database engine and is accessible from inside Nuvolos Applications and from external Applications via ODBC. See [Concepts › Data storage](/concepts/data-integration).

### Snapshot

A complete, immutable, persistent, restorable, and shareable copy of the current state of an Instance. Captures files, database tables, Application data, settings, and dependencies as a single unit. See [Concepts › Snapshots](/concepts/distribution).

### Space

The intermediate level of the Nuvolos hierarchy. Each Space corresponds to a project - typically a course, research project, or dataset. Access control and budgeting can be applied at the Space level. See [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

### Staging

In the Nuvolos architecture, 'staging' refers to the temporary area where you assign objects for distribution. Each source has its own staging area, so to distribute from multiple sources to the same target, you must distribute multiple times.&#x20;

### State / Current state

A state is a version of an instance at a given point in time. The current state is the only mutable state of an instance and represents its active working version. Other states, such as snapshot states, are immutable and are used to preserve safe versions of the instance for versioning and restoration.

### Vintage

A point-in-time version of a dataset, created via the snapshot mechanism and stored in a dataset Space. Vintages allow analyses to reference the exact data that was available at a particular date, which is essential for replicability when underlying data is revised over time. See [Concepts › Data storage](/concepts/data-integration).


# Tutorials for Instructors

Nuvolos provides a flexible environment for instructors to deliver courses, manage assignments, and interact with students. A course in Nuvolos is an education-specific space with productivity feature.

#### Use Case: Standardizing the Classroom Experience

{% tabs %}
{% tab title="Problem" %}
**Managing diverse software environments across students**\
\
When teaching a technical or data-heavy course, instructors often lose class time acting as IT support. Students arrive with different operating systems, conflicting software versions, and varying hardware capabilities - leading to the "it works on my machine" problem, delayed assignments, and unequal access to course tools.
{% endtab %}

{% tab title="Solution" %}
**A unified platform with pre-configured environments**\
\
Instead of relying on student-managed local installations, instructors can build a single master workspace in Nuvolos. With a few clicks, that exact environment - complete with all necessary libraries, teaching materials, and licensed software - is distributed to every student's browser-based cloud workspace.
{% endtab %}

{% tab title="Result" %}
**Less overhead, consistent conditions for every student**\
\
By eliminating local troubleshooting and software accessibility barriers, instructors save hours of administrative overhead each term. Every student starts on a level playing field with a consistent, reliable setup - so the class can focus on the curriculum from day one rather than debugging environments.
{% endtab %}
{% endtabs %}

Nuvolos helps you solve the following challenges:

* **Environment consistency** - every student gets the exact same software environment, eliminating "it works on my machine" problems.
* **Software accessibility** - students access specialised or licensed software without installing anything locally.
* **Material distribution** - [distribute](/concepts/distribution) course materials, assignments, and updates to all students in one step.
* **Assignment management** - manage the full assignment lifecycle from creation and distribution to collection.
* **Reproducibility** - [snapshots](/concepts/distribution) track changes in course materials and student work, letting you revert to any previous version.
* **Scalable compute** - provide students with the [computational resources](/reference/applications/application-resources) they need, from simple scripts to complex simulations.


# Your first course on Nuvolos

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have joined your institution's Nuvolos organisation, created a course, added teaching material, invited a student, and seen their first submission come back to you.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 30-40 minutes, plus the time it takes for an invited student to act on your invitation.

<mark style="color:$primary;">**What you need before you start.**</mark> \
An invitation email from a Manager at your institution, with the Faculty or Manager role on a Nuvolos organisation. If you have not received one, ask your department head or IT contact - Nuvolos is invitation-only and you cannot create a course without organisation

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Accept your organisation invitation</mark>

Nuvolos is an invitation-only platform. As an instructor, you can be invited in two main ways: directly to an organisation (the path this tutorial assumes), or to a specific course as a co-instructor or TA (covered separately in the how-to guide on joining a course).

To create and manage your own courses you need to be invited to an organisation with the appropriate role. The roles available to you are:

* **Member** - typically for students. Does not allow you to create courses.
* **Faculty** - the standard role for instructors. Lets you create courses, enroll students, and manage course environments.
* **Manager** - has all Faculty permissions, and additionally can manage organisation settings and invite other Faculty members.

For a more detailed description of all roles, see [Roles and permissions](/concepts/roles-secrets-and-identity/roles) in the Concepts section.

For this tutorial, you need either Faculty or Manager. Open the invitation email from your institution and click Review Invitation. If you do not already have a Nuvolos account, complete the sign-up process; otherwise sign in. We recommend proceeding with the recommended option for your institution (for example, SWITCH for Swiss higher education institutions). Click Accept Invitation. The first sign-up may take up to a minute to complete.

{% hint style="success" %}
**Checkpoint**

You should now see your organisation's Dashboard. If you don't, refresh the page or sign out and sign in again. The Dashboard is where every course you create or co-teach will appear.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Create your first course</mark>

A course in Nuvolos is an education-specific space - a workspace where you add learning materials (data, code, applications) for your students. Each course you create gets its own space, separate from every other course.

From the Dashboard:

1. Select **+ SPACE**. And select **Course** from the dropdown.
2. On the next screen, enter a course name and description. You can also add a `README` file at this stage if you have one ready.
3. Select **ADD SPACE**.
4. (Optional) Select an application to add to the master instance of the new space - for example, a JupyterLab or RStudio image. You can always add applications later.
5. If you chose an application, enter a name for it and select **+ INSTALL**.

{% hint style="success" %}
**Checkpoint**

You should now be inside your new course, looking at the Master instance. The Master instance is the single place where you (and any TAs you invite later) develop and maintain teaching material - it is not visible to students by default. Everything you put here can later be distributed to every student in one step.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Add a piece of teaching material</mark>

Course material is anything that supports learning: lecture notes, datasets, source code, slide decks. You always work in the Master instance - a sandbox dedicated to developing teaching material. You can run apps, upload files, and develop material directly here.

Pick one small file to upload now - a lecture PDF, a starter notebook, or a CSV. You can add more later.

1. Confirm in the breadcrumbs that you are in your new course and on the Master instance.
2. On the left sidebar, click the Folder icon to open the Files view.
3. On the top left, click **UPLOAD** and choose your file.

If you want to add a folder, compress it locally, upload the archive, and decompress it from inside one of your applications. For more on file management, see the [File Navigator](/reference/file-system-and-storage/file-navigator) in Reference.

{% hint style="success" %}
**Checkpoint**

Your file should now appear in the Master instance's file list. This file is currently visible only to you - students will not see it until you distribute it (the next step does that automatically as part of inviting them).
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Invite a student</mark>

With teaching material in the Master instance, you are ready to invite a student. For this tutorial, invite yourself using a personal email address (or a colleague who is willing to act as a test student) so you can see the full loop close.

From inside the course:

1. Click the bottom left corner **Settings menu.**
2. Select **Users.**
3. Click **+ INVITE**.
4. The default option is User invitation with Invite to individual instances. Leave both selected - this gives each student a separate, private instance.
5. Choose how to send the invitation:

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Method</strong></td><td valign="top"><strong>When to use</strong></td></tr><tr><td valign="top">Invite link</td><td valign="top">Easiest option - share a link and anyone who clicks it joins the course.</td></tr><tr><td valign="top">Email</td><td valign="top">Better for smaller courses where you want to invite specific students.</td></tr></tbody></table>

For this tutorial use the Email method and enter your test address. Send the invitation.

Each invited student receives their own instance and cannot see the Master instance or other students' instances. Open the invitation email from your test address, click Review Invitation, sign up or sign in, and accept. You should now see the course as a student would - with the file you uploaded already present in your student instance, because joining a new course pulls in everything that has been distributed to it.

{% hint style="success" %}
**Checkpoint**

If your test student does not see your file, return to the Master instance, follow the distribute-to-prospective-students how-to guide once to push the file out, then re-check the student view. Tutorial 2 walks through distribution explicitly.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Create an assignment and watch it come back</mark>

An assignment is a special type of [distribution](/concepts/distribution) designed for coursework. When you create an assignment, you distribute material to students and additionally:

* Set a deadline by which students must submit their work (a hand-in).
* Create dedicated storage for student responses and instructor feedback.
* Generate an audit trail of all actions taken in response to the assignment.

From the Master instance, prepare a small assignment file (for example, a notebook with one question, or a text file asking the student to reply with one sentence), or folder. Upload it as you did in Step 3 if it is not there yet.

Then create the assignment using the procedure described in the how-to guide on creating an assignment. Set a deadline a few minutes in the future so you can complete the loop now.

Switch to your test student account, open the assignment, make a trivial change to the file, and submit. Switch back to your instructor account - you should see the submission appear in the assignment's hand-in storage, ready to review.

{% hint style="success" %}
**You're done**

You have created a course, added material, invited a student, distributed an assignment, and received a submission. Every later piece of work - adding a TA, structuring a more complex course, running graded assignments at scale - builds on these five steps. The how-to guides in Part B cover each piece in depth.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* If you want to bring in a colleague to help develop material, see [How-to › Invite teaching assistants and co-instructors](/how-to-guides/workflows-for-instructors/invite-tas).
* If your course has more than one application, dataset, or large set of materials, see [How-to › Structure your course](/how-to-guides/workflows-for-instructors/best-practice-structuring-your-course) for the recommended layout.
* To grade assignments and provide feedback, see [How-to › Assignments, grading, and feedback](/how-to-guides/workflows-for-instructors/setting-assignments).
* If you want to understand the model behind distribution, instances, and snapshots, see [Concepts](/concepts/nuvolos-basic-concepts).


# Running a data-heavy lab session

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have set up a course space with a configured application, prepared a dataset, distributed both to a cohort of students, and run through the workflow you would use during a live teaching session.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 45–60 minutes the first time, depending on the size of your application image and dataset.

<mark style="color:$primary;">**What you need before you start.**</mark> \
You should have completed [Your first course on Nuvolos](/tutorials/tutorials-for-instructors/your-first-course-on-nuvolos) tutorial - that is, you have an organisation membership, you have created at least one course, and you understand the role of the Master instance. You should also have a sample dataset on your local machine (a CSV is enough) and a clear idea of which application image (for example, JupyterLab with Python, RStudio, or a Stata image) you want students to use.

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Create a course space dedicated to the lab</mark>

If you reuse a course from [Your first course on Nuvolos](/tutorials/tutorials-for-instructors/your-first-course-on-nuvolos) tutorial , you may end up mixing tutorial leftovers with real lab material. For this tutorial, create a fresh course.

From the Dashboard, select + SPACE. Enter a name (for example, "Data Lab - pilot") and a description. Select ADD SPACE.

When the application picker appears, do not skip it - choose the application you want students to use during the lab. Enter a name for it and select + APPLICATION. Installing the application now means it is part of the Master instance from the start, ready to be distributed to every student.

{% hint style="info" %}
**Why this matters**

A data-heavy lab fails the moment one student is on Python 3.9 and the next on Python 3.11. Setting up the application centrally - once, in the Master instance - is the move that eliminates the "it works on my machine" problem entirely. Every student gets the exact same image.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Configure the application</mark>

Open the Master instance and start the application you just installed. Install or configure anything the lab needs: extra Python packages, R libraries, connection strings, environment variables, helper scripts. Treat this like a one-time setup of a teaching laptop - but you only have to do it once, here, for everyone.

If the lab needs a GPU or unusual amount of memory, configure that on the application now. See [Application resources](/reference/applications/application-resources) in Reference for the available options. If your institution restricts GPU usage, your administrator may need to enable it for the space.

Stop the application when you are happy with the configuration. The configuration travels with the application when it is distributed.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Add the dataset and lab notebook to the Master instance</mark>

Switch to the Files view in the Master instance. Upload your dataset and a starter notebook (or script) that students will edit during the lab. Keep the layout simple at this stage - flat is fine for a single lab session.

If your dataset is large or you want to use a database-backed approach instead of flat files, see [File storage](/reference/file-system-and-storage) and [Data storage](/reference/data-storage) in Reference.

Open the application again, run the starter notebook end-to-end, and confirm that everything works in the Master instance. The Master instance is your rehearsal stage - if it does not run cleanly here, it will not run cleanly for any student.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Distribute everything to current and future students</mark>

Distribution sends teaching material to all current and future instances in your course. This means you can distribute to both existing and prospective students in one step. The mechanism is documented in detail under [Distribution](/how-to-guides/common-workflows/object-distribution); the steps below are the practical lab-session workflow.

1. From the Master instance, make sure you are in the Current state.
2. On the Files screen, select your dataset and starter notebook and click STAGE. Recently used applications are automatically added to the distribution; review them and remove any you don't want students to receive. Selecting a folder adds the entire file tree recursively, and any sub-folder structure is preserved.
3. On the sidebar, click the share icon to open the Stage. Review the staged objects and click CONTINUE.
4. (Optional) Save the staged objects as a named bundle for future reference. This is useful if you plan to run the same lab next term - you can re-distribute the bundle without rebuilding it.
5. Select the target. By default, you distribute to all students - every existing instance and every future instance.
6. Decide on notifications. Send a notification email with a custom message so students know new material is available - useful when the lab is the next morning and they need to confirm their environment in advance.
7. Select the [distribution strategy](/reference/configuration/distribution-strategies). Overwrite is the default and almost always the correct choice for a fresh lab.
8. Review the list and click SHARE OBJECTS. Distributing large applications can take a while to complete - start the distribution at least an hour before the session if your image is large.

{% hint style="success" %}
**Checkpoint**

If you have a test student account from Your first course on Nuvolos tutorial, sign in as that student now and confirm that the dataset, notebook, and application all appear in the student instance. Run the notebook end-to-end as the student would. This is the single best way to catch problems before a live session.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Run the live session</mark>

During the session itself, your role inside Nuvolos is mostly to watch and support. Each student works in their own isolated instance - they cannot break each other's work, and they cannot break the Master instance. You can:

* Continue editing material in the Master instance and re-distribute fixes as needed (use Overwrite to push corrections live).
* Switch into student instances if a student gets stuck - Space Administrators have full visibility over every instance in the course.
* Use the same application as the students in your own instance to demonstrate steps in real time.

If something goes wrong with the material mid-session - a typo in the notebook, a missing file - fix it in the Master instance, stage just the fixed file, and re-distribute. Students who refresh will pick up the fix; students mid-flow will not have their work overwritten if they have already modified the file locally.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 6 - Capture the session</mark>

After the session, take a snapshot of the Master instance. A snapshot freezes the exact state of files, code, and configuration at this moment, and you can return to it any time. This makes the session reproducible — for next term, for a student who missed it, or for a colleague who wants to see exactly what you ran. Snapshots are explained in [How snapshots and states work](/concepts/distribution) in Concepts.

{% hint style="success" %}
**You're done**

You have run a complete data-heavy lab cycle: configure once, distribute to everyone, watch students work in identical isolated environments, fix and re-distribute on the fly, and capture the result. The same pattern scales from a one-off lab to a full term-length course.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* To repeat the same setup for a parallel section, see [How-to › Structure your course](/how-to-guides/workflows-for-instructors/best-practice-structuring-your-course).
* To turn the lab into a graded assignment, see [How-to › Assignments, grading, and feedback](/how-to-guides/workflows-for-instructors/setting-assignments).
* To run the lab on GPU-enabled machines, see [How-to › Courses with GPUs](/how-to-guides/workflows-for-instructors/courses-with-gpus).


# Reusing a course for the next term

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have a fresh course for the new term that contains the teaching material from a previous course - but none of last term's student instances, hand-ins, or in-progress edits. You will know which artefacts to carry forward, how to bring them across cleanly, and how to leave the old course archived as an institutional record.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 30–45 minutes for the carry-forward itself, plus the time to re-distribute applications and material to the new cohort (which can run for a while in the background).

<mark style="color:$primary;">**What you need before you start.**</mark> \
A previous course you have taught at least once on Nuvolos, ideally with the Master instance still in good shape. You should be a Space Administrator on that course. If the previous course has already been archived, that is fine - Section Step 2 covers how to access archived material.

{% hint style="info" %}
**Why not just re-use the old course?**

It is tempting to keep teaching out of the same course year after year. Two things make that a poor choice. First, distribution targets every existing instance, so re-distributing material into last year's cohort wakes up old student instances and creates noise. Second, hand-in storage, audit trails, and grade tables accumulate - by year three, the assignment views are crowded with material from cohorts who graduated. Starting a fresh course every term keeps each cohort self-contained while letting you carry forward exactly what you want.
{% endhint %}

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Decide what you actually want to carry forward</mark>

Before touching anything, list the artefacts in the old Master instance. Most of them fit one of three buckets:

* Bring forward as-is: lecture notes, starter notebooks, datasets, configured applications, `README` content. These are the assets that took real work to produce and are still good.
* Bring forward and update: assignment files (deadlines and contexts will change), version-pinned dependencies, anything dated. Carry them across, then revise.
* Leave behind: student instances, hand-ins, grades, scratch files, anything generated during a live session that shouldn't outlive the term.

The Master instance is the right source for everything in the first two buckets. Student instances are the right place for nothing in either.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Capture the previous Master instance as a snapshot</mark>

[Snapshots](/concepts/distribution) are the cleanest carry-forward mechanism. A snapshot of the Master instance freezes its files, configured applications, and state into an immutable record that you can later use as the seed for a new course.&#x20;

Open the previous course and navigate to the Master instance. From the left sidebar, hover the camera icon and click TAKE SNAPSHOT AND DESCRIBE. Give it a clear name like "end-of-term-2024-spring" so you can find it next term too. Add a description noting what was final and what was still being worked on.

{% hint style="info" %}
**If the previous course is already archived**

Archived courses are read-mostly but you can still create the seed you need. Open the archived space (turn on the Archived toggle in the Space dropdown if you don't see it), navigate to the Master instance, and [restore an existing snapshot](/how-to-guides/common-workflows/snapshots/restore-a-snapshot) to the current state. You then have 3 days to take a fresh snapshot and complete this tutorial — see How-to › End-of-course tasks › Archive your course for the grace-period rules.
{% endhint %}

{% hint style="success" %}
**Checkpoint**

You should now see your named snapshot in the snapshot list of the previous course's Master instance. This snapshot is your safety net and your carry-forward source — everything you do next builds on it.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Create the new course</mark>

[Create the new course](/how-to-guides/workflows-for-instructors/create-a-new-course) as you would a fresh course, but pay attention to two specific choices:

* Course name - include the term so cohorts don't blur together ("Statistics 101 — Autumn 2025" not just "Statistics 101").
* Application picker - skip it. You will not pick a fresh application here; you will bring the configured one across from the previous Master instance in the next step.

From the Dashboard, select + SPACE, select **Course** in the drop-down fill in the name and description, click ADD SPACE, and skip the application step. You now have an empty new course with an empty Master instance.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Bring teaching material across with cross-space distribution</mark>

Distribution normally pushes material from the Master instance of one course to its student instances. Less obvious - and the key to this workflow - is that you can also distribute from the Master of one course into the Master of another. This is how teaching material moves across course boundaries on Nuvolos.

Open the previous course and go to the Master instance. Make sure you are looking at the Current state (or restore the snapshot from Step 2 if you took it earlier and the state has drifted). Then:

1. On the Files screen, select the files and folders you want to bring forward. On the Applications screen, select any configured applications. Stage everything together.
2. Click the share icon on the sidebar to open the Distribution. Review the staged objects and click CONTINUE.
3. Save the staged objects as a named bundle (for example, "course-template-2024"). This makes the same carry-forward repeatable next term - you re-distribute the bundle without re-staging individual files. See [distribution bundles](/how-to-guides/common-workflows/object-distribution) for details.
4. On the target screen, change the target from the default ("all students of this course") to the Master instance of the new course. This is the cross-space distribution: the source is the old course's Master, the target is the new course's Master.
5. Choose the [distribution strategy](/reference/configuration/distribution-strategies). For a fresh course Overwrite is correct, as there is nothing in the new Master to preserve.
6. Click SHARE OBJECTS. If you brought across applications, distribution may take a while.

{% hint style="success" %}
**Checkpoint**

Open the new course and navigate to its Master instance. Your carried-forward files, folders, and applications should all be present. Start the application - if you bring forward a configured JupyterLab from last term, all your packages and customisations should already be in place.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Update what needs updating</mark>

This is the part that has to happen by hand. The carried-forward material is correct as of last term, not as of this term. Walk through it and fix:

* Dates and deadlines in the README and in any assignment files.
* Term numbers, room references, lecture-day references.
* Pinned package versions if you want to refresh - or, if you don't, version-pin them more aggressively now to *prevent* updates this term.
* Anything tied to the previous cohort: "Last year's class found this hard" comments, references to specific student questions, etc.

If the course uses the Course Configuration > Student Credit Quotas screen for GPU access, redefine the quota schedule for the new term - old end-dates are now in the past and will not work.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 6 - Set up archival on the new course and invite the new cohort</mark>

Now treat the new course as you would any new course. Set the Space archival date at the time of creation, or edit it now via the info panel on the course overview, so the new course will archive automatically at the end of this term - same lifecycle, same hygiene. See [How-to › Archiving your course](/how-to-guides/workflows-for-instructors/archiving-your-course) for the mechanics.

Then invite the new cohort following [How-to › Invite students](/how-to-guides/workflows-for-instructors/invite-students). Each new student gets their own fresh instance, populated automatically from your carried-forward Master via the Distributed instance - the same mechanism that gets material to first-day joiners in any course.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 7 - Archive the previous course</mark>

If the previous course is not yet archived, archive it now. Set the archival date or wait for the automatic schedule, depending on your institution's record-keeping preferences.&#x20;

Archived courses keep hand-ins and grade tables intact for institutional reference but free up everyday storage. Students from the old cohort can still restore snapshots to retrieve their work; new students never see the old course at all.

{% hint style="success" %}
**You're done**

You have lifted the teaching material from the previous course into a fresh course, updated what needed updating, set up the new course's lifecycle, invited the new cohort, and archived the previous course. The carry-forward is now repeatable - next term you re-run the same steps, ideally re-using the bundle you saved in Step 4.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* If you want a colleague to take over the course rather than continuing it yourself, the same carry-forward works. See [How-to › Invite teaching assistants and co-instructors](/how-to-guides/workflows-for-instructors/invite-tas) to give them the right roles before you hand the bundle over.
* If your course used GPU access last term, double-check the new credit-quota schedule before students arrive. See [How-to › Courses with GPUs](/how-to-guides/workflows-for-instructors/courses-with-gpus).
* To turn the carried-forward material into graded assignments for the new cohort, see [How-to › Assignments, grading, and feedback](/how-to-guides/workflows-for-instructors/setting-assignments).


# Tutorials for Students

This platform provides you with a ready-to-use environment for your coursework, giving you access to all the software and materials you need without any complex setup.

Nuvolos helps you solve the following challenges:

* **Hassle-Free Setup -** Accessing a pre-configured environment with all the necessary software and libraries, so you can start working on your assignments right away.
* **Consistency -** Working in the same environment as your instructors and peers, ensuring that your code runs as expected and eliminating compatibility issues.
* **Access from Anywhere -** Connecting to your Nuvolos space from any device with a web browser, allowing you to work on your coursework from anywhere with an internet connection.
* **Easy Collaboration -** Collaborating with your classmates on group projects in a shared environment.
* **Version Control -** Saving snapshots of your work, so you can track your progress and revert to previous versions if needed.


# Your first day in a Nuvolos course

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have accepted your course invitation, signed in to Nuvolos, opened your course, started the application your instructor set up, and saved a first snapshot of your work.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 10 minutes the first time, plus 30–60 seconds for the application to start.

<mark style="color:$primary;">**What you need before you start.**</mark> \
An invitation email from your instructor and a web browser. You do not need to install anything - Nuvolos runs entirely in the browser.

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Accept your invitation</mark>

Course participation in Nuvolos is by invitation only. Find the invitation email from your instructor in your inbox.

1. Open the invitation email.
2. Click Review Invitation - this takes you to Nuvolos in your browser.
3. If you don't have a Nuvolos account yet, sign up. For students at a Swiss higher education institution, choose the SWITCH login option.
4. Click Accept invitation.

{% hint style="success" %}
**Checkpoint**

You should now be signed in and looking at the Nuvolos Dashboard. The Dashboard shows your organisations and recent applications. If you don't see anything, refresh the page.
{% endhint %}

{% hint style="info" %}
**First-time sign-up**

If this is your very first time on Nuvolos, the sign-up process may take up to a minute to complete. Wait for it to finish before clicking anything else.

When accepting the invitation, we strongly encourage you to proceed with the recommended option for your institution. For students at a Swiss higher education institution, this is SWITCH. If you choose to sign up with email and password authentication instead, the SWITCH option will no longer be available to you.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Navigate to your course</mark>

After signing in, the Dashboard is your starting point. From here, you can reach the course you just joined.

1. On the Dashboard, find the course you joined and click its name. This opens the course space.
2. Your personal instance is selected automatically. You will see the Current state of your instance - this is your private workspace, separate from every other student's.

For more details on the Nuvolos interface, see how to [navigate in Nuvolos](/getting-started/find-your-way-around).

{% hint style="success" %}
**Checkpoint**

You should now be inside your personal instance for the course, viewing the Current state. This is where everything you do during the term will live: course materials your instructor has shared, files you create, and work you save.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Start the application your instructor set up</mark>

[Applications](/concepts/applications) are the interactive tools you use to work with your course materials - for example RStudio, JupyterLab, MATLAB, or VS Code. Your instructor pre-installs the applications you need; you just start them.

1. On the left sidebar, click the Screen button (Applications) to open the application list.
2. Find the application your instructor set up (for example RStudio, JupyterLab, or MATLAB).
3. Click the power button or the application name to start it.
4. Wait 30–60 seconds for the application to load. The first start may take longer if packages or configuration files need to be copied.

You can also start recently used applications directly from the Dashboard - click the application name there and it opens immediately.

{% hint style="success" %}
**Checkpoint**

The application should now be open in your browser. Look around - your course materials, distributed by your instructor, should already be visible in the application's file panel. Try opening one to confirm everything works.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Save your progress with a snapshot</mark>

Before you finish a work session, take a [snapshot](/how-to-guides/workflows-for-students/snapshot-your-work) so you can always return to this point. A snapshot captures the complete current state of your instance - files, tables, and application configurations - as an immutable, time-stamped record.

1. From the left sidebar, hover on the camera icon.
2. Click **QUICK SNAPSHOT**.

That's it - your files, tables, and application state are preserved at this exact moment. Even if you accidentally delete something later, you can restore from this snapshot.

{% hint style="success" %}
**You're done**

You have signed in, opened your course, started an application, and saved your first snapshot. You are now ready to do real coursework. Take snapshots regularly - at the end of each session is a good rhythm - so you always have a recent point to return to.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* When your instructor distributes an assignment, see [Complete and submit assignments](/how-to-guides/workflows-for-students/working-on-assignments).
* To learn more options for taking and naming snapshots, see [How-to › Snapshot your work.](/how-to-guides/workflows-for-students/snapshot-your-work)
* To stop the application when you are done (which frees up resources), see [How-to › Stop an application](/how-to-guides/workflows-for-students/start-an-application).


# Submitting your first assignment

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have located your first assignment, opened the assignment files in your application, completed the work, handed it in before the deadline, verified the submission, and reviewed the feedback your instructor sends back.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 15 minutes for the submission flow itself, plus the time you spend doing the actual coursework and the time your instructor needs to grade.

<mark style="color:$primary;">**What you need before you start.**</mark> \
You should have completed your first tutorial - that is, you have accepted your invitation, you can navigate to your course, and you can start the application your instructor set up. You also need an active assignment from your instructor.

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Find the assignment</mark>

When your instructor creates an assignment for the course, it shows up in two places. Pick whichever is convenient.

* On the space overview dashboard - when you open the space, you will see the assignment listed.
* In the assignment view - click the assignment icon on the sidebar. This is the more detailed view: it shows submission deadlines, whether you have already submitted, and gives you the submission action when the hand-in is still open. The countdown color goes from red to green to indicate how much time is left.

Click the assignment to open it. You will see the files that are part of the assignment.

{% hint style="success" %}
**Checkpoint**

The files of the assignment are [distributed](/concepts/distribution) to you by the instructor. They appear in your application as regular files - you can open and edit them just like any other file. The deadline countdown should be visible in the assignment view.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Work on the assignment</mark>

Open the application your instructor set up and navigate to the assignment files. Work on them as you would any other file.

Once you are satisfied with your work, save all the files in the application before moving on to the next step.

*Tip: Take a snapshot of your instance before submitting. That way you have a recoverable copy of your final draft if anything goes wrong.*

{% hint style="warning" %}
**Important - keep file names and locations identical**

To make submission simple, Nuvolos hands in the files that are part of the assignment automatically. You cannot manually "select" files to submit - every file in the assignment description is submitted automatically to the instructor.

This means if you worked on the material offline and want to bring it back in, you must move your solution to the exact same folder with the exact same name as you received it on Nuvolos. Otherwise the submission protocol will not find the file to submit.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Hand in the assignment</mark>

To hand in:

1. Click the assignment on the dashboard, then click the Hand-in button on the top right of the dialog. Alternatively, open the assignment overview and use the Hand-in button under Actions.
2. Choose a hand-in identifier. This is what your instructor will see as the title of your submission. If you are uncertain what to use, ask your instructor - usually it is your university email address, a unique university identification number, or similar.
3. Confirm the submission.

{% hint style="warning" %}
**Submission rules**

All files in the assignment must exist at submission time - otherwise the submission will fail.

The total combined size of files and folders cannot exceed the hand-in limit. It is your responsibility to remove unneeded files from the submission folders. The system rescans file and folder sizes each time you try to submit.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Verify the submission and resubmit if needed</mark>

After handing in, the submitted files appear in the hand-in area as read-only copies. It is recommended to check the hand-in area after a submission to make sure all files were submitted with the right version. You cannot modify the files there, but you can download them to verify.

To open the hand-in area from your application, navigate to:

```sql
Assignments > handback > [assignment_name] > [handin_id]
```

You can submit multiple times for the same assignment from the same instance until the deadline has passed. The instructor will only see your latest hand-in and will grade this version. This is true even if you use different identifiers for the different submissions, or if multiple users submit assignments from the same instance - one instance can have only one gradable submission, the latest one.

{% hint style="success" %}
**Checkpoint**

You should see your hand-in identifier listed in the assignment view, and the submitted files visible (read-only) in the hand-back area. If anything is missing, you still have time before the deadline to fix it and resubmit.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Review feedback when it arrives</mark>

Once the instructor has reviewed your work, they will enable you to see the hand-back version of the files. To review:

1. Click the assignment tile to open the assignment view.
2. Look at the Handback tab. Your grade is shown there.
3. Review the corrected version of your files, listed under the Handback tab. These files are read-only for students; you can download them from the Actions column.

If you prefer to review the corrections inside the application, first stop any running applications, then click the Review Corrections button from the assignment dialog. The application will open with the corrections in:

```sql
Assignments > handback > [assignment_name] > [handin_id]
```

{% hint style="info" %}
**When feedback isn't visible yet**

You will only see feedback in the handback folder if the teacher has made handbacks available. Only the latest hand-in will be graded.
{% endhint %}

{% hint style="success" %}
**You're done**

You have completed a full assignment cycle: locate the assignment, work on the files, hand in, verify, and review feedback. The same flow applies to every assignment in your course — and you can resubmit any number of times before the deadline.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* For the full reference of submission rules, the hand-in area structure, and feedback flow, see [How-to › Complete and submit assignments](/how-to-guides/workflows-for-students/working-on-assignments).
* If your course uses GPU-enabled applications, see [How-to › Collaborate and use special resources](/how-to-guides/workflows-for-students/working-with-a-gpu-in-a-course).
* To understand the model behind assignments and feedback, see [Concepts › Snapshots, distribution, and states](/concepts/distribution).


# Working on a group project

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have accepted your group invitation, understood the difference between your personal course instance and your group instance, started the shared application your instructor set up for the group, worked alongside your teammates without overwriting their changes, and saved a snapshot of the group's combined progress.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 15–20 minutes for the orientation steps, plus the time you spend on the actual group work.

<mark style="color:$primary;">**What you need before you start.**</mark> \
You should have completed Tutorial 'Your first day in a Nuvolos course' - that is, you have accepted your course invitation and you can navigate to your course. You also need a group invitation email from your instructor (this arrives separately from the course invitation). If your group has not been set up yet, ask your instructor.

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Accept your group invitation</mark>

When your instructor sets up a group project, they create a separate group-work space and invite each group member to a shared instance inside it. The invitation arrives by email, separately from your original course invitation.

1. &#x20;Open the group invitation email.
2. Click Review Invitation.
3. Check the role: it should be Instance Editor - this lets you modify files in the shared instance.
4. Click Accept invitation.

{% hint style="warning" %}
**Use the right email address**

Your instructor must invite you using the email address you already use for Nuvolos. If the invitation was sent to a different address, you will not be able to accept it with your existing account. If this happens, ask your instructor to re-send to the email listed under your name in the course Members list.
{% endhint %}

{% hint style="success" %}
**Checkpoint**

After accepting, return to the Dashboard. You should now see two spaces for this course: your regular coursework space (with your personal instance) and a separate group-work space (with your group instance). Both belong to the same course but are organised separately so individual and group work never get tangled.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Understand which space does what</mark>

Two spaces, two different working models. Knowing when to use which avoids most of the confusion that comes with group projects.

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Your personal course instance</strong></td><td valign="top"><strong>Your group instance</strong></td></tr><tr><td valign="top">In the regular coursework space.</td><td valign="top">In the separate group-work space.</td></tr><tr><td valign="top">Only you can see and edit it.</td><td valign="top">Every group member can see and edit it. The current state is shared.</td></tr><tr><td valign="top">Use for individual assignments, your own notes, your own experiments.</td><td valign="top">Use for the group's shared deliverable, group code, group data.</td></tr><tr><td valign="top">Your work here is private to you and the instructor.</td><td valign="top">Anything you save here is immediately visible to your teammates.</td></tr></tbody></table>

{% hint style="warning" %}
Keep individual assignments in your personal instance. Keep group deliverables in the group instance. The two are deliberately separate so that an accidental edit to a group file does not lose someone's individual work, and vice versa.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Start the shared application</mark>

Open the group-work space from the Dashboard, navigate to your group instance, and start the application your instructor configured for group work. The startup procedure is the same as for any other application.

1. On the left sidebar, click the Screen button (Applications) to open the application list.
2. Click the power button or the application name to start it.
3. Wait 30–60 seconds for the application to load.

Many group projects use JupyterLab 3.1 or later configured in Shared editing mode (similar to Google Docs). In this mode, multiple group members can connect to the same notebook at the same time and you will see each other's edits live, with no file version conflicts. Your instructor sets this up - you don't configure anything yourself, you just start the application.

{% hint style="success" %}
**Checkpoint**

The application should now be running in your group instance. Any files your group has already shared are visible. If teammates are also working, you may see their cursors or recent edits — that's the shared mode in action.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Work alongside your teammates</mark>

Editing in a shared instance is mostly straightforward, but the rules differ from working alone. Two cases to know about:

**If your application is in Shared mode (e.g. JupyterLab Shared)**

You can work in the same notebook simultaneously. Edits merge automatically - like a shared document. There is no "locking" of files; just be aware that your teammates can see your work as you do it.

**If your application is not in Shared mode**

Multiple people editing the same file at the same time produces application-dependent results - sometimes one set of changes wins, sometimes both versions get saved, sometimes the file is corrupted. The way around this is to coordinate before you edit:

* Break work into appropriately small blocks (separate files, separate notebooks per task) so two people are rarely in the same file.
* If two people must edit the same file, schedule it - agree on who works on it when, and only one person at a time.
* Communicate in your group's chat (Slack, WhatsApp, or whatever you use) before opening a file someone else might be editing.
  {% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Save the group's progress with a snapshot</mark>

Snapshots in a group instance work the same way as in your personal instance — they capture the complete current state of the instance. The difference is that a snapshot in a group instance preserves *everyone's* work, not just yours. Take one before you stop for the day, and definitely before any major change that the group might want to roll back.

1. From the left sidebar, hover on the camera icon.
2. Click TAKE SNAPSHOT AND DESCRIBE.
3. Use a name that makes sense to the whole group, not just to you (e.g. "after Monday's working session" rather than "my snapshot").

{% hint style="warning" %}
**Coordinate snapshots**

Anyone in the group can take a snapshot, but only one snapshot can have a given name. Pick a snapshot-naming convention with your group early - date-based names are usually safest. If something goes wrong, anyone in the group can later restore the snapshot, which affects the whole instance and therefore everyone.
{% endhint %}

{% hint style="success" %}
**You're done**

You have joined a group, started the shared application, worked alongside teammates without conflicts, and saved a snapshot of the group's combined progress. From here, the group-instance workflow is the same as your personal-instance workflow - with the wrinkle that everything you save is immediately visible to your teammates.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* If your group project culminates in a single hand-in, the submission flow works the same way as explained under [Submitting your first assignment](/tutorials/tutorials-for-students/submitting-your-first-assignment). One group member submits on behalf of the group.
* To take and restore named snapshots, see [How-to > Save and recover work](/how-to-guides/workflows-for-students/snapshot-your-work).


# Tutorials for Researchers

Nuvolos offers researchers a collaborative, reproducible, and scalable environment for their projects. It streamlines the process of managing data, code, and computational environments, enabling you to focus on your research questions.

#### Use Case: Ensuring Reproducibility in Complex Studies

{% tabs %}
{% tab title="Problem" %}
**Recreating computational environments long after a study concludes**\
\
Researchers often struggle to recreate exact computational environments months or years after a study ends. Lost dependencies, undocumented configurations, and version mismatches create roadblocks during peer review or when building on previous work.
{% endtab %}

{% tab title="Solution" %}
**Versioned snapshots of complete computational setups**\
\
Nuvolos tracks and versions data, code, and software dependencies together as a single, immutable snapshot. This guarantees that any past study can be recreated and verified at any time, with no manual configuration required.
{% endtab %}

{% tab title="Result" %}
**Reliable reproducibility without the overhead**\
\
By eliminating the need to manually rebuild or troubleshoot historical environments, research teams can revisit and verify past work with confidence. This directly supports open science standards and removes one of the most persistent practical barriers to reproducible research.
{% endtab %}
{% endtabs %}

#### Use Case: Streamlining Global Research Collaboration

{% tabs %}
{% tab title="Problem" %}
**Fragmented tools slow down cross-institutional collaboration**\
\
When working with co-authors across different institutions, sharing large datasets, codebases, and application environments often relies on fragmented tools, clunky file transfers, and disjointed version control. This creates localized environment mismatches that bottleneck the entire project.
{% endtab %}

{% tab title="Solution" %}
**A shared, centralized cloud workspace**\
\
Nuvolos provides a cloud workspace designed for code and data collaboration. Invited collaborators instantly access the exact same computing environment, data, and applications - concurrently, without any local configuration or hardware constraints.
{% endtab %}

{% tab title="Result" %}
**A single source of truth for the entire team**\
\
With all collaborators working from the same environment and data, teams eliminate the back-and-forth caused by environment mismatches and incompatible setups. This reduces communication friction, keeps projects moving, and lets researchers focus on analysis rather than logistics.
{% endtab %}
{% endtabs %}

Nuvolos helps you solve the following challenges:

* **Reproducibility:** Ensuring your research is fully reproducible by capturing the complete computational environment, including data, code, and software dependencies.
* **Collaboration:** Facilitating seamless collaboration with colleagues by providing a shared environment where you can work together on code and data in real-time.
* **Data Management:** Simplifying the management of large and complex datasets, providing a centralized and secure location for your research data.
* **Scalability:** Offering scalable computational resources that can be adjusted to meet the demands of your research, from initial exploration to large-scale analysis.
* **Environment Management:** Eliminating the complexities of managing software dependencies and environments, allowing you to switch between different projects and configurations.
* **Preservation:** Ensuring the long-term preservation of your research outputs, including data, code, and results, in a secure and accessible format.


# Your first research project

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have joined your institution's Nuvolos organisation, created a research project, brought in some files and code, invited a collaborator, run a first application against your material, and saved a snapshot you can return to.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 30–45 minutes, plus the time it takes for an invited collaborator to act on your invitation.

<mark style="color:$primary;">**What you need before you start.**</mark> \
**An invitation** email from a Manager at your institution, with the Faculty or Manager role on a Nuvolos organisation. If you have not received one, ask your PI, lab admin, or IT contact - Nuvolos is invitation-only and you cannot create a research project without organisation membership. You should also have one or two files or a code repository in mind to bring in (a CSV, a notebook, a Git URL - anything small).

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Accept your organisation invitation</mark>

Nuvolos is an invitation-only platform. As a researcher, you can be invited in two main ways: directly to an organisation (the path this tutorial assumes), or to a specific research project as a collaborator (covered separately in the how-to guide on joining a research project).

To create and manage your own research projects you need to be invited to an organisation with the appropriate role:

* **Member** - typically for junior researchers or external collaborators. Does not allow you to create new spaces.
* **Faculty** - the standard role for researchers. Lets you create new research spaces, manage project data, and control access for collaborators.
* **Manager** - has all Faculty permissions, and additionally can manage organisation-wide billing and invite other Faculty/Managers.

For more detail, see [Roles and permissions](/concepts/roles-secrets-and-identity/roles) in Reference.

For this tutorial you need either Faculty or Manager. Open the invitation email, click Review Invitation, and complete the sign-up if you do not already have a Nuvolos account. Choose the recommended login option for your institution. Click Accept Invitation. The first sign-up may take up to a minute.

{% hint style="success" %}
**Checkpoint**

You should now see your organisation's Dashboard. The Dashboard is where every research project you create or collaborate on will appear.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Create your first research project</mark>

A research project in Nuvolos is a space - a workspace where you store and work on your code and data. Each project gets its own space, separate from every other project you have on Nuvolos.

From the Dashboard:

1. Click the **+** (plus) icon next to the Spaces list, or click the **+ SPACE** button in the Recent Spaces section at the bottom of the Dashboard.
2. From the dropdown menu, select **Project**.
3. Create a name and a description. The name has to be unique organisation-wide - try to give descriptive, unique names. You can change both the name and description later.
4. Choose a visibility option. Private is almost always the right choice and is the safe default for a first project.
5. (Optional) Add a `README.md` format description now or later.
6. Click **+ ADD SPACE**.
7. (Optional) On the next screen, create an application in the Master instance immediately. You can also do this any time later from the Applications screen of the instance - for this tutorial it does not matter which you choose, since Step 4 covers application setup either way.
8. Navigate directly into the project, or move back to the Dashboard.

{% hint style="warning" %}
**Visibility is the only thing you cannot change later**

All other properties of a project - name, description, README - can be edited at any time. Visibility is the one exception. If you are unsure, pick Private now; you can revisit only by creating a new project.
{% endhint %}

{% hint style="success" %}
**Checkpoint**

You should now be inside your new project, looking at the Master instance. The Master instance is where you will develop and maintain your research material. You'll learn what role each piece plays in the next steps.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Add some material to the project</mark>

Research material is anything that supports the project: data files, source code, notebooks, slides, papers, configuration. There are several ways to bring it in, you can mix and match depending on what you have.

For this tutorial, pick the simplest available path:

* Have a small file? Use the file upload feature from the [Files view](/reference/file-system-and-storage/file-navigator) - click UPLOAD on the top left and pick a file.
* Have a Git repository? Open a terminal in any application and clone it. If your repository is private, consider adding a [Nuvolos-generated SSH key](/reference/file-system-and-storage/access-remote-files-with-sshfs) to your accepted keys.
* Other options exist too - direct download (wget, curl, or any API from a Nuvolos application), or attaching external storage like S3 buckets via the [rclone mount option](/reference/file-system-and-storage/access-s3-buckets-with-rclone). For everything available, see [Storage and file access](/reference/file-system-and-storage).

Pick one method, bring in one piece of material, and confirm it appears in the file list. You can add more later.

{% hint style="success" %}
**Checkpoint**

Your file or repository should now be visible in the Master instance's file list. This is the canonical place for project material - everything you do next builds on it.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Run an application against your material</mark>

Applications are the interactive tools you actually work in - JupyterLab, RStudio, Matlab, VS Code, and so on. If you skipped the application step in Step 2, install one now:

1. Confirm in the breadcrumbs that you are in the new project's Master instance, in the Current state.
2. On the sidebar, click the Screen button (Applications) to see the application list.
3. Click **+ ADD NEW APPLICATION**. This brings up the Application Marketplace.
4. Pick something simple to start - JupyterLab if you work in Python, RStudio if you work in R. Click **+ INSTALL**.
5. Once installed, click the power button or the application name to start it. Wait 30–60 seconds - the first start may take longer if packages or configuration files need to be copied.

When the application opens, you should see the file or repository you brought in during Step 3 in the application's file panel. Open it, run a cell or two if it's a notebook, and confirm the environment behaves as you expect.

{% hint style="success" %}
**Checkpoint**

Your application is running, your material is accessible from inside it, and you have run something - even if it's just opening a file or printing "hello" in a cell. This is the moment your Nuvolos project becomes a real working environment.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Invite a collaborator</mark>

With material in place and an application running, you are ready to invite a collaborator. Nuvolos supports two kinds of collaborator role; pick based on what you want them to do. To go deeper later, see the full [Roles and permissions](/concepts/roles-secrets-and-identity/roles) reference.

* Space Administrator - full privileges on the project, including inviting more users, creating new instances, and deleting the project. Use for co-authors who are full partners on the project.
* Instance Editor - can see and edit a single instance only. Cannot create instances, invite users, or modify anything outside that instance. Use for collaborators with a narrower scope (a student helping with one analysis, an external advisor reviewing one branch).

For this tutorial, pick whichever fits a real colleague you want on the project. From inside the project:

1. From the sidebar, click the More options menu (⋯) next to the selected Space name, choose **Invite Users.**
2. For a co-author with full privileges, choose Option 2 - Administrator Invitation. For a narrower-scope collaborator, choose Option 1 - User Invitation, then pick the instance and the role to assign.
3. Enter the email address of the person you want to invite. Click **INVITE**.

Your collaborator receives an invitation email. Once they accept, they appear in the project users list with the role you assigned.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 6 - Save a snapshot</mark>

Before you finish for the day, take a snapshot of the Master instance. A snapshot captures the complete state - files, code, application configurations, everything - as an immutable, time-stamped record. It's the cheapest insurance you have.

From the left sidebar, hover the camera icon, and click TAKE SNAPSHOT AND DESCRIBE. Use a descriptive name ("initial setup - material loaded, JupyterLab installed" works well for a first snapshot). Add a short description noting what's in this state.

{% hint style="success" %}
**You're done**

You have created a research project, added material, run an application against it, invited a collaborator, and saved a recoverable snapshot. Every later piece of work - exploring alternative approaches, scaling up to a GPU, sharing with a reviewer, exporting the result - builds on these six steps.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* To explore alternative methods or parameters in parallel without forking the project, see [How-to › Create alternate instances](/how-to-guides/workflows-for-researchers/create-alternate-approaches).
* To scale up to GPU-enabled compute when your work requires it, see [How-to › GPU computation](/how-to-guides/workflows-for-researchers/gpu-computation).
* When the analysis is complete and you need to package it for a reviewer or hand it off, see second Tutorial: [From notebook to reproducible result](/tutorials/tutorials-for-researchers/from-notebook-to-reproducible-result).


# From notebook to reproducible result

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have run a complete analysis cycle (query → analyse → store), captured the working environment as a named snapshot, prepared a copy of it for an external reviewer, and exported the project as a portable Docker image you can hand to anyone, including someone outside your Nuvolos organisation.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 60 minutes for the full cycle, depending on how much analysis you actually run. The export step itself can take a while in the background.

<mark style="color:$primary;">**What you need before you start.**</mark> \
You should have completed '[Your first research project](/tutorials/tutorials-for-researchers/your-first-research-project)' tutorial - that is, you have a research project on Nuvolos, you can navigate to it, and you have at least one application installed. You also need at least one dataset accessible from your project (either a Nuvolos table distributed to your instance, or a file you have already brought in).

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Run a complete analysis cycle</mark>

{% hint style="info" %}
The full reference, with both Matlab and RStudio code listed in parallel, lives in How-to ›  [Database research workflow](/how-to-guides/workflows-for-researchers/a-complete-database-research-workflow-matlab-and-rstudio).
{% endhint %}

A scientific workflow on Nuvolos breaks down into three steps that you'll do back-to-back, in the same application session:

* Query research-relevant data - pull what you need from a Nuvolos table or file.
* Analyse - transform, fit, summarise.
* Store - write the result back somewhere it will outlast your application session.

Open RStudio (or Matlab, or whichever language you prefer). The cycle in RStudio looks like this:

<mark style="color:$primary;">**Querying relevant data**</mark>

The example uses the Fama-French factor set available to demo users, joining a monthly stock series with the 5-factor table for one stock:

```sql
SELECT NAF.*, SM.MPRC, SM.MRET*100 AS SM_MRET_100, SM.MTCAP 
FROM NORTH_AMERICA_5_FACTORS NAF 
INNER JOIN TIME_SERIES_MONTHLY SM 
ON SM.MCALDT = NAF.DATE 
WHERE KYPERMNO = 14593
```

The code that executes the query, the above string is saved in `query_string`.

{% code overflow="wrap" %}

```sql
conn <- nuvolos::get_connection()
dataset_factor <- dbGetQuery(conn, query_string)
```

{% endcode %}

<mark style="color:$primary;">**Simple analysis**</mark>

Fit a linear regression on the data frame, write fitted values back into it:

{% code overflow="wrap" %}

```sql
dataset_factor$EXCESS_RETURN <- dataset_factor$SM_MRET_100 - dataset_factor$RF
mod <- lm(EXCESS_RETURN ~ (-1) + MKT_RF + SMB + HML + RMW + CMA, dataset_factor)
dataset_factor$FIT_FACTOR_5 <- mod$fitted.values
```

{% endcode %}

<mark style="color:$primary;">**Storing results**</mark>

Write the result back to the database as a new table:

{% code overflow="wrap" %}

```sql
DBI::dbWriteTable(conn, name="APPLE_5FACTOR_FIT", value=dataset_factor, batch_rows = 10000)
```

{% endcode %}

{% hint style="info" %}
**Same cycle, different language**

In Matlab the cycle looks identical: get\_connection() / select(con, query\_string) to query, fitlm() to fit, sqlwrite() to store.\
The pattern generalises to any Nuvolos-supported language: query, analyse, store.
{% endhint %}

{% hint style="success" %}
**Checkpoint**

You should now have a new table in your database - the result of the cycle, stored alongside the original data. This is the moment the analysis becomes a result rather than just a session.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2 - Capture the working environment as a named snapshot</mark>

A snapshot at this point is what makes the result *reproducible* - anyone restoring this snapshot will see the same files, the same installed packages, the same environment in which your result was produced. Without it, you have a result; with it, you have a result that someone else can reach by the same path.

From the left sidebar, hover the camera icon, click TAKE SNAPSHOT AND DESCRIBE, and give the snapshot a meaningful name. Convention from the Nuvolos team: snapshots that represent a stable, citable state of the data or analysis are often called "vintages", for example, "v1.0 - final analysis 2026-05". Add a description that captures what's specifically reproducible about this state (the query you ran, the regression spec, the package versions if you bothered to pin them).
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Prepare a copy for a reviewer</mark>

If you are publishing or peer-reviewing, a journal editor or external reviewer often needs to inspect or re-run your work. The clean way to do this on Nuvolos is to give them an exact copy of your environment - restricted to that copy, with no access to anything else in your organisation.

From the project containing your snapshot:

1. Create a new instance in the same space, by clicking the **+** (plus) icon next to the Instances list.&#x20;
2. Name it after the reviewer or the journal (e.g. "Reviewer copy - XYZ").
3. Distribute the snapshot from Step 2 to the new instance - go to your Master instance, stage the relevant files/tables/applications, open the Staging menu, and select the new instance as the target.
4. Invite the reviewer to the new instance as an Instance Editor. They can see and run everything in that one instance and nothing else in your organisation.

{% hint style="warning" %}
**Two limitations to know about**

**Anonymity:** This setup is not suitable for anonymous reviewers. As the space administrator, you create the instance and handle invitations directly, so you will always know the identity of users in your space.&#x20;

**Role proliferation:** An Instance Editor can't invite further users. If a journal editor wants to bring in colleagues, they can't do so from this setup - you would have to invite each one yourself.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Export the project for an external audience</mark>

If you need to hand the project to someone you can't invite to Nuvolos at all - a customer, a partner, an auditor, an external collaborator - exporting is the right tool. Application Export turns a Nuvolos application into a portable Docker image that can be deployed outside the platform.

You can export at two levels:

* The application only - share configuration and runtime setup, but not data, code, or files. Most common when working with third parties.
* The application together with its files - a complete (with caveats) snapshot of the project state, including file-based artifacts used by the application.

For the exact procedure, see [Application Export](/reference/applications/exporting-applications) in Reference. The procedure is documented end-to-end there; this tutorial focuses on the reproducibility flow rather than the export mechanics.

{% hint style="warning" %}
**Important caveats - read before relying on exports as a full handover**

**Licenses:** Nuvolos follows a bring-your-own-license (BYOL) model. To prevent accidental license leakage, license-based applications and license-related environment variables are NOT included in exports by default. If your use case requires a fully functional, licensed package, contact Nuvolos support to discuss options.

**Tabular data:** Data stored in Nuvolos Tables is not bundled with application exports. If your project depends on tabular data, export the relevant data to files (CSV, Parquet) and adapt your setup to work with file-based inputs where appropriate, taking licensing constraints into account.

**Container registry:** Application exports are pushed to Docker Hub by default. If you need to export to a different container registry, reach out to Nuvolos support.
{% endhint %}

{% hint style="success" %}
**You're done**

You have closed the loop from raw data to a result that another researcher - inside or outside Nuvolos - can reach by the same path. The combination of a named snapshot (for collaborators on Nuvolos), a reviewer instance (for journal editors), and an Application Export (for everyone else) covers the full range of "how do I share this so it's reproducible?".
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* To preserve and version multiple research vintages over time, see [How-to › Preserve and share results](/how-to-guides/workflows-for-researchers/when-you-are-done-exporting).
* To set up the data side properly - querying, importing, datasets - see [How-to › Set up a dataset](/how-to-guides/workflows-for-researchers/setting-up-a-dataset-on-nuvolos).
* If your analysis needs more compute, see [How-to › GPU computation](/how-to-guides/workflows-for-researchers/gpu-computation).


# Reproducing a colleague's research project

This tutorial walks through how to actually reproduce someone else's work.

<mark style="color:$primary;">**What you will achieve.**</mark> \
By the end of this tutorial you will have received a colleague's reproducible research package, restored their working environment, run their original analysis to confirm it produces the result they reported, and (optionally) branched off into your own instance to build on top of their work without disturbing the original.

<mark style="color:$primary;">**How long it takes.**</mark> \
About 30–60 minutes for the reproduction itself, depending on the size of the analysis. Application restoration and (if applicable) Docker image import can take 10–20 minutes in the background.

<mark style="color:$primary;">**What you need before you start.**</mark> \
You should have completed '[Your first research project](/tutorials/tutorials-for-researchers/your-first-research-project)' tutorial - that is, you have a Nuvolos account and you can navigate the platform. You also need a handover from your colleague: an invitation email, an exported Docker image, or access to a snapshot in a project they have already shared with you. The colleague's published result (a number, a figure, a value in a paper or report) - you will need this to know whether reproduction succeeded.

{% stepper %}
{% step %}

### <mark style="color:$primary;">Step 1 - Identify what kind of handover you have</mark>

Three handover formats are common on Nuvolos. The right first move depends on which one you got, so identify yours before doing anything else:

<table data-header-hidden><thead><tr><th width="241" valign="top"></th><th width="292" valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">You received…</td><td valign="top">How you can tell</td><td valign="top">Skip to step</td></tr><tr><td valign="top">A Nuvolos invitation email</td><td valign="top">Subject line names a project; the email contains a Review Invitation button.</td><td valign="top">Step 2a</td></tr><tr><td valign="top">An exported Docker image (or a registry reference like docker.io/...)</td><td valign="top">Your colleague sent you a docker pull command, a Docker Hub URL, or a tar.gz archive.</td><td valign="top">Step 2b</td></tr><tr><td valign="top">Access to an existing project that already has a named snapshot</td><td valign="top">Your colleague says "restore the snapshot called v1.0 in the project I shared with you".</td><td valign="top">Step 2c</td></tr></tbody></table>
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2a - Restore the environment from a Nuvolos invitation</mark>

If your colleague invited you directly:

1. Open the invitation email and click Review Invitation.
2. Check the role: Instance Editor is the typical reviewer role and is what most authors will give you. It lets you run everything in the instance and modify it locally, without touching anything outside that one instance.
3. Sign in (or sign up) and accept the invitation.
4. From the Dashboard, navigate into the project. You should see one instance you have access to - that is the reviewer copy your colleague prepared.

Skip ahead to Step 3.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2b - Restore the environment from a Docker export</mark>

If your colleague sent you a Docker image or registry reference, you are reproducing the work outside Nuvolos. The [Application Export documentation](/reference/applications/exporting-applications) covers the import procedure end-to-end; the steps below are the practical reproduction workflow.

1. Load the image into your local Docker daemon. Choose the option that matches your source:
   1. Pull from a registry - if the image is hosted on Docker Hub or a private registry:

      `docker pull <reference>`
   2. Load from an archive - if you have a .tar file exported with docker save:

      `docker load -i <archive>`
2. Run the container with the recommended command from your colleague (or the defaults documented in the export). Most exports run a JupyterLab or RStudio server you can open in a local browser.
3. Open the application in your browser at the URL the container prints to its log.

Continue to Step 3.

{% hint style="info" %}
**What's missing from a Docker export**

By design, exports do not include: license-gated applications and the matching license environment variables (BYOL model - Nuvolos prevents accidental license leakage), and data stored in Nuvolos Tables. If the original analysis depended on either, your colleague should have either substituted a license-free alternative or exported the relevant Nuvolos Tables data to files (CSV or Parquet) before packaging. If you find one of these missing, that is what to ask them about first.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 2c - Restore from a named snapshot in a shared project</mark>

If your colleague has already given you access to their project:

1. From the Dashboard, navigate to the shared project. You should see at least one instance you can access.
2. Open the instance your colleague pointed you to. By default, you are looking at the Current state - but reproduction needs the historical state your colleague snapshotted.
3. Use the snapshot selector to switch from the Current state to the named snapshot your colleague identified (e.g. "v1.0 - final analysis 2026-05"). For details on snapshot navigation, see how [snapshots and states](/concepts/distribution) work in Concepts.

{% hint style="info" %}
**You're in a read-only state**

When you view a snapshot, you see the exact files and configuration as they were at snapshot time, but you cannot modify them. That is correct for the reproduction step - you want to run the original code unchanged. If you later want to extend the work, Step 5 covers how to branch off into your own writable instance.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 3 - Run the original analysis without changing anything</mark>

This is the moment of truth. Open the application your colleague used (the same JupyterLab, RStudio, Matlab, or whatever shows up in the application list - pre-configured with their package versions). Find their analysis script or notebook. Run it end-to-end without modification.

{% hint style="info" %}
**Resist the urge to refactor**

If the code is messy or in a style you would never use yourself, leave it alone. Your only goal in this step is to confirm that running the colleague's exact code produces the colleague's exact result. Cleanup, refactoring, or extension comes after the reproduction is verified, in Step 5.
{% endhint %}

If the analysis writes results to files, the database, or a return value, capture each one. You will compare them against the published numbers in the next step.
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 4 - Verify the result matches</mark>

Compare what you produced in Step 3 against your colleague's published result - the number in their paper, the figure they reported, the table in their methods section. There are three possible outcomes:

* Exact match: Numerical identity, byte-for-byte file equivalence. This is the strongest result and what well-prepared reproducibility packages aim for. Move to Step 5 (or stop here, if you only needed to confirm the result).
* Match within tolerance: Floating-point arithmetic, GPU non-determinism, or unseeded randomness can produce slightly different numbers between runs. If the difference is within reasonable tolerance for the analysis (often documented by the author), this still counts as successful reproduction.
* Mismatch: Numbers don't agree, or the script fails outright. Don't panic, the failure mode is usually informative. Common causes are listed below.

{% hint style="warning" %}
**Common failure modes when reproduction fails**

* Missing license: Errors like "License server not reachable" or "Feature not licensed" indicate a license-gated application that wasn't carried across. Most common with Matlab toolboxes, Stata, SAS, or commercial R packages. Ask your colleague which license configuration the original used.
* Missing tabular data: Errors mentioning database tables, NORTH\_AMERICA\_5\_FACTORS-style names, or "table does not exist" indicate the analysis depended on Nuvolos Tables data that wasn't bundled with a Docker export. Snapshot- and invitation-based handovers preserve this; exports do not.
* Unseeded randomness: If the analysis involves random sampling, bootstrapping, or stochastic optimisation and the author didn't set a random seed, you will get different numbers every run. The result should still be statistically equivalent - check whether the author reported confidence intervals or ran multiple seeds.
* Package version drift: If the original was run with sklearn 1.2 and you're now running 1.5, behavior may have changed. Snapshot- and invitation-based handovers preserve exact versions. With an export, check the image's package versions match what the author reported.
* Path or filename mismatch: Hard-coded paths in the original code may not exist in your environment. Check the script for absolute paths and adjust if needed - but document any change you make.
  {% endhint %}

{% hint style="success" %}
**Checkpoint**

If you reached an exact match or a match within tolerance: the reproduction is verified. The colleague's claim holds, and you now have a working environment in which to extend the work. If reproduction failed for a reason on the list above, the next step is usually to go back to the author with a specific question ("which Matlab license?" / "do you have the random seed?") rather than to try fixing it yourself.
{% endhint %}
{% endstep %}

{% step %}

### <mark style="color:$primary;">Step 5 - Branch off into your own instance to extend the work (optional)</mark>

Once reproduction is verified, you usually want to do something with the colleague's environment, like extend their model, try alternative parameters, run the analysis on your own data, build a follow-up paper. Doing this in their instance would mean modifying their work; doing it in your own personal Nuvolos project means losing their environment. The right answer is to branch.

If you have Space Administrator permission on the shared project, you can create your own writable copy of a colleague’s environment without modifying the original instance.

1. Open the shared project/space.
2. Click the **+** (plus) icon next to the Instances list to create a new Instance.
3. When prompted, choose the snapshot that you previously reproduced from. Complete the creation process.

A new instance will be created based on the selected snapshot. This gives you a fully writable copy of the environment while leaving the original instance unchanged.

For the complete workflow and additional details, see [Create alternate instances](/how-to-guides/workflows-for-researchers/create-alternate-approaches).

If you only have Instance Editor access (the typical reviewer role), you can't create new instances. Two options: (a) ask your colleague to create one for you, or (b) take a snapshot of the current state in your own first Nuvolos research project, then [distribute](/concepts/distribution) the files and applications across.

{% hint style="success" %}
**You're done**

You have received a reproducible research package, restored the working environment, run the original analysis, verified the result, and (optionally) created a writable copy to build on top of.&#x20;
{% endhint %}
{% endstep %}
{% endstepper %}

#### Where to go next

* If you intend to publish work that builds on this reproduction, see the [From notebook to reproducible result](/tutorials/tutorials-for-researchers/from-notebook-to-reproducible-result) tutorial to learn how to produce your own reproducibility package.
* To compare alternative methods or parameters in parallel without disturbing your reproduced baseline, see [How-to › Create alternate instances](/how-to-guides/workflows-for-researchers/create-alternate-approaches).
* If reproduction failed and you need to compare specific package versions or environment details, see [How-to › Run analyses and applications](/how-to-guides/workflows-for-researchers/work-with-applications) for application configuration and [How-to › GPU computation](/how-to-guides/workflows-for-researchers/gpu-computation) for GPU-specific considerations.


# Common workflows

Common Workflows is the canonical home for procedures every Nuvolos role performs the same way - accepting an invitation, starting and stopping applications, working with files, taking and restoring snapshots, distributing content, and inviting users. The role-specific guides (Instructors, Students, Researchers) link here whenever they touch one of these shared procedures, rather than duplicating the steps.

Each page in this section follows the same shape: a single-line **Outcome** describing what you will have done, a **Before you start** block with prerequisites, the steps themselves, and (where useful) role-specific notes at the bottom for the cases where the procedure has slightly different consequences depending on your role.

The pages in this section:

* **Accepting an invitation** - joining Nuvolos for the first time, choosing your identity provider, troubleshooting the wrong-email case.
* **Starting an Application** - launching an application from the Dashboard or from your instance.
* **Stopping an Application** - the four ways to stop a running application.
* **Working with files** - uploading files, cloning Git repositories, downloading from URLs, mounting external storage.
* **Snapshots - Overview, Create, Restore, Delete** - the snapshot lifecycle.
* **Requesting roles** - submitting a role request when you can see content but cannot interact with it.
* **Distribution** - the staging-and-distribute click-flow used to push files, tables, or applications between instances.
* **Inviting users** - the invitation click-flow used by Space Administrators.

If you arrived from a role-specific guide, follow the procedure here and return to your role document for the role-specific application. If you arrived directly, the procedures stand alone - you do not need to read in any particular order.

### Where to go next

* For role-specific applications of these procedures, see [How-to › For Instructors](/how-to-guides/workflows-for-instructors), [How-to › For Students](/how-to-guides/workflows-for-students), or [How-to › For Researchers](/how-to-guides/workflows-for-researchers).
* For the conceptual model behind Instances, snapshots, distribution, and roles, see [Concepts](/concepts/nuvolos-basic-concepts).
* For the technical reference on Applications, storage, data storage, and configuration, see [Reference](/reference/applications).
* For administrative procedures (organisation and Space management, resource monitoring), see [Administration](/administration/user-account-management).


# Accepting an invitation

<mark style="color:$primary;">**Outcome**</mark>\
You accept an invitation to Nuvolos, completing the sign-up if needed, and land in the right place to start working.

<mark style="color:$primary;">**Before you start**</mark>

* You have received an invitation email from your institution's manager, your instructor, or a project lead.
* You know which email address you use (or want to use) for Nuvolos.
* You have decided which identity provider to use for sign-in if this is your first time on Nuvolos - institutional SSO, Google, or Nuvolos.

Nuvolos is an invitation-only platform. Every user - instructor, student, researcher, reviewer, collaborator - joins by accepting an invitation. The click-flow below is identical regardless of the role being granted; what differs is what you can do *after* you accept.

### Accept the invitation

{% stepper %}
{% step %}
Open the invitation email.
{% endstep %}

{% step %}
Click **Review Invitation**. This takes you to Nuvolos in your browser.
{% endstep %}

{% step %}
*Inspect the roles included in the invitation (see Common roles below). The role determines what you can do once inside.*
{% endstep %}

{% step %}
If you have never signed up for Nuvolos, complete the sign-up process now. Use the recommended login option for your institution.
{% endstep %}

{% step %}
Click **Accept Invitation**.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
First-time sign-up may take up to a minute to complete. Wait for the sign-up to finish before clicking anything else.
{% endhint %}

{% hint style="warning" %}
**Login option matters - SWITCH cannot be added later.** For Swiss higher education users, choose the SWITCH option on first sign-in. If you sign up with email and password authentication instead, the SWITCH option will no longer be available for this account. The same applies to other institutional identity providers - pick the one that matches your institution on the first sign-in, not later.
{% endhint %}

### Common roles you might be invited with

* **Member -** typical for students. Cannot create courses or projects.
* **Faculty -** typical for instructors and researchers who manage their own courses or projects.
* **Manager -** Faculty plus organisation-wide management capabilities.
* **Space Administrator** - full privileges within a specific course or project.
* **Instance Editor** - read/write access to a single Instance only; cannot create Instances or invite others.

For the full role and capability matrix, see [Concepts › Roles, secrets and identity](/concepts/roles-secrets-and-identity).

### If you were invited with the wrong email address

Your invitation must be sent to the email address you already use for Nuvolos. If your colleague or instructor sent the invitation to a different address, you cannot accept it with your existing account. Ask them to re-send the invitation to the email address listed under your name in the project's Members list.

{% hint style="info" %}
This is the most common reason an invitation seems "broken". If you click Accept Invitation and end up on a Nuvolos sign-up page even though you already have an account, it almost always means the invitation went to a different email than your account email. Cancel the sign-up and ask the inviter to re-send.
{% endhint %}

### Where you land after accepting

Where the platform takes you depends on what you were invited to:

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Invitation type</strong></td><td valign="top"><strong>Where you land</strong></td></tr><tr><td valign="top">Organisation invitation (Faculty / Manager)</td><td valign="top">Organisation Dashboard. Create your first course or project from here.</td></tr><tr><td valign="top">Course invitation (instructor as TA / co-instructor)</td><td valign="top">Course space, in the Master Instance you were invited to.</td></tr><tr><td valign="top">Course invitation (student)</td><td valign="top">Your personal course instance, with distributed material already present.</td></tr><tr><td valign="top">Research project invitation (Space Administrator)</td><td valign="top">Project space with full access to all instances.</td></tr><tr><td valign="top">Research project invitation (Instance Editor)</td><td valign="top">The single instance you were invited to.</td></tr><tr><td valign="top">Group project invitation (student)</td><td valign="top">The group's shared instance, separate from your personal course instance.</td></tr></tbody></table>

From here, continue with the role-specific onboarding for whichever invitation type you accepted. See the relevant role document for the next steps.


# Starting an application

<mark style="color:$primary;">**Outcome**</mark>\
You launch an application and have it open ready for use.

<mark style="color:$primary;">**Before you start**</mark>

* The application has been added to an Instance you have access to.
* You hold at least the **Instance Editor** role in that instance (applications can only run with Editor rights).
* You are signed in to Nuvolos.

Applications are the interactive tools you use to do your work - JupyterLab, RStudio, MATLAB, VS Code, and others. The procedure below works the same for any role; what differs is who installed the application and where it lives in your space. For the conceptual model, see [Concepts › How Applications work](/concepts/applications).

### Start from the Dashboard

The fastest path when the application has been used recently:

{% stepper %}
{% step %}
Go to the Dashboard of the organisation that contains your course or project.
{% endstep %}

{% step %}
Your three most recently used applications are listed.
{% endstep %}

{% step %}
Click the application name to open it.
{% endstep %}
{% endstepper %}

### Start from your Instance

Use this path the first time you start an application, or when the application is not in your recent list:

{% stepper %}
{% step %}
Navigate to the space containing your instance.
{% endstep %}

{% step %}
Navigate to the instance.
{% endstep %}

{% step %}
Make sure you are in the Current state - applications can only run in the Current state, not in a snapshot view.
{% endstep %}

{% step %}
On the sidebar, click the screen icon (applications) to see the Application list.
{% endstep %}

{% step %}
Click the power button or the application name to start it.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Application startup typically takes 30–60 seconds. The first start may take longer if packages or configuration files need to be initialised. If the first start exceeds about 5 minutes, the cohort or environment may need pre-warming - ask the Space Administrator.
{% endhint %}

### Role-specific notes

{% tabs %}
{% tab title="🎓 For instructors" %}
You start applications in the Master Instance to develop and maintain teaching material. To pre-start applications for an entire student cohort (so students don't all wait at once during a session), see [How-to › For Instructors › Pre-start student Applications](/how-to-guides/workflows-for-instructors/configuring-student-applications#pre-start-student-applications).
{% endtab %}

{% tab title="📖 For students " %}
If your course uses GPU Lab Sessions, your instructor schedules the GPU-enabled application - you don't start it yourself. Hover over the Application icon to confirm GPU is enabled (a green badge with the GPU model appears). See [How-to › For Students › Work with a GPU in a course](/how-to-guides/workflows-for-students/working-with-a-gpu-in-a-course#work-with-a-gpu-in-a-course) for the full distinction between Lab Sessions and On-Demand GPU access.
{% endtab %}

{% tab title="🔬 For researchers" %}
Application startup time matters more for credit-based GPU sizes than for Included sizes - Credit charges start when you click the start button, not when the web UI loads. Make sure you have at least 30 consecutive minutes available before starting a credit-based application.
{% endtab %}
{% endtabs %}


# Stopping an Application

<mark style="color:$primary;">**Outcome**</mark>\
You stop a running application to free resources and (on credit-based sizes) stop accumulating Credit charges.

<mark style="color:$primary;">**Before you start**</mark>

* You have at least one running application you want to stop.

Stopping applications when you are done is good resource hygiene: you free up the resources allocated to your organisation, stop accumulating Credit charges on credit-based sizes, and (in courses) free up application slots for other students. There are four ways to stop an application - pick whichever is convenient.

### Stop from the Dashboard

On the Dashboard, the three most recently used applications are always listed. Hover over the power button - you can enter the instance the application is in, open the application directly, or stop it.

### Stop from the application view of an instance

{% stepper %}
{% step %}
Navigate to the space containing the instance where the application is.
{% endstep %}

{% step %}
Navigate to the instance.
{% endstep %}

{% step %}
Make sure you are on the **Current state**.
{% endstep %}

{% step %}
On the sidebar, click the screen icon (applications) to see the application list.
{% endstep %}

{% step %}
If the power button is green, the application is running. Click the power button to stop it.
{% endstep %}
{% endstepper %}

### Stop from the sidebar

{% stepper %}
{% step %}
Inside the instance with running applications, the sidebar shows icons for all currently running applications.
{% endstep %}

{% step %}
Hover over the application you want to stop.
{% endstep %}

{% step %}
Choose **Stop** from the menu that pops up.
{% endstep %}
{% endstepper %}

### Stop from the Running Applications header menu

{% stepper %}
{% step %}
While you are not inside an application, the top header menu is always visible.
{% endstep %}

{% step %}
Locate the screen icon labelled **Running applications**.
{% endstep %}

{% step %}
The list of your currently running applications opens as a dropdown.
{% endstep %}

{% step %}
Click the **Stop** icon next to the application you want to close.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Student applications are stopped automatically after 1 hour of inactivity. Researcher and instructor applications follow defaults of 6 hours (Included sizes) and 1 hour (credit-based sizes) in research spaces. The auto-stop covers you if you forget - but on credit-based GPU sizes, credits continue to accumulate during the idle hour. Stop explicitly when possible.
{% endhint %}

{% hint style="warning" %}
**For students on GPU Lab Sessions** - do **not** stop your GPU-enabled application yourself during a lab session. The system shuts down all student applications at the end of the session automatically. If you stop it manually during a session, you will not be able to start it again until the next session - this is intentional.
{% endhint %}


# Working with files

<mark style="color:$primary;">**Outcome**</mark>\
You add files to your instance - by upload, Git clone, direct download, or external storage mount.

<mark style="color:$primary;">**Before you start**</mark>

* You hold at least the **Instance Editor** role in the target instance.
* You are in the Current state of the instance - files cannot be modified in a snapshot view.
* You know where your source data currently lives (local machine, Git repository, public URL, or external storage).

Files in Nuvolos live inside an Instance, accessible from the Files view in the sidebar and from inside any application running in that instance. The procedures below work the same way for any role - what differs is the typical use case (instructors uploading teaching materials, students working on assignments, researchers adding code and data).

### Upload files via the web interface

The simplest path for individual files:

{% stepper %}
{% step %}
Navigate to the space and instance where you want the file.
{% endstep %}

{% step %}
On the sidebar, click the folder icon to open the Files view.
{% endstep %}

{% step %}
On the top left, click **UPLOAD** and choose your file.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
The web UI uploads individual files. To upload a folder, compress it locally first (`.zip` or `.tar.gz`), upload the archive, then extract it from the ... Actions menu in the Files view. Supported archive formats include `zip`, `tar`, `tar.gz`, `bz2`, and `tgz`.
{% endhint %}

### Clone a Git repository

Best when your code is already version-controlled. Open a terminal in any application and clone normally:

<pre class="language-sql" data-overflow="wrap"><code class="lang-sql"><strong>git clone &#x3C;repository-url>
</strong></code></pre>

If the repository is private, generate an SSH key inside the application and add the public key to the repository's accepted keys. The Nuvolos-generated key persists in the Instance, so cloning continues to work for future sessions.

### Download directly from the internet

Skip your local machine when the data is already at a public URL. From a terminal in any application:

{% code overflow="wrap" %}

```sql
wget <url>
```

{% endcode %}

You can also use curl, or any API call from a Python or R script that downloads to disk. The `wget` command is available in every Nuvolos application by default.

### Mount external storage

If your data lives in cloud storage you already use, mount it as a folder in your instance rather than copying. Most well-known storage services are supported via [rclone](https://rclone.org/overview/):

* Amazon S3
* Azure files
* Dropbox
* Google Drive
* Box
* SharePoint Online

Setup uses the [rclone mount add-on](/reference/applications/add-ons/rclone-mount-add-on). For specific guidance on the more common services, see the dedicated reference pages: [Dropbox](/reference/file-system-and-storage/mount-dropbox), [S3 buckets](/reference/file-system-and-storage/access-s3-buckets-with-rclone), [SSHFS](/reference/file-system-and-storage/access-remote-files-with-sshfs), and [SharePoint Online](/reference/file-system-and-storage/access-files-on-sharepoint-online).

### Larger datasets

For datasets that don't fit comfortably on the per-instance file system (typically above 100 GB), see [Reference › File Storage](/reference/file-system-and-storage/large-file-storage) for Large File Storage.


# Snapshots

Snapshots are immutable, point-in-time copies of an instance's Current state. For the conceptual model of snapshots, distribution, and states, see [Concepts › Snapshots, distribution, and states](/concepts/distribution).

This section covers the practical actions you can perform with snapshots:

* [Create a snapshot](/how-to-guides/common-workflows/snapshots/create-a-snapshot) - save the Current state of an instance as an immutable record (quick or detailed).
* [Restore from a snapshot](/how-to-guides/common-workflows/snapshots/restore-a-snapshot) - replace the Current state of an instance with the contents of a snapshot, either in the same Instance or a different one.&#x20;
* [Delete a snapshot](/how-to-guides/common-workflows/snapshots/delete-a-snapshot) - permanently remove a snapshot to free up storage.&#x20;
* Distribute from a snapshot - push selected files, tables, or applications from a snapshot to another location using object distribution. This allows partial restores or sharing specific artefacts without overwriting an entire instance.&#x20;


# Create a snapshot

<mark style="color:$primary;">**Outcome**</mark>\
You preserve the complete Current state of an instance - files, tables, and application configurations - as an immutable, time-stamped record.

<mark style="color:$primary;">**Before you start**</mark>

* You are in the Current state of the instance you want to snapshot.
* You hold the **Instance Editor** role or higher in the instance.
* All work you want to preserve has been saved (snapshots capture what is on disk, not what is in memory).

A snapshot captures the complete Current state of an instance as an immutable, time-stamped record. There are two ways to create one:

* **Quick snapshot** - captures the Current state with the timestamp as the snapshot name. Use this when you want a safety net before a risky operation and don't need to find the snapshot by name later.
* **Detailed snapshot** - captures the Current state with a user-provided name and description. Use this when you want a named record of a meaningful state ("end of term", "v1.0 final analysis", "before final submission") that you can find later by name.

### **Create a quick snapshot**

{% stepper %}
{% step %}
Navigate to the space containing the instance.
{% endstep %}

{% step %}
Make sure you are viewing the Current State of an instance.
{% endstep %}

{% step %}
From the left sidebar, hover on the camera icon, click the **+** (plus) icon and select **QUICK SNAPSHOT**.
{% endstep %}
{% endstepper %}

### Create a detailed snapshot

{% stepper %}
{% step %}
Navigate to the space containing the instance.
{% endstep %}

{% step %}
Make sure you are viewing the current state of an instance.
{% endstep %}

{% step %}
From the left sidebar, hover on the camera icon, click the **+** (plus) icon and select **TAKE SNAPSHOT AND DESCRIBE**.
{% endstep %}

{% step %}
Fill in the snapshot name and description form. Snapshot names need to be unique in an instance.
{% endstep %}

{% step %}
Click **+ ADD SNAPSHOT**.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Snapshots are created almost instantaneously. Refresh the page before creating another snapshot - the UI may otherwise prevent the second creation.
{% endhint %}

### Role-specific notes

{% tabs %}
{% tab title="🎓 For instructors" %}
Date- or term-based names work well for course archives ("2025-spring-final", "end-of-term-stats101"). Detailed snapshots are worth the extra effort here because you'll be looking for them next term when reusing the course.
{% endtab %}

{% tab title="📖 For students" %}
Quick snapshots are usually sufficient. Take one before starting an assignment session and another before submitting. If you take a detailed snapshot, descriptive task-based names ("before final submission", "after Tuesday's lab") are easier to identify than dates.
{% endtab %}

{% tab title="🔬 For researchers" %}
Detailed snapshots representing stable, citable states of the data or analysis are often called vintages - convention from the Nuvolos team. Names like "v1.0 - final analysis 2026-05" make snapshots easy to reference in handovers and papers.
{% endtab %}
{% endtabs %}


# Restore a snapshot

<mark style="color:$primary;">**Outcome**</mark>\
You replace the Current State of an instance with the contents of a snapshot - fully, partially, or to a different target.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the **Instance Editor** role in the target instance (Viewers can read snapshots but cannot restore from them).
* The snapshot you want to restore from is available in the timeline.
* You have decided whether to restore to the same instance, to a different Instance, or only specific items.

Restoring a snapshot replaces the Current State of an instance with the contents of the snapshot. If you don't have Editor rights on the target instance, ask an Instance Editor to either restore for you or [distribute](/concepts/distribution#distribution-the-push-mechanism) the snapshot to your instance.

{% hint style="info" %}
Before any restore, Nuvolos automatically creates a safety snapshot of the target Instance's Current state. This means you can always revert the restore if it turns out to be the wrong move.
{% endhint %}

### Restore to the same instance

The most common case - bring this Instance back to a previous state.

{% stepper %}
{% step %}
Navigate to the space containing the instance.
{% endstep %}

{% step %}
Navigate to the instance.
{% endstep %}

{% step %}
Open the snapshot timeline view by hovering over the camera icon on the sidebar and clicking **SNAPSHOTS**.
{% endstep %}

{% step %}
Identify the snapshot you want to restore.
{% endstep %}

{% step %}
Click the blue restore icon under Actions.
{% endstep %}

{% step %}
Confirm the operation.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
A green padlock icon next to a snapshot in the timeline indicates the snapshot has no separate backup copy. The restore procedure is the same; the icon is informational.
{% endhint %}

### Restore to a different instance

Use this when you want a fresh instance pre-populated with a known-good state - for example, when onboarding a new team member or spawning a parallel exploration.

The limitation: the target instance has to be in the same space as the snapshot. If you need to restore to a different space, use the partial restore technique below, which uses distribution.

{% stepper %}
{% step %}
Navigate to the space containing the source instance.
{% endstep %}

{% step %}
Navigate to the Instance that holds the snapshot.
{% endstep %}

{% step %}
Open the snapshot timeline view by hovering over the camera icon on the sidebar and clicking **SNAPSHOTS**.
{% endstep %}

{% step %}
Identify the snapshot you want to restore to somewhere else.
{% endstep %}

{% step %}
Click the two-persons icon under **Actions**.
{% endstep %}

{% step %}
Select the target instance - you must be an Instance Editor of the target, and the target must be in the same space.
{% endstep %}

{% step %}
Confirm the operation.
{% endstep %}
{% endstepper %}

### Partially restore from a snapshot

You can selectively recover specific files, tables, or applications from a snapshot without overwriting the entire Current State. This uses the distribution feature, and unlike full restore, can target an instance in a different space.

{% stepper %}
{% step %}
Navigate to the space containing the instance.
{% endstep %}

{% step %}
Navigate to the instance that holds the snapshot.
{% endstep %}

{% step %}
Open the timeline view of snapshots and click the snapshot name to open it.
{% endstep %}

{% step %}
Stage the objects (files, tables, or applications) you want to restore.
{% endstep %}

{% step %}
Open the distribution flow and select the target instance - this can be the same instance, or any instance you have Editor access to (including in other spaces).
{% endstep %}

{% step %}
Select the **Overwrite** distribution strategy.
{% endstep %}

{% step %}
Complete the distribution.
{% endstep %}
{% endstepper %}

The selected objects in the target instance's Current State are replaced with the versions from the snapshot. Other files in the target instance are left alone.

For the full distribution mechanic and all four distribution strategies, see [Reference › Configuration](/reference/configuration).

### Role-specific notes

{% tabs %}
{% tab title="📖 For students" %}
In archived courses, restoring a snapshot to the Current State gives you a 3-day grace period to access the data before the instance is re-archived automatically. You can repeat the restore as many times as needed. See [How-to › For Students › Work with an archived course](/how-to-guides/workflows-for-students/working-with-archived-courses) for the full lifecycle.
{% endtab %}

{% tab title="🔬 For researchers" %}
Restoring a named vintage snapshot is the canonical way to begin a reproduction attempt. See [Tutorials › For Researchers › Reproducing a colleague's research project](/tutorials/tutorials-for-researchers/reproducing-a-colleagues-research-project) for the full reproduction workflow including verification.
{% endtab %}
{% endtabs %}


# Delete a snapshot

<mark style="color:$primary;">**Outcome**</mark>\
You permanently remove a snapshot you no longer need, freeing up the storage it referenced.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the **Instance Editor** role or higher in the instance.
* You have confirmed you no longer need the snapshot - deletion is permanent.
* You understand that data only stored in this snapshot (and nowhere else) will be permanently lost.

Snapshots are immutable - they cannot be partially modified or selectively cleaned up. If you delete a file or table from the Current State, the data is not freed up as long as it still exists in at least one snapshot. To reclaim that storage, you must delete every snapshot that contains the data. For the underlying reasoning, see [Concepts › Snapshots, distribution, and states](/concepts/distribution).

### Delete a snapshot

{% stepper %}
{% step %}
Navigate to the space containing the instance.
{% endstep %}

{% step %}
Navigate to the instance.
{% endstep %}

{% step %}
Open the snapshot timeline view by hovering over the camera icon on the sidebar and clicking **SNAPSHOTS**.
{% endstep %}

{% step %}
Identify the snapshot you want to delete.
{% endstep %}

{% step %}
Click the bin icon next to the snapshot name.
{% endstep %}

{% step %}
Confirm the operation by clicking **I UNDERSTAND**, then **DELETE SNAPSHOT**.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Once deleted, a snapshot cannot be recovered. If the snapshot is the only place the data still exists - i.e. the data has been removed from the Current State and from all other snapshots - the data is gone for good. Take a fresh snapshot of anything you still need before deleting old ones.
{% endhint %}

{% hint style="info" %}
If you experience issues when deleting a snapshot, please refer to the [troubleshooting guide](/troubleshooting/troubleshooting/administration-troubleshooting/i-cant-delete-a-snapshot).
{% endhint %}


# Requesting roles

<mark style="color:$primary;">**Outcome**</mark>\
You submit a role request for content you can see but cannot interact with, and track it through approval.

<mark style="color:$primary;">**Before you start**</mark>

* You can see the dataset or space but cannot view its contents.
* You understand that an **Organisation Manager** or **Space Administrator** will review your request - it is not automatic.

If you need access to a course, research project, or dataset you can see but can't interact with, you can submit a role request. The most common case is requesting the Viewer role for a public dataset where you currently hold only the Observer role.

### Request a Viewer role for a public dataset

{% stepper %}
{% step %}
Open the dataset from the toolbar menu.
{% endstep %}

{% step %}
Click **REQUEST ROLE** on the overview page.
{% endstep %}
{% endstepper %}

Once submitted, an Organisation Manager will review the request. You can view the dataset once your request is approved.

### Cancel a pending request

If you change your mind about a request, you can withdraw it as long as it is still pending.

{% stepper %}
{% step %}
Open the notifications icon in the toolbar.
{% endstep %}

{% step %}
Find your request in the **REQUESTS SUBMITTED** section.
{% endstep %}

{% step %}
Click the red cancel button to withdraw the request.
{% endstep %}
{% endstepper %}

### Track your requests

Use the notifications icon in the toolbar to see two types of requests:

* Requests you have submitted - waiting for approval.
* Requests requiring your approval - only relevant if you have manager privileges. See [Administration › Organisation administration](/administration/organisation-management) for the approver workflow.

Other useful filters in the requests view:

* Colour-coded mail checkboxes filter requests (for example, show only pending requests).
* Username and organisation filters help you find specific requests quickly.


# Distribution

<mark style="color:$primary;">**Outcome**</mark>\
You push files, tables, or applications from a source instance to one or more target instances using the staging-and-distribute click-flow.

<mark style="color:$primary;">**Before you start**</mark>

* You hold at least **Instance Viewer** in the source instance and **Instance Editor** in the target.
* You are in the Current State (or in a snapshot view if you are distributing from a snapshot) of the source.
* You have decided which distribution strategy to use - Overwrite, Distribute Extra, Mirror, or Skip. See [Reference › Configuration](/reference/configuration) for the four strategies.

Distribution is how content moves between Instances on Nuvolos - files, tables, applications, or any combination. The same mechanical click-flow applies regardless of the source and target. This page documents the mechanic; the role-specific applications (who you distribute to, why, and what strategy to use) are covered in the role-specific documents.

You can distribute the following object types:

* Files, sets of files, or entire directories
* Tables or sets of tables
* Applications or sets of applications
* Entire snapshots

## Distributing a selected list of items

You can distribute a set of items from a single instance using the **Stage** - a temporary area for collecting objects to be distributed. To distribute from multiple sources, you must initiate a separate distribution from each source.

The procedure:

{% stepper %}
{% step %}
Navigate to the source instance and the Current State.
{% endstep %}

{% step %}
On the sidebar, click **Files**. Select the file you want to distribute and click **STAGE**.&#x20;

You can also do mass operations on the action item row about the file list table in the vertical ... menu.
{% endstep %}

{% step %}
*(Optional) On the sidebar, click Applications. Select the application you want to distribute and stage it.*
{% endstep %}

{% step %}
*(Optional) On the sidebar, click Tables. Select the tables you want to distribute, and stage them.*
{% endstep %}

{% step %}
On the sidebar, click the share icon to open the **Stage**.
{% endstep %}

{% step %}
Review your staged objects - you can remove items using the red "X" button - and click **CONTINUE**.

*(Optional) Save the staged objects as a **named bundle** for future reference. Useful if you plan to re-run the same distribution later - you can re-distribute the bundle without re-staging individual items.*
{% endstep %}

{% step %}
Select the target for distribution. You can distribute within the current space, to another space, or to another organisation. You can also choose whether to share with all instances (education-only) or just one. Click **CONTINUE**.
{% endstep %}

{% step %}
*(Optional) Enable notifications - Nuvolos can send a notification email to recipients on completion with a custom message. The message notifies all users in the target instances about a distribution having completed.*
{% endstep %}

{% step %}
Select the distribution strategy. **Overwrite** is the default and almost always the correct choice.
{% endstep %}

{% step %}
*(Optional) Create a snapshot in the target before distribution to guard against data loss.* Click **CONTINUE**.
{% endstep %}

{% step %}
Review the list of items and click **SHARE OBJECTS**.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Selecting a folder adds the entire file tree recursively. If a sub-folder is selected, the folder structure above it is created so paths match across all targets. Recently used Applications are auto-added to the distribution - remove them before continuing if you didn't intend to include them.
{% endhint %}

{% hint style="warning" %}
Distribution runs in the background. You will receive an email when it completes. If it fails, contact <support@nuvolos.cloud>. For large Application images, allow at least an hour before any time-sensitive deadline (such as an instructor distributing before a live lab session, or a researcher refreshing a dataset for collaborators).
{% endhint %}

### Role-specific notes

This page covers only the mechanical click-flow. For role-specific applications:

{% tabs %}
{% tab title="🎓 For instructors" %}
See [How-to › For Instructors › Distribute teaching material](/how-to-guides/workflows-for-instructors/distribute-to-prospective-students) for the cohort-distribution workflow including current and future student instances, and [Tutorials › Running a data-heavy lab session](/tutorials/tutorials-for-instructors/running-a-data-heavy-lab-session) for the live lab-session pattern.
{% endtab %}

{% tab title="📖 For students " %}
Students are typically recipients of distribution rather than initiators. The mechanic is the same when distributing within a group instance, but the typical use case is the receiving end.
{% endtab %}

{% tab title="🔬 For researchers" %}
See [How-to › For Researchers › Create alternate Instances](/how-to-guides/workflows-for-researchers/create-alternate-approaches) for cross-instance distribution, and [How-to › For Researchers › Set up a dataset](/how-to-guides/workflows-for-researchers/setting-up-a-dataset-on-nuvolos) for distributing to a dataset space.
{% endtab %}
{% endtabs %}


# Recalling files

If a file, folder, table or even application is accidentally distributed, **Space Administrators** can remove it from other instances.

### Recalling from the Master instance

{% stepper %}
{% step %}
Navigate to the space containing the instance you distributed from.
{% endstep %}

{% step %}
Navigate to the Master instance.
{% endstep %}

{% step %}
On the sidebar, click Files and locate the file or folder you want to recall.
{% endstep %}

{% step %}
Click ... in the Actions column of the object list.
{% endstep %}

{% step %}
Select **DELETE FOR OTHERS** to delete the file from all instances except the Master, or **DELETE FOR ALL** to delete it from all instances including the Master.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
**DELETE FOR ALL** only affects the current state of each instance. Existing snapshots are not modified - the object remains available in any snapshot taken before the deletion. This also means the storage hold is only released once all containing snapshots are also removed from the system.
{% endhint %}

### Recalling from the Distributed or student instances

{% stepper %}
{% step %}
Navigate to the space.
{% endstep %}

{% step %}
Navigate to the **Distributed instance** (or the relevant student instance).
{% endstep %}

{% step %}
On the sidebar, click **Files** and locate the file or folder you want to recall.
{% endstep %}

{% step %}
Click ... in the Actions column of the object list.
{% endstep %}

{% step %}
Select **Delete for students** to remove the file from all current and future student instances. This creates a new snapshot in the Distributed instance with the selected files removed.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
To recall accidentally distributed files, trigger the **DELETE FOR OTHERS/DELETE FOR STUDENTS** action **after** the distribution has finished. Otherwise, the deletion task might execute before the distribution task and have no effect.
{% endhint %}


# Inviting users

<mark style="color:$primary;">**Outcome**</mark>\
You invite a user to a space, either to a specific instance with a non-administrative role or to the whole space as an Administrator.

<mark style="color:$primary;">Before you start</mark>

* You hold the **Space Administrator** role in the space (the creator of a space automatically has this role).
* You have the email addresses of the users you want to invite.
* You have decided what to invite them to - an individual instance, a shared instance, or the whole space as Administrator.

Inviting a user to a Nuvolos space follows the same click-flow regardless of who you are inviting and why. This page documents the mechanic; the role-specific framing - what you invite people for, whether they get an individual or shared instance, what role to assign - is covered in the role-specific documents.

### The procedure

{% stepper %}
{% step %}
Navigate to the space (course or project) you want to invite the user to.
{% endstep %}

{% step %}
From the sidebar, click the More options menu (⋯) next to the selected Space name, choose **Invite Users**.
{% endstep %}

{% step %}
Choose between the two invitation options (see below).
{% endstep %}

{% step %}
For Option 1, additionally choose whether to invite to an existing shared Instance or create individual Instances per invitee.
{% endstep %}

{% step %}
Choose the invitation method (invite link or email).
{% endstep %}

{% step %}
Click **INVITE**.
{% endstep %}
{% endstepper %}

### Invitation options

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Option</td><td valign="top">What it does</td></tr><tr><td valign="top">Option 1 - User Invitation</td><td valign="top">Invites the user to a specific instance with a non-administrative role. You pick the instance and the role (typically Instance Editor).</td></tr><tr><td valign="top">Option 2 - Administrator Invitation</td><td valign="top">Invites the user as a Space Administrator with full privileges across the entire space. They can see all instances, invite further users, and create new instances.</td></tr></tbody></table>

Individual instances are typical for course students. Shared instances are typical for group members and co-authors on a research project.

### Invitation methods

* **Invite link** - share a URL; anyone who clicks it joins. Easiest for larger cohorts.
* **Email -** enter specific email addresses. Better for targeted invitations.

{% hint style="warning" %}
When inviting users who already have a Nuvolos account, use the email address listed under their name in the Members list of any space they are already in. If you send the invitation to a different address, they will not be able to accept it with their existing account - they will be forced to create a new one.
{% endhint %}

### Role-specific notes

This page covers only the mechanical click-flow. For role-specific applications:

{% tabs %}
{% tab title="🎓 For instructors" %}
See [How-to › For Instructors › Invite students](/how-to-guides/workflows-for-instructors/invite-students) for cohort-scale invitations with individual instances per student, and [How-to › For Instructors › Invite teaching assistants and co-instructors](/how-to-guides/workflows-for-instructors/invite-tas) for Administrator invitations.
{% endtab %}

{% tab title="📖 For students " %}
Students typically don't invite other users. The exception is when a student Space Administrator on a group project needs to invite an additional group member; the procedure is the same as above.
{% endtab %}

{% tab title="🔬 For researchers" %}
See [How-to › For Researchers › Invite collaborators](/how-to-guides/workflows-for-researchers/invite-collaborators) for Administrator vs. Instance Editor decisions for co-authors, and [How-to › For Researchers › Invite an external reviewer](/how-to-guides/workflows-for-researchers/inviting-a-reviewer) for the snapshot-and-Instance-Editor pattern for journal reviewers.
{% endtab %}
{% endtabs %}


# Workflows for Instructors

These guides answer the question *"how do I do X?"* for instructors who already have working familiarity with Nuvolos. If you are new to the platform, start with the [Instructor tutorials](/tutorials/tutorials-for-instructors) first - they take you from creating your first course to seeing assignments come back from students.

The guides are organised by where you are in your course lifecycle:

* **Course setup** - create the course, structure it, add teaching material, document it.
* **Manage students, TAs, and groups** - invite students and co-instructors, distribute material, set up group projects, enable collaborative editing.
* **Configure course tools and resources** - pre-start and schedule applications, configure them for students, manage performance for large concurrent classes.
* **GPU courses** - enable GPU access, schedule Lab Sessions, set up On-Demand GPU access with Credit quota schedules.
* **Assignments, grading, and feedback -** create assignments, set hand-in limits, grade, provide feedback, export grades, automate with programmatic grading.
* **End-of-course tasks** - archive a course, prepare for the next term, reuse teaching material.

Each page assumes you can navigate Nuvolos's Dashboard, sidebar, and breadcrumbs. If anything in the interface is unfamiliar, see [Getting Started › Find your way around](/getting-started/find-your-way-around).

### Where to go next

* For step-by-step walk-throughs of the most common instructor workflows (first course, data-heavy lab session, reusing a course), see [Instructor tutorials](/tutorials/tutorials-for-instructors).
* For procedures every role shares (invitations, Applications, snapshots, distribution), see [How-to › Common Workflows](/how-to-guides/common-workflows).
* For the technical reference on Applications, storage, data storage, and configuration, see [Reference](/reference/applications).
* For the conceptual model behind Instances, snapshots, distribution, and roles, see [Concepts](/concepts/nuvolos-basic-concepts).


# Join an organisation

## Join an organisation as an instructor

<mark style="color:$primary;">**Outcome**</mark>\
You accept an organisation-level invitation and gain the Faculty or Manager role required to create your own courses.

<mark style="color:$primary;">**Before you start**</mark>

* A Manager in your organisation (typically a department head or lab admin) has sent you an invitation.
* You know which identity provider you want to use to sign in (institutional SSO, Google, or Nuvolos).

Instructors are invited in one of two ways: to a specific course space (if you are a co-instructor or TA - see the next page) or to an entire organisation (if you will create and manage your own courses). This page covers the organisation-level case.

#### **Roles to look for in the invitation**

To create and manage your own courses, you need one of these roles:

* **Faculty** - the standard role for instructors. Lets you create courses, enroll students, and manage course environments.
* **Manager** - has all Faculty permissions and can additionally manage organisation settings and invite other Faculty members.

If your invitation grants only the Member role, you cannot create courses. Contact the inviter and ask for a Faculty role instead. For the full role definitions, see [Concepts › Roles](/concepts/roles-secrets-and-identity/roles).

#### **Accept the invitation**

The procedure for accepting any Nuvolos invitation is the same regardless of the role. See the canonical procedure: [How-to › Common Workflows › Accepting an invitation](/how-to-guides/common-workflows/accepting-an-invitation).

## Join a course as a co-instructor or TA

<mark style="color:$primary;">**Outcome**</mark>\
You accept an invitation to an existing course as a Space Administrator, gaining full control over the course space.

<mark style="color:$primary;">**Before you start**</mark>

* The course creator has sent you an invitation.
* You have read the invitation and confirmed it grants the Space Administrator role.

A course is always created by one user, and additional instructors join only by invitation. The acceptance flow is identical to any other Nuvolos invitation - see [How-to › Common Workflows › Accepting an invitation](/how-to-guides/common-workflows/accepting-an-invitation).

{% hint style="info" %}
Check the role in the invitation before accepting. Co-instructors and TAs typically need the Space Administrator role, which gives them full control over the course Space - including visibility of all student Instances, the ability to distribute materials, and the ability to invite further users.
{% endhint %}


# Create a new course

<mark style="color:$primary;">**Outcome**</mark>\
You create a new course space, ready to receive teaching material and student invitations.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the **Organisation Manager** or **Organisation Faculty** role.
* You have a name and description in mind for the course.

**Create the Space**

{% stepper %}
{% step %}
Navigate to the Dashboard.
{% endstep %}

{% step %}
Click the **+** (plus) icon next to the Spaces list, or click the **+ SPACE** button in the Recent Spaces section at the bottom of the Dashboard.
{% endstep %}

{% step %}
From the dropdown menu, select **Course**.
{% endstep %}

{% step %}
&#x20;Enter the course name and description. Optionally, add a `README` file.
{% endstep %}

{% step %}
**Select + ADD SPACE.**
{% endstep %}

{% step %}
Optionally, select an application to add to the Master Instance of the new course. You can do this later if you prefer.
{% endstep %}

{% step %}
If you selected an Application, give it a name and click + INSTALL.
{% endstep %}
{% endstepper %}

For full space management options - including cloning spaces and Git repositories - see [Administration › Space management](/administration/space-management).


# Add teaching material

<mark style="color:$primary;">**Outcome**</mark>\
You upload course files, code, or data into the Master Instance, where you will work on them before distributing to students.

<mark style="color:$primary;">**Before you start**</mark>

* You are a Space Administrator of the course (creators automatically receive this role).
* You have the material ready to upload from your local machine.

You always work in the **Master Instance** - a private working environment dedicated to developing and maintaining teaching material. The Master Instance is not visible to students by default. Once material is ready, you distribute it from the Master Instance to all students in one operation.

#### **Upload files via the web UI**

{% stepper %}
{% step %}
Navigate to the course and confirm in the breadcrumbs that you are in the correct Space.
{% endstep %}

{% step %}
Navigate to the Master Instance.
{% endstep %}

{% step %}
Make sure you are in the Current state.
{% endstep %}

{% step %}
On the sidebar, click the folder icon to open the Files view.
{% endstep %}

{% step %}
Click UPLOAD in the top left and select files from your local machine.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
To upload folders, compress them locally first (as .zip or .tar.gz), upload the archive, then extract it from the ... Actions menu in the Files view. Supported formats include zip, tar, tar.gz, bz2, and tgz.
{% endhint %}

For all available file operations (upload, download, extract, preview, edit), see [Reference › File storage](/reference/file-system-and-storage).


# Structure your course

<mark style="color:$primary;">**Outcome**</mark>\
You set up the course's Instance layout in the way that best matches your teaching style and the kind of work students will do.

<mark style="color:$primary;">**Before you start**</mark>

* You are a Space Administrator of the course.
* You have a sense of whether students will work individually, in groups, or both.

A course in Nuvolos is a space containing multiple instances. As a Space Administrator you control how many instances exist and which students can access each one. Your layout decisions determine how material flows between instructors and students and how much isolation each participant has. For the conceptual model, see [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

#### Suggested layout

The recommended setup for most courses:

* **Master Instance** - the single place where all instructors (you and your TAs) develop, edit, and maintain teaching material. When material is ready, you distribute it from here. The Space Administrator role gives all instructors full control of this Instance.
* **Distributed Instance** - a special Instance that accumulates everything distributed. New student Instances are spawned from it, so late joiners automatically receive all previously distributed material.
* **One Instance per student** - each student works in their own isolated Instance with the Instance Editor role, so they can modify files and run applications without affecting anyone else. Students also automatically receive Instance Viewer access on the Distributed Instance, which lets them pull material into their own Instance if needed.
* **Group work in a separate space** - see [Set up group projects](/how-to-guides/workflows-for-instructors/setting-up-group-projects) below. Keeping group and individual material in separate Spaces prevents the two threads from tangling.

This layout keeps material development centralised, gives each student an isolated working environment, and makes the distribution flow predictable: **Master → Distributed Instance → Student Instances**.

#### Alternate layout - separate instructor Instances

When multiple instructors develop material in parallel and want to avoid editing the same files simultaneously, an alternate setup uses separate Instances per instructor instead of sharing the Master Instance. The Master Instance and the per-instructor Instances all have Space Administrator role.

{% hint style="info" %}
This layout avoids file-editing collisions in the Master Instance, but distributions become more complex - multiple instructors distributing to the same target may overwrite each other's work. Establish clear agreements about who distributes what, and when, before adopting this layout.
{% endhint %}


# Document your course

<mark style="color:$primary;">**Outcome**</mark>\
You add a `README.md` file to your course that students see automatically on the space overview, with links and embedded video.

<mark style="color:$primary;">**Before you start**</mark>

* You are an **Instance Editor** or **Space Administrator**.
* You are in the **Current state** of the **Master Instance**.

Any folder in Nuvolos can contain a `README.md` file that is rendered automatically as Markdown by the web UI. The top-level `README.md` in the Master Instance is also displayed on the space overview, making it the natural home for course-level documentation.

#### Edit a README from the web UI

{% stepper %}
{% step %}
Open the Files view of the Master Instance.
{% endstep %}

{% step %}
Upload or locate the `README.md` file you want to edit.
{% endstep %}

{% step %}
In the ... Actions menu on the file row, choose **EDIT**.
{% endstep %}

{% step %}
Use the WYSIWYG or source-code editor to write your content in Markdown.
{% endstep %}

{% step %}
Save your changes.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
You can embed videos from streaming providers directly in the README by pasting the embed snippet they provide. This is useful for keeping a running log of recorded lectures that students can review.
{% endhint %}

For full Markdown features supported by Nuvolos - including links to headings via the Anchor button - see [Reference › File storage](/reference/file-system-and-storage).


# Invite students

<mark style="color:$primary;">**Outcome**</mark>\
You invite your students to the course, with each student receiving their own individual instance.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the course.
* Your teaching materials are set up in the Master Instance and ready to be distributed.

#### **Send the invitations**

{% stepper %}
{% step %}
Navigate to the course space.
{% endstep %}

{% step %}
From the sidebar, click the More options menu (**⋯**) next to the selected Space name, choose **Invite Users**.

The default is **User Invitation** with **Invite to individual instances** - this creates a separate Instance for each student so they can work independently.
{% endstep %}

{% step %}
Choose between invitation methods (see below).
{% endstep %}
{% endstepper %}

#### **Invitation method**

<table><thead><tr><th width="159.8333740234375">Method</th><th>When to use</th></tr></thead><tbody><tr><td><strong>Invite link</strong></td><td>Easiest for larger cohorts - share one link, anyone who clicks it joins.</td></tr><tr><td><strong>Email</strong></td><td>Better for smaller courses where you want to invite specific students by name.</td></tr></tbody></table>

For all space-level invitation options (including invitation links with expiry), see [Administration › Space management](/administration/space-management).


# Invite teaching assistants and co-instructors

<mark style="color:$primary;">**Outcome**</mark>\
You invite TAs and co-instructors as Space Administrators, giving them full visibility and management of the course.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the course.
* You have a list of email addresses for the colleagues to invite.

#### Send administrator invitations

{% stepper %}
{% step %}
Navigate to the course space.
{% endstep %}

{% step %}
From the sidebar, click the More options menu (**⋯**) next to the selected Space name, choose **Invite Users**.
{% endstep %}

{% step %}
Switch to **Option 2 - Administrator Invitation**.
{% endstep %}

{% step %}
Enter the email addresses of the colleagues or assistants you want to invite.
{% endstep %}

{% step %}
Click **+ INVITE**.
{% endstep %}
{% endstepper %}

Space Administrators have full visibility over every Instance in the course, including the Master Instance and all student Instances.


# Distribute teaching material

<mark style="color:$primary;">**Outcome**</mark>\
You distribute files, tables, or applications from your Master Instance to every student in the course - including students who join later.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the course.
* The objects you want to distribute exist in the Current state of the Master Instance.
* You have decided whether to create an Assignment from this distribution (or not).

Distribution sends teaching material to every instance in the course - both existing student instances and any instance created in the future via the Distributed Instance. For the conceptual model, see [Concepts › Snapshots, distribution, and states](/concepts/distribution).

#### Stage and distribute

{% stepper %}
{% step %}
Navigate to the course and the Master Instance.&#x20;

Make sure you are in the Current state.
{% endstep %}

{% step %}
On the Files, Tables, or Applications view, select the items to distribute and click **STAGE** or **STAGE SELECTED**.
{% endstep %}

{% step %}
On the sidebar, click the share icon to open the Stage.
{% endstep %}

{% step %}
Review your staged objects.&#x20;

Recently used Applications are auto-added - you can remove them before continuing.
{% endstep %}

{% step %}
Click **CONTINUE**.
{% endstep %}

{% step %}
*Optionally save the list as a named bundle for future reference, or create an Assignment from it (see Setting assignments below).*
{% endstep %}

{% step %}
Select the target - by default, all students (every existing Instance and every future Instance).
{% endstep %}

{% step %}
Optionally enable a notification email with a custom message, sent to students on completion.
{% endstep %}

{% step %}
Choose the distribution strategy.&#x20;

Overwrite is the default and almost always the correct choice.
{% endstep %}

{% step %}
Review the list of items being shared.&#x20;

Note that distributing large applications can take several minutes.
{% endstep %}

{% step %}
Click **SHARE OBJECTS**.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Selecting a folder adds the entire file tree recursively. If you stage only a sub-folder, the folder structure above it is created so paths match across all student Instances.
{% endhint %}

For the full distribution mechanic, including all four distribution strategies (Overwrite, Distribute Extra, Mirror, Skip), see [Reference › Configuration](/reference/configuration).


# Set up group projects

<mark style="color:$primary;">**Outcome**</mark>\
You set up a separate group-work space with one instance per group, and group members are invited as Instance Editors.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the Organisation Faculty or Organisation Manager role (required to create a new space). If you are a TA without those rights, ask the course instructor to create the space for you.
* You have a list of group memberships (which students belong to which group).
* You have decided whether to use shared editing (most reliable in JupyterLab 4.0.0 or later - see *Collaborative editing in JupyterLab* below).

Group projects work best as a **separate space** from regular coursework. Distributing two threads of workflows on top of each other tangles individual and group work - keeping them apart prevents that. The space hierarchy for group projects looks like this:

* A **group-work space** containing one instance per group.
* A **regular coursework space** with one instance per student.
* Students see both spaces in their Dashboard.

### Create the group-work Space

Follow the procedure in [Create a new course](/how-to-guides/workflows-for-instructors/create-a-new-course), but give it a name that clearly distinguishes it from the regular coursework space (for example: *Statistics 101 — Group Work*).

### Create one Instance per group

For each group, create an instance and invite its members as editors.

{% stepper %}
{% step %}
Navigate to the group-work space.
{% endstep %}

{% step %}
Click the **+** (plus) icon next to the Instances list to create a new Instance.
{% endstep %}

{% step %}
Choose whether to start from a snapshot or create an empty instance.
{% endstep %}

{% step %}
Name the instance after the group.
{% endstep %}
{% endstepper %}

### Invite group members as Instance Editors

{% stepper %}
{% step %}
Open the **Instances** tab.
{% endstep %}

{% step %}
Find the group Instance you just created and click **+ USERS**.
{% endstep %}

{% step %}
Select **Option 1 - User Invitation** and **Invite to an existing shared instance**.
{% endstep %}

{% step %}
Choose **Instance Editor** as the role.
{% endstep %}

{% step %}
Enter the email addresses of the group members and click **INVITE**.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
When entering email addresses for users already on Nuvolos, use the email listed under their name in the Members list. If the invitation is sent to a different email, the student will not be able to accept it with their existing Nuvolos account.
{% endhint %}

### Upload files and distribute

Once the space and instances are in place, upload group-work files to the Master Instance of the group-work space and distribute as usual. Since group and individual workspaces are separate, new groups added later can also be initialised from the Distributed Instance.

As the course proceeds, you can use cumulative distribution to push new material to all group instances, and you can bridge information between regular and group-work spaces via cross-distributing between spaces.


# Collaborative editing in JupyterLab

<mark style="color:$primary;">**Outcome**</mark>\
You configure a JupyterLab application so multiple students can edit the same notebook simultaneously, with edits merging automatically.

<mark style="color:$primary;">**Before you start**</mark>

* You have set up a group-work space with one instance per group (see [Set up group projects](/how-to-guides/workflows-for-instructors/setting-up-group-projects) above).
* You will use JupyterLab 4.0.0 or later. Collaborative editing is most reliable from this version onward.

In collaborative editing mode, multiple students connect to the same application at the same time and edit files and notebooks together - similar to Google Docs. Edits merge automatically, with no file version conflicts.

#### Configure the Application

{% stepper %}
{% step %}
Add a JupyterLab application to the Master Instance of the group-work space (JupyterLab 4 recommended).
{% endstep %}

{% step %}
In the Master Instance applications view, open the ... Actions menu next to the application.
{% endstep %}

{% step %}
Click **CONFIGURE**.
{% endstep %}

{% step %}
Enable **Run in shared mode**.
{% endstep %}

{% step %}
Save the configuration.
{% endstep %}

{% step %}
Distribute the application to the group instances along with any regular files or instructions.
{% endstep %}
{% endstepper %}

For the full configuration screen (all shared-mode behaviors, connectivity options, and add-ons), see [Reference › Applications](/reference/applications).


# Configure course tools and resources

## Pre-start student Applications

<mark style="color:$primary;">**Outcome**</mark>\
You start applications for all students in advance, so resource allocation does not slow down the start of class.

<mark style="color:$primary;">**Before you start**</mark>

* You are a Space Administrator of the course.
* You have distributed the application to all students.
* You expect a large number of students (above \~50) to start the application at the same time, or the application has been customised to request higher resources.

When many students start the same application simultaneously, resource allocation may take several minutes per application instead of the usual 30–60 seconds. Pre-starting applications avoids this - the applications are already running by the time students log in.

### Schedule a startup

{% stepper %}
{% step %}
In the Master Instance, open the applications view.
{% endstep %}

{% step %}
Click the ... Actions menu next to the application.
{% endstep %}

{% step %}
Select **Schedule for start**.
{% endstep %}

{% step %}
Set the date and time by when all applications in the space should be running.
{% endstep %}
{% endstepper %}

The scheduled prestarts can be viewed, edited, or deleted from under the applications list. To repeat a schedule for the next week, click **Add to next week** in the Actions column. The next scheduled startup is also visible from the **Course checklist** on the space overview.

### Schedule constraints

* The schedule must be at least **30 minutes in the future**, to allow time for all applications to start.
* Up to **20 scheduled prestarts** can exist in a space at the same time.
* Prestart dates cannot be more than **6 months in the future**.
* Prestarts cannot be set for archived courses.

### Manual pre-start

If you want to start applications for all users immediately rather than scheduling, use the **Start for all users** option in the ... Actions menu of the applications view.

{% hint style="info" %}
Student applications are stopped automatically after 1 hour of inactivity, so it does not make sense to pre-launch more than an hour before the planned start time. The pre-launch starts the application in the Master Instance for Space Administrators, and the respective student application in each student instance.
{% endhint %}

### Optimisation for repeated prestarts

Only the first prestart starts the application for all users in the space. Subsequent prestarts check which users actually used the application around the last prestart time and start the application only for those users. This saves resources for courses with significant student dropout.


# Configure Applications for student use

<mark style="color:$primary;">**Outcome**</mark>\
You set application configuration (inactivity limit, shared mode, resources) and distribute the configuration to all students at once.

<mark style="color:$primary;">**Before you start**</mark>

* You are a Space Administrator of the course.
* The application exists in the Master Instance.

Space Administrators can configure student applications in two ways:

* **Per application, per instance** - configure through the web UI. Affects only that application in that instance.
* **Via distribution** - configure the application in the Master Instance, then distribute it. Configuration is included with the distribution and applied to every student application.

When distributing applications in course spaces, three configuration values are particularly important and travel with the application:

* **Inactivity limit** - how long the application stays running without student interaction.
* **Shared mode** - whether multiple users connect to the same running application.
* **Resource settings (size)** - how many NCUs the application uses.

For all configurable options and their effects, see [Reference › Applications](/reference/applications).


# Manage performance for large concurrent classes

<mark style="color:$primary;">**Outcome**</mark>\
You design teaching material and application sizing to keep performance acceptable when many students run code simultaneously.

<mark style="color:$primary;">**Before you start**</mark>

* You are designing material for an interactive session with a large class.
* You have a sense of which code examples involve heavy computation.

Every student in a course runs code in the same application configuration as the instructor. When many students execute computationally intensive code concurrently, application performance can be lower than what you experienced while developing the material (when fewer users were active).

For interactive sessions with a large class, two options:

* Design code examples that execute within a minute or so at most.
* Configure the space with larger per-student application sizes - see [Reference › Applications](/reference/applications) for size options.

For the most performance-sensitive cases, contact Nuvolos support to discuss dedicated compute nodes for each student application. For out-of-class work where concurrency is lower, these considerations can be relaxed.


# Video library

## Publish videos to the Video Library

<mark style="color:$primary;">**Outcome**</mark>\
You upload course videos to the Video Library and embed them in a `README.md` so students can watch them in the browser.

<mark style="color:$primary;">**Before you start**</mark>

* The Video Library is enabled at the organisation level and at the space level. For enablement, see [Administration › Space management](/administration/space-management).
* You hold the Space Administrator role on the course space (only Space Administrators can access the Video Library).
* You have the video file(s) ready to upload.

The Video Library is a Nuvolos-managed storage option specifically for video content. Once a video is uploaded, you can embed it in any `README.md` in the space - students with access to that space see the embedded video and play it in the browser. For the conceptual model, capabilities, and quota details, see [Reference › File Storage](/reference/file-system-and-storage).

### **Upload a video**

{% stepper %}
{% step %}
Navigate to the Master Instance of your course.
{% endstep %}

{% step %}
In the Files view, upload the video file as you would any other file. Common video formats are recognised automatically.
{% endstep %}

{% step %}
After upload, Nuvolos offers two options: **keep the file on the file system** or **remove the file and store only in the Video Library**.
{% endstep %}

{% step %}
Choose **remove the file** unless you have a specific reason to keep a copy on the file system - video files consume file-system quota, and the Video Library is the storage-efficient option.
{% endstep %}

{% step %}
The upload to the streaming provider begins automatically. Processing may take up to 30 minutes for a one-hour video.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
The embed code is available as soon as the upload completes - you do not need to wait for processing to finish before embedding. The video may not yet play, but the link is already there.
{% endhint %}

### **Get the embed code**

{% stepper %}
{% step %}
Navigate to the Video Library menu in the space.
{% endstep %}

{% step %}
Find the video in the library.
{% endstep %}

{% step %}
Choose the **embed code format**: fixed size (for tabular layouts where space is constrained) or responsive (for full-width embedding that adapts to the browser).
{% endstep %}

{% step %}
Copy the embed code to the clipboard.
{% endstep %}
{% endstepper %}

### **Embed in a `README.md`**

{% stepper %}
{% step %}
Open the `README.md` file you want to embed the video in (or create one with **+ NEW**).
{% endstep %}

{% step %}
Open the file in **EDIT** mode via the ... Actions menu.
{% endstep %}

{% step %}
Make sure you are in the side-by-side editor mode - embedding does not work in WYSIWYG mode. Toggle modes via the control in the bottom right corner.
{% endstep %}

{% step %}
Paste the embed code where you want the video to appear.
{% endstep %}

{% step %}
Save the file.
{% endstep %}
{% endstepper %}

When you save, the video renders in the preview pane. Once you distribute the `README.md` to student instances, the video appears in the rendered README on the space overview.

#### Reusing one video across multiple READMEs

A single video in the library can be embedded into any number of README.md files at no additional storage cost. To update a video in multiple places, change the underlying video in the library - every README that embeds it automatically shows the new version. To add a recording to an existing course mid-term, paste the embed code into the relevant README, distribute, and students see the update within seconds.

{% hint style="info" %}
Embed codes are origin-locked - the streaming provider only plays back videos when embedded on Nuvolos. Embed codes copied to a third-party site will not play. This prevents unauthorised reuse of your video content.
{% endhint %}


# GPU courses

## Enable GPU access for your course

<mark style="color:$primary;">**Outcome**</mark>\
You enable credit-based application sizes and confirm that your course can run GPU-enabled applications.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the Space Administrator role on the course.
* You have enough credits in the resource pool mapped to the space. See [Billing › Resource pools and budgets](/billing/resource-pools-and-budgets) to verify.
* You have decided between GPU Lab Sessions and On-Demand GPU (see below).

Nuvolos supports two GPU workflows for courses: GPU Lab Sessions (instructor-scheduled) and On-Demand GPU (students start GPU applications themselves within a credit quota). Both require enabling credit-based application sizes in the space.

To enable credit-based sizes for your course, see [Administration › Space management](/administration/space-management).

## Schedule a GPU Lab Session

<mark style="color:$primary;">**Outcome**</mark>\
You schedule a fixed time window during which all students have GPU access, with predictable per-session pricing.

<mark style="color:$primary;">**Before you start**</mark>

* GPU access is enabled for your course (see above).
* You have an application distributed to all students.
* You have decided the session length in minutes.

In a GPU Lab Session workflow, every student gets a GPU-enabled machine during a planned session - for example, *every Monday between 10:00–12:00 on Tesla T4 cards*. Students sign in at the scheduled time and find an already-running, GPU-enabled application waiting for them. Students cannot start the GPU-enabled application themselves.

### Why GPU Lab Sessions work well

* Easy to explain to students - they just show up at the scheduled time.
* Equal opportunity - all students use machines with the same specifications during the same window.
* All students start with the same environment, but can make persistent changes to packages and settings.
* Ideal for exams or for courses where GPU access is only needed in specific windows.
* Predictable, flat pricing - once you know times and durations, your total cost is fixed.

### Schedule the session

{% stepper %}
{% step %}
In the Master Instance, open the applications view.
{% endstep %}

{% step %}
Click the ... Actions menu next to the application and select **Schedule for startup**.
{% endstep %}

{% step %}
Turn on the **Scale resources** toggle.
{% endstep %}

{% step %}
Select your desired GPU size.

The dropdown shows the credit-based sizes available in your space.
{% endstep %}

{% step %}
Configure the **Stop after selected minutes** field.

This determines how long the application runs before automatic shutdown.
{% endstep %}

{% step %}
Save the schedule.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Stop-after-minutes must be between **30 and 360 minutes**. The application stops automatically at the end of the configured duration, including the instructor's own application. Example: if scheduled start is at 10:05 and stop-after is 120 minutes, all GPU applications shut down at 12:05.
{% endhint %}

### Limitations of GPU Lab Sessions

* In course spaces, only smaller GPUs are available, such as Tesla T4 and ⅙ A10. Check the **Schedule for start** menu for the current offer.
* Currently up to **90 concurrent students** are supported. For larger classes or larger GPU sizes, contact Nuvolos support.
* Scheduled startups using GPU machines do not consider past user activity - every student in the space gets a GPU application started for them.
* Any applications already running when the session starts are restarted and moved to GPU machines automatically.

The total cost of a session is approximately *N students × session length (hours) × hourly GPU price + warmup premium*, where the warmup premium accounts for applications starting 30–10 minutes ahead of schedule due to longer machine provisioning at peak times.

## Set up an On-Demand GPU course

<mark style="color:$primary;">**Outcome**</mark>\
Students can start GPU-enabled applications themselves within a credit budget you control.

<mark style="color:$primary;">**Before you start**</mark>

* GPU access is enabled for your course (see [Enable GPU access for your course](#enable-gpu-access-for-your-course) above).
* You understand that students cannot change application sizes - every GPU size you want them to use needs its own distributed application.
* You have decided on a credit budget for the course.

In On-Demand workflows, students start GPU-enabled applications themselves when they need them. This is more flexible than Lab Sessions and ideal for assignments or homework. The instructor controls the credit budget so total cost is capped.

### **Why On-Demand GPU works well**

* Students decide when to use machines - more flexible than fixed windows.
* Equal opportunity - every student gets the same total runtime within the same credit quota.
* All students start with the same environment but can persist their own package changes.
* Predictable, capped pricing through credit quotas.

### **Distribute the right Applications**

Since students cannot change application sizes themselves, the recommended setup is to distribute **multiple applications** - typically the same software at different sizes:

* A version with an **Included size** (for example, 1 NCU) so students can work on source code without consuming credits.
* A version with a **credit-based size** (for example, Tesla T4) for code execution with GPU.

If you want students to choose between multiple GPU sizes, distribute one application per size.

{% hint style="info" %}
To save on credits and storage, install all packages students will likely need in the Master Instance before distributing. This avoids repeated installation of large libraries (such as TensorFlow or PyTorch) in every student instance.
{% endhint %}

## Configure a Credit quota schedule

<mark style="color:$primary;">**Outcome**</mark>\
You set the credit budget available to student instances, distributed over the course timeline.

<mark style="color:$primary;">**Before you start**</mark>

* Credit-based sizes are enabled in the space.
* You have decided on either fixed or tiered quota distribution (see below).

Credit quotas are set on the **Course Configuration → Student Credit Quotas** screen. Each quota row has three properties:

* **Amount** - the total Credits available.
* **End date** - the date by which the amount applies.
* **Reset flag** - determines how the amount accumulates across periods (see fixed vs tiered below).

### End-date consistency requirements

* End-dates must be in monotonous order.
* You cannot move an end-date into the past or past the next end-date in the schedule.

### Fixed quota schedule&#x20;

**(Reset = Yes)**

Fixed schedules let you define maximum credit usage between specific dates. At each end-date, unused credits are lost and a new period begins.

Example fixed schedule:

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Credit limit</strong></td><td valign="top"><strong>End date</strong></td><td valign="top"><strong>Reset counter</strong></td></tr><tr><td valign="top">1.2</td><td valign="top">2025-09-15</td><td valign="top">Yes</td></tr><tr><td valign="top">1.2</td><td valign="top">2025-09-22</td><td valign="top">Yes</td></tr><tr><td valign="top">0.6</td><td valign="top">2025-09-29</td><td valign="top">Yes</td></tr></tbody></table>

&#x20;Under this schedule, each student Instance can:

* Consume up to 1.2 credits from space creation until 2025-09-15 EOD.
* Consume up to 1.2 *more* credits from 2025-09-16 to 2025-09-22 EOD.
* Consume up to 0.6 *more* credits from 2025-09-23 to 2025-09-29 EOD.
* From 2025-09-30 onwards, cannot start credit-based applications.

End-of-day (EOD) is 23:59:59 UTC. Counter reset also stops any running credit-based applications at midnight in student Instances.

### **Tiered quota schedule**&#x20;

**(Reset = No until final period)**

Tiered schedules let you define maximum credit usage up to specific dates without resetting between periods. Unused credits roll forward - an instance that becomes active only in the last week can still use the full final allowance.

Example tiered schedule:

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Credit limit</strong></td><td valign="top"><strong>End date</strong></td><td valign="top"><strong>Reset counter</strong></td></tr><tr><td valign="top">1.2</td><td valign="top">2025-09-15</td><td valign="top">No</td></tr><tr><td valign="top">2.4</td><td valign="top">2025-09-22</td><td valign="top">No</td></tr><tr><td valign="top">3.0</td><td valign="top">2025-09-29</td><td valign="top">Yes</td></tr></tbody></table>

&#x20;Under this schedule, each student instance can:

* Consume up to 1.2 credits from space creation until 2025-09-15 EOD.
* Consume up to 2.4 credits *total* from space creation until 2025-09-22 EOD.
* Consume up to 3.0 credits *total* from space creation until 2025-09-29 EOD.
* From 2025-09-30 onwards, cannot start credit-based applications.

### Cross-instance quota usage

Quotas apply at the **space level** but enforce **per instance**. A quota of 1 credit by a given date means each instance independently can use up to 1 credit by that date. The **usage across instances** subscreen of **Course Configuration → Student Credit Quotas** gives you the full overview.

To calculate the total credit allowance of a course up to a given date: cumulative quota × number of instances in the course up to that date. The exact calculation depends on whether you use fixed or tiered.

### **Current quota - concept**

The **current quota** is whichever row in your schedule has the nearest end-date that is past today's date (inclusive). For example, if today is 2026-03-23 and your schedule has rows ending 2026-03-23 (2 Credits) and 2026-03-25 (3 Credits), the current quota is the 2026-03-23 row - 2 credits is the maximum each Instance could spend by today.

## Use a GPU Lab Session inside an On-Demand course

<mark style="color:$primary;">**Outcome**</mark>\
You schedule a one-off lab session inside a course that otherwise uses On-Demand GPU, ensuring the session's Credit usage does not exhaust the students' regular budget.

<mark style="color:$primary;">**Before you start**</mark>

* You have an On-Demand GPU course set up with a Credit quota schedule.
* You want to schedule a single lab session inside that course.

Two important caveats when running a Lab Session in an On-Demand course:

* You must explicitly select the GPU resource in the schedule configuration. Without enabling Scale resources, the Application will start without GPU.
* Lab session Credit spending counts against students' regular Credit limit — exactly like any session they start themselves. Plan accordingly.

{% hint style="info" %}
Lab sessions inside On-Demand courses can cause credit imbalance between students. Student applications are started in sequence, so different students incur different credit costs based on the order. If a student's application is started by the system scheduler, it is also stopped by the system scheduler at the end - but students who started their applications themselves before the lab session continue working uninterrupted (and are responsible for stopping their own application).
{% endhint %}

Recommended pattern: set a dedicated quota row for the lab session's day, separate from the regular quota. Example schedule with lab session days on 2025-09-17 and 2025-09-24:

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Credit limit</strong></td><td valign="top"><strong>End date</strong></td><td valign="top"><strong>Reset counter</strong></td></tr><tr><td valign="top">1.2</td><td valign="top">2025-09-16</td><td valign="top">Yes</td></tr><tr><td valign="top">0.36</td><td valign="top">2025-09-17</td><td valign="top">Yes</td></tr><tr><td valign="top">1.2</td><td valign="top">2025-09-23</td><td valign="top">Yes</td></tr><tr><td valign="top">0.36</td><td valign="top">2025-09-24</td><td valign="top">Yes</td></tr></tbody></table>


# Assignments, grading, and feedback

## Creating an assignment

<mark style="color:$primary;">**Outcome**</mark>\
You create an assignment by distributing a set of files with a deadline, after which students cannot hand in further work.

<mark style="color:$primary;">**Before you start**</mark>

* You are working in the **Master Instance** (always create assignments from the Master Instance!).
* The files you want students to work on are ready and located where you want them in the Workspace.
* You have decided on the hand-in deadline and size limit.

An assignment is a collection of Nuvolos objects (files, folders) plus a deadline. Assignments are created during material distribution - you tick the **Create an assignment** checkbox in the distribution flow. You then set the hand-in deadline and a hand-in size limit (see below).

Created assignments are visible on the space overview Dashboard and on the Assignments view in the sidebar. The Assignments icon and view only become active once at least one assignment exists in the space.

### Assignment with fixed files

Let's assume we've selected the following files for the assignment:

```
/Assignment1/instructions.pdf
/Assignment1/exercise.ipynb
/Assignment1/results.csv
```

In this case, the students have the instructions for the exercise in `instructions.pdf`. They need to complete the prepared `exercise.ipynb` file and execute all cells successfully, such that in the end a `results.csv` file is generated. During hand-in, all 3 files will be collected and copied to a new location for review and grading. This is ideal for simple exercises, because the format of the collected documents is fixed: students can only hand-in these fixed 3 files, and nothing else.

### Assignment with folders

There are cases where students need to have more freedom in what they want to hand. For example, the output format depends on the group exercise. In such cases, the instructor can add a **folder** to the assignment, like this:

```
/Assignment1/instructions.pdf
/Assignment1/solution
```

Now, students can put multiple different files/folders under the `solution` folder.

### Assignment with data

Sometimes assignments require datasets, e.g. training data for an ML model. In that case, a 2-step process is recommended:

1. First [distribute](/concepts/distribution) the dataset using normal distribution. Wait until the confirmation email arrives, then all students have the datasets already.
2. Then create the assignment *only with the files the students are expected to change*. Example:

```
/Assignment1/dataset -> share using normal distribution
/Assignment1/exercise.ipynb -> add only this to the assignment
```

{% hint style="info" %}
We do not recommend sharing more than a few hundred MB of dataset data via distribution. For larger datasets, use Large File Storage - see [Large File Storage](/reference/file-system-and-storage/large-file-storage).
{% endhint %}

## Set the hand-in size limit

<mark style="color:$primary;">**Outcome**</mark>\
You set an upper bound on submission size, preventing students from accidentally submitting large files (such as virtual environments or data dumps) that would fill up shared storage.

<mark style="color:$primary;">**Before you start**</mark>

* You are creating or modifying an assignment.
* You have a sense of how large legitimate submissions are likely to be.

When you create an assignment, you set a hand-in size limit between **1 MB and 100 MB**. This limit applies to all files combined in a single hand-in. If a student's submission exceeds the limit, they see an error and must reduce file sizes before submitting.

#### Why hand-in limits matter

When an assignment contains a folder, students sometimes leave large unintended files inside it - entire Python virtual environments, data dump files, and similar. Every 10 MB hand-in is copied twice into the Distributed Instance (once as the read-only hand-in, once as the editable hand-back for instructors). Without limits, the Distributed Instance can quickly fill up, blocking further hand-ins for the entire class.

{% hint style="info" %}
If you created an assignment before hand-in limits were introduced, the system will ask you to set a limit the next time you change related settings. Setting a hand-in size limit does not affect submissions already made.
{% endhint %}

## View and modify assignments

<mark style="color:$primary;">**Outcome**</mark>\
You change an assignment's deadline, description, or hand-back visibility.

<mark style="color:$primary;">**Before you start**</mark>

* You are a Space Administrator of the course.
* The assignment already exists.

Space Administrators can modify assignment properties (deadlines, descriptions, hand-back visibility) from the assignment overview page in three places:

* Under the **Actions** column in the Assignments list.
* By opening the assignment from the Space overview directly.
* By clicking the edit button under the assignment details on the Assignments overview page.

## Review and grade assignments

<mark style="color:$primary;">**Outcome**</mark>\
You open a student's submission inside the student's application, review their work, and assign a grade.

<mark style="color:$primary;">**Before you start**</mark>

* The assignment deadline has passed (or you are reviewing early submissions).
* You are a Space Administrator of the course.

**Open the grade table**

{% stepper %}
{% step %}
Open the assignment view.
{% endstep %}

{% step %}
Click **Grade**. The grade table opens with one row per hand-in.
{% endstep %}

{% step %}
Click **Review** next to a hand-in.&#x20;

The student's Application launches with a copy of their submission mounted in the Files area. All packages the student installed are available, so open-ended projects work end-to-end.
{% endstep %}
{% endstepper %}

To download files without opening an application, use the Handback tab. Use the dropdown menu to choose which hand-in to review.

{% hint style="info" %}
Students can submit multiple times until the deadline. Nuvolos only allows grading of the latest submission from a given Instance, and by default only these are shown on the Handin tab. To inspect earlier hand-ins, uncheck Show only gradeable handins on the Handin tab.
{% endhint %}

Students can use any custom name for their submissions (often their student ID). Nuvolos groups submissions coming from the same Instance as different versions from the same entity, and only the latest submission is gradeable - even if different users in the same Instance submitted under different names.

## Providing feedback

<mark style="color:$primary;">**Outcome**</mark>\
You add written feedback directly inside the submitted files and assign a grade.

<mark style="color:$primary;">**Before you start**</mark>

* You have opened the student's submission via the Review button.

Feedback can be added inside the submitted files in any form you see fit - inline comments, separate annotation files, code review notes. Nuvolos maintains a copy of the original hand-in for reference if needed.

{% hint style="info" %}
Use explicit inline comments so students can clearly see what came from you. A useful convention is to mark all instructor comments with a single-letter prefix, for example # I::
{% endhint %}

```sql
var = 1   # I: Use a more informative variable name

test_tuple = (False, "test")

if test_tuple:   # I: Use test_tuple[0] instead
    print("This should not appear.")
```

Once review is complete, assign a grade:

{% stepper %}
{% step %}
Click the grade icon on the sidebar.&#x20;

The grade table opens with the current hand-in highlighted.
{% endstep %}

{% step %}
Enter the grade as free text.
{% endstep %}
{% endstepper %}

## Hand back assignments

<mark style="color:$primary;">**Outcome**</mark>\
Students see their grades and the corrected versions of their files in a read-only handback folder.

<mark style="color:$primary;">**Before you start**</mark>

* All hand-ins have been reviewed and graded.
* You have decided to release all grades at once.

During grading, hand-backs are not visible to students. Once review is complete, edit the assignment (see *View and modify assignments* above) and enable hand-back visibility.

When students start their Applications after hand-backs are enabled, they see a special folder structure with the reviewed versions of their files (read-only):

<pre class="language-sql" data-overflow="wrap"><code class="lang-sql"><strong>Assignments/handback/&#x3C;assignment_name>/&#x3C;handin_id>
</strong></code></pre>

Students can also view the corrected files under the Handin and Handback tabs of the assignment view.

## Export grades

<mark style="color:$primary;">**Outcome**</mark>\
You export grades as an Excel file you can upload into other systems or share with administrative staff.

<mark style="color:$primary;">**Before you start**</mark>

* You have completed grading.

Open the grade table and use the export option to download grades as Excel.


# Programmatic assignment handling

<mark style="color:$primary;">**Outcome**</mark>\
You collect, grade, and hand back assignments at the command line using nvcollect, integrated with otter-grader.

{% hint style="warning" %}
This is a new and experimental feature of Nuvolos, please provide us with feedback to make it better!
{% endhint %}

<mark style="color:$primary;">**Before you start**</mark>

* You have access to a JupyterLab + TeX Live application.
* `otter-grader` and `pandoc` are available in the application (TeX Live is available on request from Nuvolos support).
* You have installed `nvcollect` (contact support for the current install command).
* You are working in the Master Instance.

{% hint style="info" %}
To install `nvcollect`, run the following command from the terminal in your JupyterLab application:

```bash
pip install --upgrade git+https://github.com/alphacruncher/nv-collect
```

{% endhint %}

`nvcollect` is a command-line tool available in supported applications. It lets you:

* Collect assignments from all students into a folder in your instance.
* Grade assignments with the `otter-grader` package.
* Hand back assignments to all students in one command.

### Otter Grader integration

Below is a complete pipeline integrating `nvcollect` with `otter-grader`. It assumes you have already set up a JupyterLab application with `otter-grader`, `pandoc`, and `TeX Live`.

{% stepper %}
{% step %}

#### Obtain the Otter tutorial files

In a JupyterLab terminal, download the Otter Grader tutorial files. Refer to the [otter-grader documentation](https://otter-grader.readthedocs.io/) for the current download command.
{% endstep %}

{% step %}

#### Modify `demo.ipynb` for headless use

The Otter Grader `demo.ipynb` assumes a windowed environment, which is not available on Nuvolos. In the second cell, replace the windowed call with the headless equivalent:

```sql
%matplotlib inline
```

Make sure to have:

```sql
import matplotlib
matplotlib.use('Agg')
```

{% endstep %}

{% step %}

#### Run `otter assign`

In the directory where you extracted the tutorial archive, run:

{% code overflow="wrap" %}

```sql
otter assign demo.ipynb dist --v1
```

{% endcode %}

This creates a `dist/` directory containing autograding artefacts and the student-facing assignment file at `dist/student/demo.ipynb`.
{% endstep %}

{% step %}

#### Create the assignment on Nuvolos

Copy `dist/student/demo.ipynb` to a clean folder under `/files`, then stage and distribute it as an Assignment (see [Creating an assignment](/how-to-guides/workflows-for-instructors/setting-assignments#creating-an-assignment) above). \
For example, copy from `/files/otter-test/dist/student/demo.ipynb` to `/files/assignment_1/demo.ipynb`, stage `/files/assignment_1/`, and create an assignment named 'assignment\_1'.

{% hint style="info" %}
Keeping the assignment name in Nuvolos the same as the folder name (assignment\_1) is a useful convention - it is not required, but it makes the `nvcollect` command much easier to remember.
{% endhint %}
{% endstep %}

{% step %}

#### Collect hand-ins

Once the deadline has passed, collect submissions:

{% code overflow="wrap" %}

```sql
nvcollect collect \
  --assignment_name "assignment_1" \
  --assignment_folder assignment_1 \
  --target_folder /files/test_collect
```

{% endcode %}

This gathers everything in the *assignment\_1* folder of the *assignment\_1* assignment from all students into `/files/test_collect/`. The directory structure is:

{% code overflow="wrap" %}

```sql
/files/test_collect
+-- nvcollect_manifest.json
+-- single_user_inst_<code1>
|   +-- ...
+-- single_user_inst_<code2>
|   +-- ...
```

{% endcode %}
{% endstep %}

{% step %}

#### Grade hand-ins

Run autograding across all collected submissions:

{% code overflow="wrap" %}

```sql
nvcollect otter-grade \
  --source_folder /files/test_collect \
  --autograder_location /files/otter-test/dist/autograder/autograder.zip \
  --relative_path demo.ipynb
```

{% endcode %}

Three notes:

* `source_folder` is the same as the `target_folder` from the collect command.
* `autograder_location` is the absolute path to the autograder zip from step 3.
* `relative_path` tells the tool where to look inside each student folder for the notebook to grade.

After grading, `source_folder` contains:

* A `grade.csv` file at the top level with the score of each student.
* A `grade.csv` file inside each student folder with that student's score.
  {% endstep %}

{% step %}

#### Hand back the results

Optionally add additional artifacts to each student folder (manually or programmatically), then push results back to students:

{% code overflow="wrap" %}

```sql
nvcollect handback --source_folder /files/test_collect
```

{% endcode %}

`source_folder` here is the same folder where collection and grading happened.
{% endstep %}
{% endstepper %}

### Collecting assignments for download and archival

Starting version `1.0.0` of `nuvolos-collect`, the library provides the `nvcollect archive` command. This command collects submissions grouped by assignment and create a zip file per assignment into a target folder.


# Archiving your course

## Archive your course

<mark style="color:$primary;">**Outcome**</mark>\
You set a date after which the course is archived, freeing up storage while preserving student work for download or distribution.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the course.
* The course is winding down or the term has ended.

Course spaces have a defined lifecycle. After a configured date, the space is archived automatically - its data moves to cold storage, freeing space for active courses. This is conceptually similar to resting spaces in research projects, but archival is specific to course spaces and managed automatically. See [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts) for the conceptual model.

### Set or change the archival date

{% stepper %}
{% step %}
Open the course space.
{% endstep %}

{% step %}
From the sidebar, navigate to the space **Settings**.
{% endstep %}

{% step %}
Select **General** settings menu.
{% endstep %}

{% step %}
Under the **Space details**, edit **Archive on** date.
{% endstep %}
{% endstepper %}

The space is archived automatically overnight on the configured date. You can change the archival date at any time before archival happens.

#### What archival means for you and students

* Application and personal data in student instances are backed up to cold storage.
* Applications can't be launched in an archived course directly.
* Data can be restored from snapshots, after which files can be downloaded and applications started again.
* After a few days' grace period, restored instances are re-archived automatically. Snapshots can be restored as many times as needed.

{% hint style="warning" %}
Archived courses are not for everyday use. Restored snapshots are periodically re-archived without taking new safety backups. Restore a snapshot in an archived course only when you need to either download specific data or distribute files, tables, or applications to another active space.
{% endhint %}

#### Assignments in archived courses

When a course is archived, the Assignments view remains accessible (moved to the bottom of the sidebar) but is shown in a read-only, dimmed state:

* Assignment rows are greyed out to indicate the archived state.
* Action buttons (submit hand-in, edit assignment, delete) are hidden.
* Clicking an assignment name does not navigate to its detail page.

Assignment history remains visible for reference, but no modifications are possible.

### Find archived courses

{% stepper %}
{% step %}
Either use the **Recent Spaces** on the bottom of the Dashboard or from the sidebar select **Spaces** to open the Space list.
{% endstep %}

{% step %}
In the search bar click **Filters** and toggle on **Courses** and **Inactive**.
{% endstep %}

{% step %}
All archived spaces will be listed once filtered, to see the full list select Rows per page count on the bottom of the list.
{% endstep %}
{% endstepper %}

### Resume work in an archived course

To resume work, restore a past snapshot to the Current state. After restoration you have a three-day grace period to work with the data or download what you need. After the grace period, the Current state is deleted again. If you need more time, restore the snapshot again - there is no limit on repeats.

## Reuse a course for the next term

<mark style="color:$primary;">**Outcome**</mark>\
You bring your teaching material into a new course space for the next term without manually re-uploading everything.

<mark style="color:$primary;">**Before you start**</mark>

* The previous course space still exists (active or archived).
* You have decided what to carry forward - typically the polished material from the Master Instance, not student work.
* You hold Faculty or Manager role so you can create a new course space.

The full cross-term workflow is covered as a tutorial - see [Tutorials › Reusing a course for the next term](/tutorials/tutorials-for-instructors/reusing-a-course-for-the-next-term) in the Instructor tutorials. The tutorial walks through capturing the previous Master Instance as a snapshot, creating the new course, and cross-distributing materials.


# Workflows for Students

These guides answer the question *"how do I do X?"* for students who already have working familiarity with Nuvolos. If you are new to the platform, start with the [Student tutorials](/tutorials/tutorials-for-students) first - they take you from zero to your first submitted assignment by following along.

The guides are organised by where you are in your course lifecycle:

* **Join and get oriented** - accept your invitation, find your materials, understand the layout.
* **Use applications and files** - start and stop applications, work with files, navigate the storage areas.
* **Complete and submit assignments** - work on assignments, hand them in, review feedback.
* **Save and recover work** - take snapshots, restore from snapshots, version your work.
* **Collaborate and use special resources** - group projects, GPU access, course-specific tools.
* **Finish and take work with you** - leave a course, work with archived courses, export files.

Each page assumes you can navigate Nuvolos's Dashboard, sidebar, and breadcrumbs. If anything in the interface is unfamiliar, see [Getting Started › Find your way around](/getting-started/find-your-way-around).

### Where to go next

* For a guided first-day walk-through (invitation → application → assignment), see [Student tutorials](/tutorials/tutorials-for-students).
* For procedures every role shares (invitations, Applications, snapshots), see [How-to › Common Workflows](/how-to-guides/common-workflows).
* For the conceptual model behind instances, snapshots, and the rest of the Nuvolos hierarchy, see [Concepts](/concepts/nuvolos-basic-concepts).
* For terms you don't recognise, see [Getting Started › Glossary](/getting-started/glossary).


# Accept a course invitation

<mark style="color:$primary;">**Outcome**</mark>\
You join a course on Nuvolos by accepting the invitation sent by your instructor.

<mark style="color:$primary;">**Before you start**</mark>

* You have received an invitation email from your instructor.
* You know which identity provider you want to use to sign in (institutional SSO, Google, or Nuvolos).

The procedure for accepting any Nuvolos invitation is the same regardless of the role you are being granted. See the canonical procedure: [How-to › Common Workflows › Accepting an invitation](/how-to-guides/common-workflows/accepting-an-invitation).

{% hint style="info" %}
**First-time users**

For first-time users, the signing up process might take up to a minute to conclude.
{% endhint %}

{% hint style="danger" %}
**Choose the right login option**

When accepting the invitation, we encourage you to proceed with the recommended option. For students affiliated with a Swiss higher education institution, this is SWITCH.

If you choose to sign up with email and password authentication, the SWITCH option will not be available for you anymore.
{% endhint %}


# Find your course materials

<mark style="color:$primary;">**Outcome**</mark>\
You locate the files, datasets, and applications your instructor has provided for the course.

<mark style="color:$primary;">**Before you start**</mark>

* You have accepted your course invitation.
* You know the course name.

Course materials are distributed to your personal Instance within the course space. Once distributed, they appear inside your applications as regular files in the Workspace area.

### Open your personal instance

{% stepper %}
{% step %}
Navigate to the Dashboard.
{% endstep %}

{% step %}
On the sidebar select Spaces to open the Spaces list, or see Recent Spaces section at the bottom of the Dashboard. Click Filters and toggel on Courses.
{% endstep %}

{% step %}
Click the name of your course. Nuvolos opens your personal instance automatically.

Courses often include multiple instances. You typically work in your own instance, though shared or instructor-provided materials may exist in other instances.
{% endstep %}
{% endstepper %}

### Access the Distributed instance

Many instructors distribute course-wide materials to a shared space called the Distributed instance (typically with viewer access). To access it:

{% stepper %}
{% step %}
Open the instance selector by clicking on the Instance name on the sidebar.
{% endstep %}

{% step %}
Select Distributed.
{% endstep %}

{% step %}
Open Files.
{% endstep %}

{% step %}
Find the relevant course materials folder.
{% endstep %}
{% endstepper %}

### Find the material

Distributed materials appear in two places:

* In the Files view - click the folder icon on the sidebar. The Workspace area (mounted at `/files` inside running Applications) is the default view.
* Inside any running application - start an application and look in the `/files` directory. Same content, accessed from the other side.

{% hint style="info" %}
If you joined the course recently and do not see any materials yet, check with your instructor. New material is delivered through the distribution mechanism, and it may not have been pushed to your Instance yet.
{% endhint %}

For the full file navigator reference (uploads, downloads, archives), see [Reference › File storage](/reference/file-system-and-storage).


# Understand the course layout

<mark style="color:$primary;">**Outcome**</mark>\
You understand the difference between your personal Instance and the Distributed Instance, and where your work is saved.

<mark style="color:$primary;">**Before you start**</mark>

* You have at least one application running, or you have opened the Files view.

Every student in a course has a personal Instance - a private working environment that only you and your instructor can see. Course material that your instructor distributes flows into this instance through a special distribution channel:

**Master instance → Distributed instance → Your personal instance**

Three terms are worth knowing without going deeper:

* Your **Personal Instance** is where you work. Files you save, applications you start, and snapshots you take all live here.
  * You can edit files, run applications, and complete assignments here.
  * Your work does not affect other students.
  * Changes you make are only visible in your own instance.
* The **Distributed Instance** is the channel through which course materials reach you. You see distributed material as files in your personal Instance, not as a separate location.
* The **current state** is the live, mutable version of your personal instance. When you take a snapshot, you create an immutable copy of the current state at that moment.

For the full conceptual model of how these pieces fit together, see [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).


# Use applications

## Start an Application

<mark style="color:$primary;">**Outcome**</mark>\
You launch a course Application (RStudio, JupyterLab, MATLAB, VS Code, or similar) and access your course materials inside it.

<mark style="color:$primary;">**Before you start**</mark>

* You have at least one Application configured for your course Instance (your instructor pre-installs these).
* You are signed in to Nuvolos.

The procedure for starting an Application is the same regardless of the role using it. See the canonical procedure: [How-to › Common Workflows › Starting an Application](/how-to-guides/common-workflows/starting-an-application).

{% hint style="info" %}
Application startup typically takes 30–60 seconds. The first start may take longer if packages or configuration files need to be initialised.
{% endhint %}

## Stop an Application

<mark style="color:$primary;">**Outcome**</mark>\
You stop a running Application to free up resources.

<mark style="color:$primary;">**Before you start**</mark>

* You have a running Application you want to stop.

The procedure for stopping an Application is the same regardless of the role using it. See the canonical procedure: [How-to › Common Workflows › Stopping an Application](/how-to-guides/common-workflows/stopping-an-application).

{% hint style="info" %}
You do not strictly have to stop Applications manually. Nuvolos automatically stops inactive student Applications after one hour. Stopping them explicitly frees resources sooner - useful when your course has a Credit budget or shared GPU schedule.
{% endhint %}


# Work with files

<mark style="color:$primary;">**Outcome**</mark> \
You upload, download, organise, and edit files in your personal Instance.

<mark style="color:$primary;">**Before you start**</mark>

* You are inside your course Instance.
* You are in the **Current state** (the live, writable version of the Instance).

#### Two ways to work with files

You can manage files from two places:

* **The Nuvolos web UI (Files view)** - best for quick uploads, downloads, renames, and previews. Reach it via the folder icon on the sidebar.
* **Inside a running Application** - best when you are already coding. Files in `/files` (Workspace) and \~ (Personal) are persistent; changes save automatically.

#### Most common file operations

* **Upload** a file from your computer - click UPLOAD in the Files view.
* **Download a file** - click the ... Actions menu on the file row and choose DOWNLOAD.
* **Download a folder** - same menu; the folder is delivered as a ZIP archive.
* **Extract an archive** (zip, tar.gz, bz2, and similar) - use the ... Actions menu and choose EXTRACT.
* **Edit a small text file** in the browser - click the file name and choose Edit. Supported for files under 1 MB that decode to UTF-8.

For the full file navigator reference, including all supported archive formats and the file preview behavior, see [Reference › File storage](/reference/file-system-and-storage).

## Navigate personal and Workspace areas

<mark style="color:$primary;">**Outcome**</mark>\
You understand the difference between Workspace, Personal, and Application library areas, and you know which one to put a file in.

<mark style="color:$primary;">**Before you start**</mark>

* You have at least one application running, or the Files view open.

Each Nuvolos application has three persistent storage areas. They look identical inside the application, but they have different visibility scopes and different use cases.

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Area</strong></td><td valign="top"><strong>Where it lives</strong></td><td valign="top"><strong>Who can see it</strong></td><td valign="top"><strong>What it's for</strong></td></tr><tr><td valign="top"><strong>Workspace files</strong></td><td valign="top"><code>/files</code> in the Application</td><td valign="top">All users in your Instance</td><td valign="top">Course materials, your assignments, files you want collaborators to see.</td></tr><tr><td valign="top"><strong>Personal files</strong></td><td valign="top"><code>~</code> (your home directory)</td><td valign="top">Only you, only in this Instance</td><td valign="top">Personal scratch files, account-specific configuration, files you do not want to share.</td></tr><tr><td valign="top"><strong>Application library files</strong></td><td valign="top">Depends on Application type</td><td valign="top">All users for the same Application in this Instance</td><td valign="top">Packages and libraries you install in the Application.</td></tr></tbody></table>

&#x20;In the Nuvolos web UI Files view, you can switch between Workspace and Personal using the dropdown below the UPLOAD button. Application library files are managed automatically by the Application itself.

{% hint style="info" %}
When you submit an assignment, only files in the Workspace (`/files`) are included. Keep your assignment files in Workspace, and use Personal for scratch work that should not be submitted.
{% endhint %}


# Complete and submit assignments

## View your assignments

<mark style="color:$primary;">**Outcome**</mark>\
You see the assignments your instructor has set, their deadlines, and your submission status.

<mark style="color:$primary;">**Before you start**</mark>

* You are inside the course space.
* Your instructor has created at least one assignment.

#### Where to find assignments

* **Space overview** - a summary appears on the Space's landing page when you open the Space.
* **Assignments view** - click the assignments icon on the sidebar for a detailed list: deadlines, submission status, and the hand-in button if the assignment is still open.

The color coding (red → green) on each assignment indicates how much time is left before the deadline.

#### Open the assignment files

Click an assignment to see the files included in it. These files are distributed to you by the instructor and appear inside your Applications as regular files in the Workspace area - you work on them in place, you do not need to download them anywhere.

## Work on an assignment

<mark style="color:$primary;">**Outcome**</mark>\
You edit the assignment files, save your work, and prepare for hand-in.

<mark style="color:$primary;">**Before you start**</mark>

* You can see the assignment in the Assignments view.
* You have started the relevant Application (such as JupyterLab or RStudio).

To work on an assignment, edit the files distributed as part of it. When you are satisfied, make sure all your files are saved and proceed to the hand-in.

{% hint style="warning" %}
Nuvolos hands in the files automatically based on the assignment's file list. You cannot manually select files to submit. If you work on the assignment offline, you must move your solution to the exact same folder with the exact same filename as you originally received - otherwise the submission protocol will not find it.
{% endhint %}

## Hand in an assignment

<mark style="color:$primary;">**Outcome**</mark>\
You submit your assignment files for grading.

<mark style="color:$primary;">**Before you start**</mark>

* All assignment files exist in their original folders with their original filenames.
* The assignment deadline has not passed.
* The total combined size of your submission is within the hand-in limit (set by your instructor).

#### Submit the assignment

{% stepper %}
{% step %}
Click the assignment from the Dashboard or the Assignments view.
{% endstep %}

{% step %}
Click the Hand-in button.

Top right of the dialog, or under Actions in the assignment overview.
{% endstep %}

{% step %}
Choose a hand-in identifier.

This is the submission title your instructor will see - usually your university email address, a student identification number, or similar. If unsure, ask your instructor what convention to use.
{% endstep %}

{% step %}
Confirm the submission.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
You can submit multiple times for the same assignment from the same Instance until the deadline passes. Your instructor will only see and grade your latest submission. This is true even if different submissions use different hand-in identifiers, or if multiple users submit from the same Instance - one Instance can have only one gradable submission (the latest one).
{% endhint %}

#### Confirm the submission worked

After you submit, the read-only files appear under the assignment's hand-in area at the path:

{% code overflow="wrap" %}

```
Assignments/handback/<assignment_name>/<handin_id>
```

{% endcode %}

Check this folder to confirm that all files were submitted in the version you expected. Files are read-only - you cannot modify them, but you can download them if needed.

{% hint style="info" %}
Past submissions are not deleted. You can review the list of submissions you have made using the dropdown menu in the assignment overview.
{% endhint %}

## Review instructor feedback

<mark style="color:$primary;">**Outcome**</mark>\
You see your grade and the instructor's feedback on your assignment.

<mark style="color:$primary;">**Before you start**</mark>

* You have submitted at least one hand-in for the assignment.
* Your instructor has reviewed your work and enabled hand-back visibility.

#### Open the feedback

{% stepper %}
{% step %}
Click the assignment tile to open the Assignment view.
{% endstep %}

{% step %}
Open the Handback tab. Your grade and corrected files are listed there.
{% endstep %}

{% step %}
Click Download in the Actions column to download corrected files, or Review Corrections to open them inside an Application.
{% endstep %}
{% endstepper %}

Corrected files appear at:

{% code overflow="wrap" %}

```
Assignments/handback/<assignment_name>/<handin_id>
```

{% endcode %}

{% hint style="info" %}
Feedback is only visible if your instructor has made hand-backs available. If you cannot see corrected files after grading, it means your instructor has not yet released feedback - wait or contact them.
{% endhint %}

{% hint style="warning" %}
Only your latest hand-in is graded. If you submitted multiple times, the instructor's feedback applies to the final submission.
{% endhint %}


# Save and recover work

## Take a snapshot

<mark style="color:$primary;">**Outcome**</mark> \
You preserve the complete state of your Instance - files, tables, and Application configurations - as an immutable, time-stamped record.

<mark style="color:$primary;">**Before you start**</mark>

* You are in the Current state of your personal Instance.
* All work you want to preserve has been saved.

The procedure for creating a snapshot is the same regardless of the role taking it. See the canonical procedure: [How-to › Common Workflows › Create a snapshot](/how-to-guides/common-workflows/snapshots/create-a-snapshot).

{% hint style="info" %}
Take a snapshot before any major change to your work - before a risky refactor, before submitting an assignment, or at the end of a working session. The snapshot preserves the *entire* state, not just files, so you can roll back without losing your Application configuration.
{% endhint %}

## Restore from a snapshot

<mark style="color:$primary;">**Outcome**</mark>\
You revert your Instance to a previous state captured in a snapshot.

<mark style="color:$primary;">**Before you start**</mark>

* You have taken at least one snapshot of the Instance.
* You understand that restoring will replace the Current state with the snapshot contents.

The procedure for restoring from a snapshot is the same regardless of the role doing it. See the canonical procedure: [How-to › Common Workflows › Restore from a snapshot](/how-to-guides/common-workflows/snapshots/restore-a-snapshot).

{% hint style="info" %}
Restoring affects the entire Instance. Before any restore, Nuvolos automatically creates a snapshot of the current state so you can revert the restore if needed.
{% endhint %}

## Delete a snapshot

<mark style="color:$primary;">**Outcome**</mark>\
You permanently remove a snapshot you no longer need, freeing up storage.

<mark style="color:$primary;">**Before you start**</mark>

* You have identified the snapshot you want to delete.
* You understand the action is irreversible.

The procedure for deleting a snapshot is the same regardless of the role doing it. See the canonical procedure: [How-to › Common Workflows › Delete a snapshot](/how-to-guides/common-workflows/snapshots/delete-a-snapshot).

{% hint style="info" %}
If you delete files from your Current state but the data is still referenced in a snapshot, storage is not freed. To fully reclaim storage, delete the snapshots that contain the data as well. For the reasoning, see [Concepts › Snapshots, distribution, and states](/concepts/distribution).
{% endhint %}


# Collaborate and use special resources

## Work in a group project

<mark style="color:$primary;">**Outcome**</mark>\
You collaborate with teammates inside a shared group Instance, editing the same files and saving snapshots together.

<mark style="color:$primary;">**Before you start**</mark>

* Your instructor has set up a group Instance for your group.
* You have accepted the invitation to the group Instance and can see the group Space in your Dashboard.

Group projects in Nuvolos use a **shared Instance** - one Instance that several students access as Instance Editors. All edits, files, and snapshots in the group Instance are visible to every group member in real time.

### **Start the shared Application**

{% stepper %}
{% step %}
From the Dashboard, open the group-work Space.
{% endstep %}

{% step %}
Navigate to your group Instance.
{% endstep %}

{% step %}
Open the Applications view and start the Application your instructor configured for group work.
{% endstep %}
{% endstepper %}

The startup procedure is identical to starting any other Application - see [Start an Application](/how-to-guides/common-workflows/starting-an-application) above.

### Edit together without conflicts

Two cases to be aware of:

* **If the Application runs in Shared mode** (most commonly JupyterLab 4.0.0 or later) - you and your teammates can edit the same file simultaneously and see each other's changes live, similar to Google Docs. Edits merge automatically, with no file-locking and no version conflicts.
* **If the Application does not run in Shared mode** - multiple people editing the same file at the same time produces application-dependent results. Sometimes one set of changes wins, sometimes the file is corrupted. Coordinate before editing: break work into separate files where possible, agree on who edits what, and communicate through your group's chat.

{% hint style="info" %}
You cannot tell from the student-facing UI whether Shared mode is enabled - it is configured by your instructor. If your group has not been told, assume non-shared mode and coordinate before editing the same file.
{% endhint %}

### Save the group's progress with snapshots

Snapshots in a group Instance work the same way as in your personal Instance, but they preserve everyone's work, not just yours. Take one at the end of each working session and before any major change. See [Take a snapshot](/how-to-guides/common-workflows/snapshots/create-a-snapshot) above.

{% hint style="info" %}
Pick a snapshot-naming convention with your group early - date-based names work well. Anyone in the group can restore a snapshot, which affects the entire Instance and therefore everyone, so coordinate before doing so.
{% endhint %}

## Work with a GPU in a course

<mark style="color:$primary;">**Outcome**</mark>\
You run a GPU-enabled Application during a scheduled lab session or on demand, depending on how your instructor has set up the course.

<mark style="color:$primary;">**Before you start**</mark>

* Your instructor has enabled GPU access for your course.
* You know which workflow your course uses - GPU Lab Sessions or On-Demand GPU.

Nuvolos supports two GPU workflows for courses, and the procedure differs significantly between them. Check with your instructor or the course README which one applies before continuing.

### GPU Lab Sessions

In Lab Session workflows, your instructor schedules specific times during which you have GPU access. You do not start the GPU-enabled Application yourself - the system starts it for you at the scheduled time.

Three rules to follow:

* **Sign up for the course at least one hour before the first scheduled session.** The system processes the attendee list well before each session start, and last-minute sign-ups will not get a GPU-enabled machine.
* **Do not start the Application manually.** If you have an Application running with a non-GPU size when the session begins, the system will restart it with GPU access a few minutes before the start. Any other action on your part is unnecessary.
* **Do not stop the GPU-enabled Application.** The system shuts down all student Applications at the end of the session. If you stop the Application yourself during the session, you will not be able to restart it.

### Confirm your Application has GPU enabled

Hover your mouse over the Application's icon on the left sidebar. A tooltip with a green badge and the GPU model (e.g. *"on Tesla T4 GPU"*) confirms GPU is active.

### **On-Demand GPU courses**

In On-Demand workflows, **you start the GPU-enabled Application yourself**. The Applications view shows three pieces of information you need to monitor:

* **Size column** - displays the GPU model attached to the Application (for example, Tesla T4). You cannot change the size yourself; if no GPU-enabled size is available, contact your instructor.
* **Credit/hour column** - how many Credits it costs to run this Application for one hour.
* **Credit progress bar (top right)** - how much Credit you have used so far against your limit, and the end date of that limit.

{% hint style="info" %}
Credit charges start when you click the start button, not when the web UI loads. To make the most of your Credits, only start the Application when you have at least 30 consecutive minutes to work, and always stop the Application when you no longer need it.
{% endhint %}

### **What happens at the Credit limit**

Each Credit limit has an end date. At midnight UTC on the end date, one of three things happens:

* Your Credit usage resets to zero and a new period with a new limit begins.
* Your Credit usage remains and a new period with a higher limit begins.
* No further limit period is defined - *Credit limit* and *Ends on* show *N/A*. In this case, you cannot run GPU Applications anymore.

Two things to be aware of:

* **Reaching your limit stops all running Applications with a non-zero Credit price.** You must wait for the next limit period to continue.
* **On end dates, running Applications are stopped at midnight UTC** if Credit usage is configured to reset to zero.


# Working with archived courses

## Work with an archived course

<mark style="color:$primary;">**Outcome**</mark>\
You access your work in a course that has been archived, restoring data when needed.

<mark style="color:$primary;">**Before you start**</mark>

* The course has passed its archival date.
* Your work was preserved in at least one snapshot before archival.

Education Spaces have a defined lifecycle: after a fixed period, they are archived automatically. Once a course is archived, your Instance still exists and your work is preserved - but you need to follow specific steps to access it.

### **What archival means for your access**

* Your Application and personal data have been backed up to cold storage.
* Applications cannot be launched in an archived course directly.
* You can restore data from a snapshot, after which you can download files or start the Application again.
* After a few days, your restored Instance is re-archived automatically. To access it again, restore the relevant snapshot once more - there is no limit on how often you can do this.

{% hint style="warning" %}
Archived courses are not for everyday use. Restored snapshots are periodically re-archived without taking new safety backups. Restoring a snapshot in an archived course should serve one of two purposes: either to download specific data, or to distribute files, tables, or Applications to another (active) Space.
{% endhint %}

### **What you see in an archived course**

The Assignments view remains accessible (it moves to the bottom of the sidebar) but is shown in a read-only state:

* Assignment rows are greyed out to indicate the archived state.
* Action buttons (such as submit hand-in or edit assignment) are hidden.
* Clicking on an assignment name does not navigate to the assignment detail page.

You can review your assignment history for reference, but you cannot make changes.

### **Find your archived courses**

{% stepper %}
{% step %}
Either use the **Recent Spaces** on the bottom of the Dashboard or from the sidebar select **Spaces** to open the Space list.
{% endstep %}

{% step %}
In the search bar click **Filters** and toggle on **Courses** and **Inactive**.
{% endstep %}

{% step %}
All archived spaces will be listed once filtered, to see the full list select Rows per page count on the bottom of the list.
{% endstep %}
{% endstepper %}

### **Resume work or download data**

Restore a past snapshot to the Current state, then work in the Instance as before. For the restore procedure, see [Restore from a snapshot](/how-to-guides/common-workflows/snapshots/restore-a-snapshot) above.

Tip: After you restore a snapshot, you have a three-day grace period during which the Current state remains accessible. After the grace period, the contents of the Current state are removed again. If you need more time, restore the snapshot again - there is no limit on repeats.

## Export files and results

<mark style="color:$primary;">**Outcome**</mark>\
You take your work out of Nuvolos as files you can save locally or upload elsewhere.

<mark style="color:$primary;">**Before you start**</mark>

* You know which files or folders you want to export.
* You have at least Instance Viewer access to the Instance containing the files.

### **Download files from the web UI**

* **A single file** - open the Files view, click ... on the file row, and choose DOWNLOAD.
* **A folder** - same Actions menu; the folder is delivered as a ZIP archive.
* **Up to 10 selected items** - select files via the tickboxes and click DOWNLOAD SELECTED in the top menu.
* **Everything in the current folder** - click DOWNLOAD ALL in the top menu.

### **Export an Application**

If you want to take an Application home - for example, to continue working on course code after the course ends - your instructor or you can export the Application as a Docker image. This packages the Application with its configuration and installed packages, and the image will run on any computer with Docker installed.

Application export requires Instance Editor access. See [Reference › Applications](/reference/applications) for the full export procedure.

{% hint style="warning" %}
Exported Application images are public on the Nuvolos container registry. Anyone can use them without authentication. Do not export an Application if its files or installed packages contain personal or sensitive data - and never export with Workspace files included if your Workspace contains assignment files belonging to other students.
{% endhint %}

### **Export tabular data**

If your course uses Nuvolos Tables (the integrated data warehouse), you can export tabular data by running a query and saving the results to a file. For the full procedure, see [Reference › Data storage](/reference/data-storage).


# Leaving a course

<mark style="color:$primary;">**Outcome**</mark>\
You remove yourself from a course on Nuvolos while preserving your Instance and work.

<mark style="color:$primary;">**Before you start**</mark>

* You have clarified the disenrolment policy with your instructor and institution.
* You understand that leaving the course removes your roles in the course but does not delete your Instance or its data.

{% hint style="warning" %}
Nuvolos is not currently linked to any institutional administrative systems. If you need to formally disenroll from the course at your institution, you must take those steps separately. Nuvolos support cannot guide you on institutional procedures.
{% endhint %}

#### Remove yourself from the course

{% stepper %}
{% step %}
Open the course Space from the Dashboard.
{% endstep %}

{% step %}
From the sidebar, click the More options menu (⋯) next to the selected Space name.
{% endstep %}

{% step %}
Click Leave Course.
{% endstep %}
{% endstepper %}

Leaving removes your viewer and editor roles in the course. Your Instance is preserved in case you change your mind, or in case your institution requires retention of your work.


# Workflows for Researchers

These guides answer the question *"how do I do X?"* for researchers who already have working familiarity with Nuvolos. If you are new to the platform, start with the [Researcher tutorials](/tutorials/tutorials-for-researchers) first - they take you from creating your first project to a reproducible, reviewer-ready result.

The guides are organised by where you are in your research lifecycle:

* **Project setup** - create or join a project, add files and code, structure your project, create alternate instances for experimentation.
* **Collaborate and review** - invite collaborators with the right roles, invite an external reviewer.
* **Run analyses and applications** - create, start, and stop applications.
* **Work with data** - set up a dataset, import data, query and write back tabular data from applications.
* **Scale and automate** - use GPUs, scale to HPC, automate with the CLI or Python API.
* **Preserve and share results** - export your project, snapshot and distribute results.

Each page assumes you can navigate Nuvolos's Dashboard, sidebar, and breadcrumbs. If anything in the interface is unfamiliar, see [Getting Started › Find your way around](/getting-started/find-your-way-around).

### Where to go next

* For end-to-end walk-throughs of common researcher workflows (first project, reproducible result, reproducing a colleague's work), see [Researcher tutorials](/tutorials/tutorials-for-researchers).
* For procedures every role shares (invitations, applications, snapshots, distribution), see [How-to › Common Workflows](/how-to-guides/common-workflows).
* For the technical reference on applications, storage, data storage, and configuration, see [Reference](/reference/applications).
* For the conceptual model behind instances, snapshots, distribution, and the data storage architecture, see [Concepts](/concepts/nuvolos-basic-concepts).


# Join an organization

<mark style="color:$primary;">**Outcome**</mark>\
You accept an organisation-level invitation and receive the Faculty or Manager role required to create your own research projects.

<mark style="color:$primary;">**Before you start**</mark>

* A Manager in your target organisation (typically a PI or lab admin) has sent you an invitation.
* You know which identity provider you want to use to sign in (institutional SSO, Google, or Nuvolos).

Researchers are invited in one of two ways: to a specific research space (if you are joining as a collaborator - see the next page) or to an entire organisation (if you will create and manage your own projects). This page covers the organisation-level case.

#### Roles to look for in the invitation

To create and manage your own research projects, you need one of these roles:

* **Faculty** - the standard role for researchers. Lets you create new spaces, manage project data, and control access for collaborators.
* **Manager** - has all Faculty permissions and can additionally manage organisation-wide settings and invite other Faculty members.

If your invitation grants only the Member role, you can't create new spaces. Contact the inviter and ask for a Faculty role instead. For the full role definitions, see [Concepts › Roles, secrets and identity](/concepts/roles-secrets-and-identity).

#### Accept the invitation

The procedure for accepting any Nuvolos invitation is the same regardless of the role. See the canonical procedure: [How-to › Common Workflows › Accepting an invitation](/how-to-guides/common-workflows/accepting-an-invitation).


# Create a research project

<mark style="color:$primary;">**Outcome**</mark>\
You create a new research space, ready to receive files, applications, and collaborators.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the **Organisation Manager** or **Organisation Faculty** role.
* You have a name and description in mind for the project.
* You have decided on visibility - Private is almost always the right choice for active research.

#### Create the Space

{% stepper %}
{% step %}
Navigate to your organisation Dashboard.
{% endstep %}

{% step %}
Click the **+** (plus) icon next to the Spaces list, or click the **+ SPACE** button in the Recent Spaces section at the bottom of the Dashboard.
{% endstep %}

{% step %}
From the dropdown menu, select **Project**.
{% endstep %}

{% step %}
Enter a name and description.

The name must be unique within the organisation, so be descriptive. Both name and description can be edited later.
{% endstep %}

{% step %}
Choose a visibility option.
{% endstep %}

{% step %}
*Optionally add a `README.md` description now, or do this later.*
{% endstep %}

{% step %}
Click **+ ADD SPACE**.
{% endstep %}

{% step %}
*Optionally select an application to add to the Master Instance immediately, or skip and add applications later.*
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Visibility is set at creation and cannot be changed. All other properties - including name, description, and resource pool mapping - can be modified at any time later.
{% endhint %}

For full Space management options including cloning from a Git repository, see [Administration › Space management](/administration/space-management).


# Join a research project

<mark style="color:$primary;">**Outcome**</mark>\
You accept an invitation to an existing research project as a Space Administrator or Instance Editor.

<mark style="color:$primary;">**Before you start**</mark>

* The project Space Administrator has sent you an invitation.
* You have read the invitation and confirmed the role it grants is appropriate.

Joining a research project is by invitation only. The acceptance flow is identical to any other Nuvolos invitation - see [How-to › Common Workflows › Accepting an invitation](/how-to-guides/common-workflows/accepting-an-invitation).

{% hint style="info" %}
Check the role in the invitation before accepting. Common roles for research collaborators are Space Administrator (full control over the project, including the ability to invite others) and Instance Editor (works in one specific instance only). \
For the full role definitions, see [Concepts › Roles, secrets and identity](/concepts/roles-secrets-and-identity).
{% endhint %}


# Add material to the project

<mark style="color:$primary;">**Outcome**</mark>\
You bring files, code, and data into your Master Instance, ready to work on with applications.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** or **Instance Editor** of the project.
* You are in the Current state of the Master Instance.

There are several ways to add research material to a project. Pick the method that matches where the material currently lives:

* **Upload local files** - use the file upload feature in the [Files view](/reference/file-system-and-storage/file-navigator). Best for files on your computer.
* **Clone a Git repository** - use git from a terminal inside any application. For private repositories, add a Nuvolos-generated SSH key to the repository's deploy keys.&#x20;
* **Download from the web** - use `wget`, `curl`, or any download tool from inside an application. Useful when data is available as a public URL.
* **Attach external storage** - mount S3 buckets, SharePoint sites, Dropbox folders, or SSH-accessible servers as folders inside applications.&#x20;

For all storage options and the trade-offs between them, see [Reference › File Storage](/reference/file-system-and-storage).


# Create alternate approaches

<mark style="color:$primary;">**Outcome**</mark>\
You create a new instance branching off from your main work, populated with the files and configuration you want to experiment with.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the project (required to create instances).
* You have decided whether to start from a snapshot or from an empty instance.
* You know which files, tables, or applications you want to copy from the source.

In research, you often need to explore different methods, parameters, or data transformations side by side. Each alternative lives in its own instance within the same space - think of instances as lightweight branches. Each has its own Current state, snapshots, and running applications, but they all share the same project space. For the conceptual model, see [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts).

### Create the new Instance

{% stepper %}
{% step %}
Navigate to the space.
{% endstep %}

{% step %}
Click the **+** (plus) icon next to the Instances list to create a new Instance.
{% endstep %}

{% step %}
Choose whether to start from a snapshot of an existing instance or to create an empty Instance.
{% endstep %}

{% step %}
Give the instance a descriptive name (for example: Model B — ridge regression).
{% endstep %}
{% endstepper %}

For the full Instance management reference, see [Administration › Instance management](/administration/instance-management).

### **Copy material from the source Instance**

Use distribution to copy files, tables, or applications from your main instance:

{% stepper %}
{% step %}
Navigate to the source Instance (typically the Master Instance).
{% endstep %}

{% step %}
On the Files, Tables, or Applications view, select the items you want to copy and click **STAGE** or **STAGE SELECTED**.
{% endstep %}

{% step %}
On the sidebar, click the share icon to open the Stage.
{% endstep %}

{% step %}
Click **CONTINUE**.
{% endstep %}

{% step %}
Select the new Instance as the target.
{% endstep %}

{% step %}
Confirm and complete the distribution.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Distribution runs in the background. You will receive an email when it completes. If it fails, contact <support@nuvolos.cloud>.
{% endhint %}

### Switch between Instances

Once you have multiple instances, use the third element of the breadcrumbs to switch context. For navigation tips, see [Getting Started › Find your way around](/getting-started/find-your-way-around).

### Compare and consolidate

You can distribute results back from the alternate instance to the Master Instance when an experiment proves successful. Use snapshots to preserve the state of each approach for later comparison.


# Invite collaborators

<mark style="color:$primary;">**Outcome**</mark>\
You invite co-authors and colleagues to your research project with the role that matches their level of involvement.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the project (project creators automatically receive this role).
* You have decided which role each collaborator should hold (Space Administrator vs. Instance Editor - see below).
* You have the email addresses of the collaborators.

Pick the role first, then send the invitation. The two common collaborator patterns:

* **Space Administrator** - gives the collaborator every privilege on the project: editing every instance, inviting more users, creating new instances, and deleting the project. Use for co-authors who need full control.
* **Instance Editor** - limits the collaborator to one specific instance. They cannot create instances, invite users, or modify anything outside that instance. Use for contributors with a defined scope.

For the full role and capability matrix, see [Concepts › Roles, secrets and identity](/concepts/roles-secrets-and-identity).

### Invite co-authors as Space Administrators

{% stepper %}
{% step %}
Navigate to the project Space.
{% endstep %}

{% step %}
From the sidebar, click the More options menu (⋯) next to the selected Space name, choose **Invite Users.**
{% endstep %}

{% step %}
Select **Option 2 — Administrator Invitation**.
{% endstep %}

{% step %}
Enter the email addresses of the co-authors.
{% endstep %}

{% step %}
Click **INVITE**.
{% endstep %}
{% endstepper %}

### Invite collaborators as Instance Editors

{% stepper %}
{% step %}
Navigate to the project Space.
{% endstep %}

{% step %}
From the sidebar, click the More options menu (⋯) next to the selected Space name, choose **Invite Users.**
{% endstep %}

{% step %}
Select **Option 1 — User Invitation**.
{% endstep %}

{% step %}
Select the Instance and the role you want to assign.
{% endstep %}

{% step %}
Enter the email addresses of the collaborators.
{% endstep %}

{% step %}
Click **INVITE**.
{% endstep %}
{% endstepper %}


# Invite an external reviewer

<mark style="color:$primary;">**Outcome**</mark>\
You give an external reviewer (such as a journal editor) an isolated copy of your complete research environment to inspect and re-run, without exposing any of your other work.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** of the research project.
* Your research project contains everything the reviewer needs: Applications, source code, and data.
* You understand that this approach is not suitable for double-blind anonymous review (see *Limitations* below).

The pattern is straightforward: take a snapshot of your work, create a dedicated instance for the reviewer, distribute the snapshot into it, then invite the reviewer to that single instance only.

### Set up the reviewer Instance

{% stepper %}
{% step %}
Take a snapshot of the Instance containing your complete research environment.&#x20;

See [How-to › Common Workflows › Create a snapshot](/how-to-guides/common-workflows/snapshots/create-a-snapshot).
{% endstep %}

{% step %}
Create a new instance in the same space.

See [Create alternate approaches](/how-to-guides/workflows-for-researchers/create-alternate-approaches) above.
{% endstep %}

{% step %}
Distribute the snapshot from step 1 to the new instance.

See [How-to › Common Workflows › Distribute content](/how-to-guides/common-workflows/object-distribution).
{% endstep %}

{% step %}
Invite the reviewer to the new Instance as an Instance Editor.&#x20;

See [Invite collaborators](/how-to-guides/workflows-for-researchers/invite-collaborators) above.
{% endstep %}
{% endstepper %}

The reviewer can now access an exact copy of your environment, re-run code, and verify your results - without seeing anything else in your organisation.

### **Limitations**

* **Not suitable for anonymous reviewers**. As the Space Administrator, you create the Instance and handle invitations directly, so you will always know the identity of users in your Space.
* **Reviewers cannot invite others**. Instance Editor does not include the right to invite further users. If a journal editor needs to bring in additional reviewers, they cannot do so with this setup - they must ask you to extend the invitations.


# Run analyses and applications

## Create an Application

<mark style="color:$primary;">**Outcome**</mark>\
You add a new application (JupyterLab, RStudio, MATLAB, VS Code, or similar) to an instance in your project.

<mark style="color:$primary;">**Before you start**</mark>

* You are an **Instance Editor** or **Space Administrator** of the target instance.
* You are in the Current state of the instance.
* You know which application type you need.

#### Add the Application

{% stepper %}
{% step %}
Navigate to the space and the instance.
{% endstep %}

{% step %}
Make sure you are in the **Current state**.
{% endstep %}

{% step %}
On the sidebar, click the screen icon (**Applications**) to open the Applications list.
{% endstep %}

{% step %}
Click **+ ADD NEW APPLICATION** in the top left.
{% endstep %}

{% step %}
In the Application Marketplace, find the Application you want.
{% endstep %}

{% step %}
Click **+ INSTALL**.
{% endstep %}
{% endstepper %}

For all available Applications, their resource sizes, and the full configuration options, see [Reference › Applications](/reference/applications).

## Start an Application

<mark style="color:$primary;">**Outcome**</mark>\
You launch an application and open it ready for use.

<mark style="color:$primary;">**Before you start**</mark>

* The application has been added to an instance you have access to.
* You are signed in to Nuvolos.

The procedure for starting an application is the same regardless of the role. See the canonical procedure: [How-to › Common Workflows › Starting an Application](/how-to-guides/common-workflows/starting-an-application#starting-an-application).

{% hint style="info" %}
Application startup typically takes 30–60 seconds. The first start of a newly created Application may take longer if dependencies are still being initialised.
{% endhint %}

## Stop an Application

<mark style="color:$primary;">**Outcome**</mark>\
You stop a running application to free up resources and stop accumulating NCU or Credit consumption.

<mark style="color:$primary;">**Before you start**</mark>

* You have a running application you want to stop.

Stopping applications when you are done is good research-budget hygiene: you stop consuming resources you do not need. The procedure for stopping an application is the same regardless of the role. See the canonical procedure: [How-to › Common Workflows › Stopping an Application](/how-to-guides/common-workflows/stopping-an-application).

{% hint style="info" %}
Nuvolos auto-stops idle applications after 6 hours (Included sizes) or 1 hour (Credit-based sizes) in research spaces. Stopping explicitly frees resources sooner. The inactivity limit can be configured per application - see [Reference › Applications](/reference/applications).
{% endhint %}


# Set up a dataset

<mark style="color:$primary;">**Outcome**</mark>\
You create a dataset space with the right visibility and populate it with curated data via distribution.

<mark style="color:$primary;">**Before you start**</mark>

* You hold the **Organisation Faculty** role (required to create a new space).
* You have decided on visibility - Private, Faculty-only, or Public - and understand that this can't be changed later.
* Your data has been prepared in a regular research space (a pipeline run, manually curated, or imported).

Dataset Spaces are specialised spaces for hosting finished, curated data and its documentation. Unlike research spaces, you can't run applications in a dataset space - they are sources of data and distribution. For the conceptual model and design guidelines (one dataset per space, vintages, name uniqueness within vintages), see [Concepts › Data storage](/concepts/data-integration).

### Create the dataset space

{% stepper %}
{% step %}
Navigate to the Dashboard.
{% endstep %}

{% step %}
Click **+ NEW DATASET** in the Datasets section.
{% endstep %}

{% step %}
Enter a name and description.
{% endstep %}

{% step %}
Choose the visibility (see below).
{% endstep %}

{% step %}
Click **+ ADD SPACE**.
{% endstep %}
{% endstepper %}

Visibility options:

* **Private** (default) - visible only to users you explicitly invite.
* **Faculty-only** - visible to all Faculty users in the organisation.
* **Public** - visible to all users in the organisation. Public visibility does not automatically grant access to the contents - users initially receive the Instance Observer role and must request the Viewer role to access data.

{% hint style="info" %}
You can't run applications in dataset spaces. The intended workflow is to prepare data in a regular research space, then distribute the finished data to the dataset space.
{% endhint %}

### Prepare your data in a research space

Dataset Spaces hold static information. The recommended workflow is:

{% stepper %}
{% step %}
Set up a regular research space where you can run applications and develop your data pipeline.
{% endstep %}

{% step %}
Execute the pipeline (ETL steps, transformations, cleaning) until the data is in its final form.
{% endstep %}

{% step %}
Keep the research space as the long-term home for the pipeline - dataset spaces only hold the published artefacts.
{% endstep %}
{% endstepper %}

For the tools and patterns of building data pipelines on Nuvolos, see [Import data](/how-to-guides/workflows-for-researchers/importing-data-on-nuvolos) below.

### Distribute your finished data to the dataset space

Once your pipeline is complete:

{% stepper %}
{% step %}
Stage the tables or files to distribute from the source research space.
{% endstep %}

{% step %}
Open the distribution flow.
{% endstep %}

{% step %}
Choose the dataset space (and the appropriate instance) as the target.
{% endstep %}

{% step %}
*Optionally include an application - useful as a documentation aid or a software library blueprint, even though the application cannot run in the dataset space.*
{% endstep %}

{% step %}
Complete the distribution.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Before distributing an updated dataset, clean up the Current state in the dataset space first. This ensures the next vintage starts from a clean baseline and does not carry over leftover artefacts from the previous one.
{% endhint %}

### Snapshot the dataset as a named vintage

Once distribution completes, create a named snapshot of the dataset space with a full description of the data's provenance and date. Nuvolos calls these snapshots **vintages** because the same dataset evolves over time - for example, a financial dataset updated quarterly has one vintage per quarter.

See [How-to › Common Workflows › Create a snapshot](/how-to-guides/common-workflows/snapshots/create-a-snapshot) for the snapshot procedure. For the conceptual model of vintaging, see [Concepts › Data storage](/concepts/data-integration).

### How public datasets work

Public datasets are visible to all members of an organisation, but visibility ≠ access:

* Users in a Public dataset space initially receive the Instance Observer role.
* To access the contents, they must request the Instance Viewer role.
* The organisation manager reviews and approves these requests - see [Administration › Organisation administration](/administration/organisation-management).


# Import data

How do you import data onto Nuvolos?

<mark style="color:$primary;">**Outcome**</mark>\
You bring external data into Nuvolos using the import method that matches the data source.

<mark style="color:$primary;">**Before you start**</mark>

* You know where the data currently lives (local files, external storage, a public URL, or another database).
* You have decided whether the data will land in the Nuvolos file system, the data warehouse, or Large File Storage.

#### Where the data will land

Three storage targets are available in Nuvolos. Pick the one that matches your data size and usage pattern:

* **Nuvolos file system** - for flat files (CSV, [Parquet](https://parquet.apache.org/), code, documents). Suitable for the 1 GB–100 GB range.
* **Scientific Data Warehouse** - for tabular data that benefits from SQL queries and joins. Suitable for datasets where row-level access patterns matter.
* **Large File Storage** - for very large files (above 100 GB) that do not change often. See [Reference › File Storage](/reference/file-system-and-storage/large-file-storage).

### Data pipelines (ETL)

A data pipeline is a chain of processes that extracts data from a source and stores it in a target. Typical sources include files over the internet, web-scraped pages, or existing databases.

For running data pipelines on Nuvolos, we recommend the [Apache Airflow](/how-to-guides/application-specific-guides/apache-airflow) application. Airflow lets you build complex workflows as directed acyclic graphs, mixing script languages and command-line operations, with built-in monitoring, failover, and scheduling.

For Airflow best practices, see the [Apache Airflow documentation](https://airflow.apache.org/docs/apache-airflow/stable/best-practices.html). For application-specific guidance on running Airflow on Nuvolos, see [Reference › Applications](/reference/applications).

### File uploads

Two paths for getting files into Nuvolos:

* **The Files view in the web UI** - best for individual files up to a few hundred MB.&#x20;
* **Application-specific upload UIs** - sometimes more suitable for larger files. For example, RStudio and JupyterLab both have built-in upload features that handle interrupted uploads better than the web UI for very large files.

### Download directly from a URL

If the data you need is available at a public URL, do not download it to your computer first. Use `wget` (available in every Nuvolos application) from a terminal:

{% code overflow="wrap" %}

```sql
wget <url>
```

{% endcode %}

See the [wget documentation](https://man7.org/linux/man-pages/man1/wget.1.html) for options.

### **Mount external storage**

Many cloud storage services can be mounted as folders inside your applications. The supported list includes Amazon S3, Azure Files, Dropbox, Google Drive, Box, Mega, and SharePoint Online. Mounting avoids the need to copy data into Nuvolos - the data stays in its origin storage and is accessed live by applications.

For the full list of mountable services, see the [rclone overview](https://rclone.org/overview/). For the specific Nuvolos integrations, see [Reference › File Storage](/reference/file-system-and-storage) - the connector pages cover Dropbox sync, S3 buckets via rclone, SSHFS, and SharePoint.

Detailed guidance on some relevant, non-trivial use-cases:

* [SSHFS](/reference/file-system-and-storage/access-remote-files-with-sshfs)
* [SharePoint Online](/reference/file-system-and-storage/access-files-on-sharepoint-online)


# Database research workflow - Matlab & RStudio

<mark style="color:$primary;">**Outcome**</mark>\
You query data from the Scientific Data Warehouse, analyse it in MATLAB or RStudio, and write results back as a new table.

<mark style="color:$primary;">**Before you start**</mark>

* Tables are activated in your space. See [Reference › Data storage](/reference/data-storage) if not.
* You have at least one MATLAB or RStudio application configured.
* You have identified the source tables for your analysis.

Nuvolos supports a *query–analyse–insert* cycle. The example below uses the Fama-French 5-factor table (`NORTH_AMERICA_5_FACTORS`) joined with a monthly stock returns table - the same pattern extends to any tables you have access to.

A standard skeleton scientific workflow in MATLAB/RStudio can be broken down into three main steps:

1. Query research-relevant data
2. Analyse, transform or otherwise manipulate data
3. Store results

You can create more complex workflows, but they will usually be built from three-step modules like the one above.

## MATLAB workflow

{% stepper %}
{% step %}

### Querying relevant data

After opening the MATLAB application, define your SQL query as a string and execute it:

{% code overflow="wrap" %}

```sql
query_string = "SELECT NAF.*, SM.MPRC, SM.MRET*100 AS SM_MRET_100, SM.MTCAP " + ...
               "FROM NORTH_AMERICA_5_FACTORS NAF " + ...
               "INNER JOIN TIME_SERIES_MONTHLY SM " + ...
               "ON SM.MCALDT = NAF.DATE " + ...
               "WHERE KYPERMNO = 14593";
 
con = get_connection();
dataset_factor = select(con, query_string);
```

{% endcode %}
{% endstep %}

{% step %}

### The simple analysis

Use MATLAB's fitlm to fit a linear regression with an R-style formula:

{% code overflow="wrap" %}

```sql
dataset_factor.EXCESS_RETURN = dataset_factor.SM_MRET_100 - dataset_factor.RF;
 
mod = fitlm(dataset_factor, ...
  'EXCESS_RETURN ~ (-1) + MKT_RF + SMB + HML + RMW + CMA');
 
dataset_factor.FIT_FACTOR_5 = mod.Fitted;
```

{% endcode %}
{% endstep %}

{% step %}

### Write results back

Use the sqlwrite command to push the results back to the warehouse as a new table:

{% code overflow="wrap" %}

```sql
sqlwrite(con, 'APPLE_5FACTOR_FIT', dataset_factor);
```

{% endcode %}
{% endstep %}
{% endstepper %}

## RStudio workflow

{% stepper %}
{% step %}

### Querying relevant data

After opening the RStudio application, define your SQL query as a string and execute it:

{% code overflow="wrap" %}

```sql
query_string <- "
SELECT NAF.*, SM.MPRC, SM.MRET*100 AS SM_MRET_100, SM.MTCAP
FROM NORTH_AMERICA_5_FACTORS NAF
INNER JOIN TIME_SERIES_MONTHLY SM
  ON SM.MCALDT = NAF.DATE
WHERE KYPERMNO = 14593
"
 
conn <- nuvolos::get_connection()
dataset_factor <- dbGetQuery(conn, query_string)
```

{% endcode %}
{% endstep %}

{% step %}

### The simple analysis

Use RStudio's fitlm to fit a linear regression with an R-style formula:

{% code overflow="wrap" %}

```sql
dataset_factor$EXCESS_RETURN <- dataset_factor$SM_MRET_100 - dataset_factor$RF
 
mod <- lm(EXCESS_RETURN ~ (-1) + MKT_RF + SMB + HML + RMW + CMA,
          dataset_factor)
 
dataset_factor$FIT_FACTOR_5 <- mod$fitted.values
```

{% endcode %}
{% endstep %}

{% step %}

### Write results back

As a final step, we write back the results using the data upload command for R:

{% code overflow="wrap" %}

```sql
DBI::dbWriteTable(conn, name = "APPLE_5FACTOR_FIT",
                  value = dataset_factor, batch_rows = 10000)
```

{% endcode %}
{% endstep %}
{% endstepper %}

For the full data warehouse reference - Python and Stata connectors, off-Nuvolos access, ODBC drivers, big-data exports - see [Reference › Data storage](/reference/data-storage).


# GPU Computation

<mark style="color:$primary;">**Outcome**</mark>\
You configure an application to use a GPU, install the right libraries, and verify the setup works.

<mark style="color:$primary;">**Before you start**</mark>

* Your space has credit-based application sizes enabled. See [Administration › Space management](/administration/space-management).
* You have enough Credits in the resource pool mapped to the space.
* You know which framework you will use - PyTorch, TensorFlow, XGBoost, or another.

GPU acceleration on Nuvolos requires two things:

* A GPU-enabled size for the application. By default, applications run on nodes without GPUs. You scale the application to a GPU-enabled size - all of which are [credit-based](/billing/pricing-structure#application-resource-accounting).
* Properly configured libraries. The remainder of this guide covers per-framework setup so your Application actually uses the available GPU.

### Library versions

The NVIDIA device drivers are automatically loaded in all GPU-enabled sizes. However, depending on the software you use, additional components (e.g., CUDA toolkit) might need to be installed via conda.

If you launch an app in a GPU-enabled size on Nuvolos, the `nvidia-smi` [tool](https://developer.nvidia.com/nvidia-system-management-interface) will be available from the command line/terminal. You can use this to check the driver version and monitor memory usage of the card.

```
$ nvidia-smi
Thu Jun  1 08:39:06 2023       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.73.08    Driver Version: 510.73.08    CUDA Version: 11.6     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA A10-4Q       On   | 00000002:00:00.0 Off |                    0 |
| N/A   N/A    P0    N/A /  N/A |    333MiB /  4096MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+
```

{% hint style="info" %}
Due to the underlying virtualization technology in Nuvolos, the `nvidia-smi` tool is currently unable to list processes using the GPU
{% endhint %}

Note that [nvidia-smi reports](https://stackoverflow.com/questions/53422407/different-cuda-versions-shown-by-nvcc-and-nvidia-smi) the CUDA Driver API version in its output (11.6). However, most high-level machine learning frameworks use the CUDA Runtime API as well, which is provided by the CUDA Runtime library. Most frameworks can automatically install the required version of the runtime, so if you're starting from scratch, this should be straightforward to set up.

Please find examples below on how to get started with GPU computations on Nuvolos, or consult the relevant machine learning library documentation directly. If you need additional support, reach out to our team.

### GPU Monitoring

For interactive GPU monitoring, install the nvitop package:

```sql
pip install nvitop
nvitop  # run from a terminal
```

{% hint style="warning" %}
Due to the underlying virtualization technology in Nuvolos, the `nvitop` tool cannot load the details of the processes using the GPU.
{% endhint %}

### Large Language Models

Two practical guidelines for running LLMs on Nuvolos:

* Assess your VRAM requirements first. The [Hugging Face model size estimator](https://huggingface.co/docs/accelerate/main/en/usage_guides/model_size_estimator) is a useful tool.
* Try loading models with quantised parameters before reaching for larger GPU sizes. The Hugging Face transformers library has built-in support for automatic weight quantisation via [PreTrainedModel.from\_pretrained](https://huggingface.co/docs/transformers/main_classes/model#transformers.PreTrainedModel.from_pretrained).

## Python

Installing the right CUDA version for Python packages can be intricate. Start with a clean Application and install your high-level ML library (PyTorch, TensorFlow) first - these libraries pull in the exact CUDA they need. Install other libraries afterwards.

### PyTorch

For PyTorch, pip works better than conda - pip does not try to overwrite system libraries:

```sql
pip3 install torch torchvision torchaudio
```

{% hint style="info" %}
The standard PyTorch pip command installs PyTorch with the latest major CUDA Runtime version (12). On Nuvolos, all GPUs currently support version 12 except the A10 card. If you need to run on an A10, install PyTorch with the older CUDA Runtime version 11.
{% endhint %}

You do not need a GPU available in your application to install PyTorch with GPU support - install on any size, then scale up to a GPU-enabled size. To verify the installation works on a GPU-enabled size:

```sql
import torch
print(torch.cuda.is_available())  # should print True
```

If it completes without an error, your configuration is correct.

{% hint style="info" %}
Note that pip will install the runtime libraries needed by PyTorch, but will **not** set up a complete developer environment that you could use outside Python (see [official notes](https://docs.nvidia.com/cuda/cuda-quick-start-guide/index.html#pip-wheels-linux)). To use tools like nvcc from the command line, please install the [CUDA Toolkit](#cuda-toolkit) via conda instead.
{% endhint %}

### **NVCC (CUDA compiler)**

To compile CUDA executables with [nvcc](https://anaconda.org/nvidia/cuda-nvcc), install the compiler binaries and the C runtime headers:

```sql
conda install -c nvidia cuda-nvcc cuda-cudart-dev
```

Both packages are available in CUDA 11 and 12 versions. For the full toolkit:

{% code overflow="wrap" %}

```sql
conda install -c nvidia cuda-toolkit
```

{% endcode %}

### TensorFlow

To install TensorFlow, we recommend using conda as TensorFlow requires the cudatoolkit package.

```sql
conda install -c conda-forge tensorflow-gpu "cudatoolkit<=CUDA_VERSION"
```

Substitute `CUDA_VERSION` with the version reported by `nvidia-smi`. If you do not need the latest CUDA, start with an older version (such as 11.6) for compatibility with older GPU cards.

{% hint style="info" %}
Install TensorFlow and cudatoolkit from the same conda channel when possible.
{% endhint %}

You don't need a GPU available in your running app to install TensorFlow with GPU support. It's sufficient to scale up to a GPU-enabled size after installation is complete. To test if your installation was successful, execute the following code snippet while on a GPU-enabled size:

```sql
import tensorflow as tf

a = tf.constant([1, 2, 3])
print(a.device)
```

If you see an output similar to

```sql
/job:localhost/replica:0/task:0/device:GPU:0
```

that ends with `GPU:0`, your configuration is correct.

## RStudio

With Machine Learning (CUDA-enabled) RStudio images, you can run GPU computations on GPU-accelerated nodes. These images have the CUDA runtime/toolkit installed as well.

### XGBoost

We recommend using the pre-built experimental binary to get started with XGBoost and R. In a terminal on a GPU node:

```sql
# define version used - update if needed
XGBOOST_VERSION=1.4.1
# download binary
wget https://github.com/dmlc/xgboost/releases/download/v${XGBOOST_VERSION}/xgboost_r_gpu_linux_${XGBOOST_VERSION}.tar.gz
# Install dependencies
R -q -e "install.packages(c('data.table', 'jsonlite'))"
# Install XGBoost
R CMD INSTALL ./xgboost_r_gpu_linux_${XGBOOST_VERSION}.tar.gz
```

Test with the [XGBoost GPU acceleration demo](https://github.com/dmlc/xgboost/tree/master/demo/gpu_acceleration).

### TensorFlow and Keras

You can use TensorFlow with GPU acceleration by following our TensorFlow installation guide and selecting to install version = "gpu" when installing TensorFlow.


# Scale and automate

<mark style="color:$primary;">**Outcome**</mark>\
You scale workloads beyond regular applications and automate Nuvolos operations from scripts.

<mark style="color:$primary;">**Before you start**</mark>

* You have a workload that needs more compute than self-service application scaling provides, or you want to automate Nuvolos operations.
* You have read the conceptual model - see [Concepts › The hierarchy and resource model](/concepts/nuvolos-basic-concepts) for HPC and resource pools.

Three capabilities cover this part of the lifecycle. None of them are duplicated here - they have full reference pages of their own.

* **HPC Spaces and credit-based sizes** - scale individual applications onto dedicated nodes with up to 120 vCPUs / 456 GB RAM and GPU configurations. Enabled per space by a Space Administrator. See [Administration › Space management](/administration/space-management).
* **Nuvolos CLI** - control applications, sessions, and workflows from a shell, either inside Nuvolos or on your local machine. Useful for automated pipelines (start → run script → stop). See [Reference › CLI and Python API](/reference/nuvolos-cli-and-python-api).
* **Nuvolos Python API -** the same operations as the CLI, exposed as Python functions. Useful for integrating Nuvolos into scripts, notebooks, and CI/CD systems. See [Reference › CLI and Python API](/reference/nuvolos-cli-and-python-api).

For large-scale batch workloads that exceed the limits of self-service sizes, contact Nuvolos support to discuss dedicated compute nodes.


# Preserve and share results

## Export your project

<mark style="color:$primary;">**Outcome**</mark>\
You export your application as a portable Docker image that can be run outside Nuvolos.

<mark style="color:$primary;">**Before you start**</mark>

* You are a **Space Administrator** or **Instance Editor** on the Instance containing the application.
* You have decided whether to export the application alone or together with its workspace files.
* You have read the *Important caveats* section below - particularly around licenses and tabular data.

Nuvolos's Application Export feature turns a Nuvolos application into a portable Docker image that runs anywhere Docker runs. This is the recommended way to hand over a complete, reproducible research environment to external collaborators, customers, partners, auditors, or any infrastructure outside Nuvolos. For the conceptual model and the contents of an exported image, see [Concepts › How Applications work](/concepts/applications).

#### When Application Export is the right choice

* You need to share a full project with collaborators you cannot invite to Nuvolos.
* You want to hand over a reproducible environment for review, audit, or archival.
* You need to run the same application setup in another infrastructure or organisation.

#### What you can export

* **Application only** - configuration, installed packages, environment variables, and the runtime setup, without workspace data. This is the most common option for third-party hand-overs.
* **Application together with workspace files** - adds the workspace contents to the image, useful when sharing a full project state including code and data.

#### Run the export

For the step-by-step export procedure (naming the image, including or excluding workspace files, managing exports), see [Reference › Applications](/reference/applications).

#### Important caveats

Before relying on Application Export as a full project handover, three boundaries to be aware of:

* **Licensed Applications** - Nuvolos uses a Bring-Your-Own-License model. To prevent accidental license leakage, license-based Applications and license-related environment variables are not included in exports by default. Contact Nuvolos support if you need a fully functional, licensed package in the export.
* **Tabular data is not bundled -** Data stored in Nuvolos Tables (the Scientific Data Warehouse) is not included in Application exports. If your project depends on tabular data, export it to files (CSV or Parquet) first and adapt your code to work with file-based inputs.
* **Container registry -** Application exports are pushed to Docker Hub by default. For a different container registry, contact Nuvolos support.

{% hint style="warning" %}
Exported images are public on the container registry. Anyone can pull them without authentication. Make sure the application's contents (installed packages, configuration, and - if you opt to include them - workspace files) do not contain sensitive information.
{% endhint %}

## Snapshot and distribute results

<mark style="color:$primary;">**Outcome**</mark>\
You preserve a moment in your research as a named snapshot, and optionally share it with collaborators by distributing it to another instance.

<mark style="color:$primary;">**Before you start**</mark>

* You are an **Instance Editor** or **Space Administrator**.
* You are in the Current State of the instance.
* You know what you want to preserve and (if distributing) where it should go.

Snapshots are the foundation of reproducibility on Nuvolos - they capture files, tables, and application configurations as a single immutable record. Researchers typically use snapshots in three ways:

* **As named research vintages** - snapshot at key milestones (a paper draft, a clean dataset, a working analysis) with a descriptive name and a complete provenance note. The snapshot remains available indefinitely and can be referenced later.
* **As reproducibility packages** - distribute a snapshot to a reviewer instance, or export the application from a snapshot, to give a colleague exactly the working setup you used.
* **As experiment checkpoints** - snapshot before any major change to your analysis. If the change does not work out, restore from the snapshot and you are back where you started.

#### Take a snapshot

The procedure for creating a snapshot is the same regardless of the role. See the canonical procedure: [How-to › Common Workflows › Create a snapshot](/how-to-guides/common-workflows/snapshots/create-a-snapshot).

#### Distribute a snapshot to share it

To share a snapshot with collaborators or reviewers, distribute its contents (in whole or in part) to a target instance:

{% stepper %}
{% step %}
Open the snapshot from the snapshot timeline.
{% endstep %}

{% step %}
Stage the objects you want to share (files, tables, applications, or all of them).
{% endstep %}

{% step %}
Open the distribution flow and select the target instance.
{% endstep %}

{% step %}
Complete the distribution.
{% endstep %}
{% endstepper %}

For the full distribution mechanic, see [How-to › Common Workflows › Distribute content](/how-to-guides/common-workflows/object-distribution) and [Reference › Configuration](/reference/configuration) for the distribution strategy options.

{% hint style="info" %}
Use named snapshots with descriptive names (such as paper-revision-2-data or pre-cleanup-baseline), not auto-generated timestamps. Future-you searching for the right snapshot to restore from will benefit considerably.
{% endhint %}


# Application-specific guides

In this rubric you will find an assortment of helpful guides for configuring, interacting with, and troubleshooting various common applications using Nuvolos.


# Antigravity

Google Antigravity is available on Nuvolos with access to leading-edge AI agents.

## Setup

{% hint style="info" %}
A Google account is needed to use Google Antigravity.
{% endhint %}

Recent versions are available in the Nuvolos applications gallery when you click **`+ADD NEW APPLICATION`** in the Applications view.

To start using Antigravity:

1. In Applications, click +ADD NEW APPLICATION and add Antigravity.
2. Start the application. When Antigravity opens, choose your preferred window theme and agentic behavior settings.
3. When prompted, sign in with your Google account. A Google Chrome window opens inside the application and loads the Google sign-in page.
4. Complete the Google sign-in flow in that Chrome window. You must sign in here even if you already used the same Google account to sign in to Nuvolos.
5. After the Google sign-in succeeds, close the Chrome window and return to Antigravity. The application is then ready to use.

## Usage notes

Google Antigravity on Nuvolos runs as a desktop application exposed through VNC in an Ubuntu 24.04-based virtual machine. Because of licensing restrictions, it uses the [`open-vsx` extension marketplace](https://www.open-vsx.org).

{% hint style="info" %}
If *Persist sessions data in home area between restarts* is disabled in the application configuration, you will need to sign in with your Google account each time you start Antigravity. If repeated sign-in is unexpected, check that this setting is enabled.
{% endhint %}


# JupyterLab

Tips for using JupyterLab on Nuvolos

## Long-running notebooks

If running notebooks via Jupyter, we recommend submitting the notebooks for computation using [papermill](https://papermill.readthedocs.io/en/latest/) and specifying an explicit logfile when executing from the Jupyter terminal. This way you can disconnect from the Jupyter application and the notebook execution can continue whilst be able to monitor run progress.

```
papermill --stdout-file /files/my_job.out --stderr-file /files/my_job.err NOTEBOOK_PATH [OUTPUT_PATH]// Some code
```

{% hint style="info" %}
Note that your Jupyter notebook wil only receive cell output updates as long as the notebook is kept open in the browser. If you reopen a notebook that is still calculating in the background, you won't receive cell output updates. This is standard Jupyter behavior, unrelated to Nuvolos. This is one of the reasons why using tools like Papermill makes sense for long-running notebooks.
{% endhint %}

## Adding a new launcher <a href="#adding-a-new-launcher" id="adding-a-new-launcher"></a>

In some cases it might be useful to have multiple conda environments inside a single JupyterLab application and be able to launch notebooks from the JupyterLab launcher with kernels that run in these environments. We recommend that the kernel specification associated with the new conda environments created is always installed into the base conda environment (and not user / system prefix) to make sure that the kernel/launcher will function well after distributing an application. Our examples below follow this convention. If you don't want to share the application, then you can also follow instructions from other sources where typically the kernel specification is installed into the user home directory. The following can be done from a JupyterLab terminal and shortly afterwards a new Launcher should appear.

#### Python <a href="#python" id="python"></a>

In this case we recommend to create a new conda environment and install a launcher **into the environment** as following:

`conda create env --name my_new_env`

`conda activate my_new_env`

`conda install ipykernel`

`ipython kernel install --prefix=/opt/conda --name "My New Env"`

#### R <a href="#r" id="r"></a>

In this case we recommend to create a new conda environment and install a launcher **into the environment** as following:

`conda create env --name my_new_env`

`conda activate my_new_env`

`conda install r-recommended r-irkernel`

`R -e 'IRkernel::installspec(prefix="/opt/conda")'`**​**

**Julia**

Once you have a working Julia installation, execute the following command in Julia REPL:

```
using Pkg
Pkg.add("IJulia")           # Install IJulia package if not already installed
using IJulia
installkernel()             # Installs the default Julia kernel spec for Jupyter
```

## Accessing a local webserver in the browser

Some Python tools run as local web servers and need to be opened in a browser. In Nuvolos, these services must be exposed through [Jupyter Server Proxy](https://jupyter-server-proxy.readthedocs.io/en/latest/index.html) rather than by connecting directly to a port from your local browser. The example below uses [Tensorboard](https://www.tensorflow.org/tensorboard).

1. Use a JupyterLab application with version later than 3.0.0.
2. Install TensorBoard:

   ```
   pip install tensorboard
   ```
3. Install Jupyter Server Proxy if it is not already available:

   ```
   pip install jupyter-server-proxy
   ```
4. Create `/opt/conda/etc/jupyter/jupyter_server_config.py` with:

   ```
   c.ServerProxy.servers = {
     'tensorboard': {
       'command': ['tensorboard', '--logdir', '/files/tensorboard_logdir', '--port', '{port}'],
       'timeout': 120
     }
   }
   ```
5. Restart the Nuvolos application. After restart, a new TensorBoard launcher appears in the Notebook section of the JupyterLab launcher.
6. Run your TensorFlow job and note the output directory, for example `/tmp/my_fit_1`.
7. Create a symbolic link so TensorBoard reads from that run directory:

   ```
   ln -s /tmp/my_fit_1 /files/tensorboard_logdir
   ```

   \
   If `/files/tensorboard_logdir` already exists, remove it first with `rm /files/tensorboard_logdir`.
8. Open the TensorBoard launcher in JupyterLab. TensorBoard opens using the linked log directory. To inspect a different run, update the symlink and launch it again.

{% hint style="warning" %}
For best performance, write TensorBoard event files to `/tmp`, which is the fastest local storage available to the application. Files in `/tmp` are not preserved across restarts, so move any data you need to persistent storage afterward. If the server starts slowly, increase the configured `timeout` value or refresh the page until the service becomes available.
{% endhint %}

{% hint style="info" %}
If the server application takes a lot of time to start, you might need to increase the timeout value in the example, otherwise you'll need to refresh the page periodically until the server starts.
{% endhint %}

## Creating a ploty dash application from a notebook

Make sure you have the following packages installed (we suggest to do this via `conda` from the `conda-forge` channel).

* `plotly`
* `dash`

Once these are installed, install the JupyterDash extension:

```
pip install jupyter-dash
```

After this you need to make sure that your dash application has the following logic in it:

```python
from jupyter_dash import JupyterDash
# ... your imports

# the next line is key for the application to be routed to JupyterLab properly
JupyterDash.infer_jupyter_proxy_config()

# ... your code


# now it's time to create the app object
# note that normally, you would create via app = Dash(__name__)
# here we instantiate a JupyterDash instance which already has the correct reverse proxy configuration
# you can use all normal arguments you would pass Dash to pass to JupyterDash
app = JupyterDash(__name__)

# ... your code

# run the app - the jupyterlab mode opens the app in a new tab
app.run_server(mode="jupyterlab")
```

{% hint style="info" %}
Note that this procedure relies on the dash application being run in the context of a notebook.
{% endhint %}

## Real-time kernel resource usage monitoring

JupyterLab supports real-time resource monitoring through the `jupyter-resource-usage` [extension](https://github.com/jupyter-server/jupyter-resource-usage). Install it with:

```
pip install jupyter-resource-usage
```

Restart the Nuvolos application after installation. A new metering icon appears in the right sidebar. When a notebook tab is active, the panel shows CPU and RAM usage for the attached kernel, together with host-level CPU and RAM utilization.

{% hint style="info" %}
This extension requires IPyKernel 6.10.0 or later, so it may not work in older JupyterLab versions.
{% endhint %}

## Matplotlib plots with LaTeX

[To render](https://matplotlib.org/stable/users/explain/text/usetex.html) `matplotlib` labels and other text with LaTeX, install a LaTeX environment and the required packages:

1. [Install TinyTex](/reference/applications/install-a-software-package#install-tinytex).
2. Install the TeX packages required by matplotlib:\
   ​`tlmgr install type1cm cm-super underscore dvipng`
3. [Configure your notebook's environment](/reference/applications/install-a-software-package#tinytex-in-notebooks) as described in the linked setup instructions.
4. Run the notebook cell again with `usetex=True.`


# RStudio

For Rstudio we recommend using the 'Local Jobs' feature to run jobs in the background. This way you can submit multiple jobs whilst also making sure the job continues to run if you navigate away from Rstudio without blocking the interface.

[Learn more about local jobs in Rstudio](https://github.com/rstudio/webinars/blob/master/74-background-jobs/slides.pdf).

## Recovering an unresponsive RStudio session

In certain cases RStudio sessions can become unresponsive, due to large amounts of output printed or large amount of data loaded. If restarting the application in Nuvolos doesn't resolve the issue, you can follow the steps in the [Application Troubleshooting](/troubleshooting/troubleshooting/application-troubleshooting) guide to clear the application state.

## RStudio is responsive but it doesn't accept commands

If the RStudio window is still responsive but commands do not run, check the R console prompt. If the prompt starts with `+` instead of `>`, R is waiting for additional input because the previous command is incomplete, for example due to an unclosed brace, parenthesis, or quote.

To continue, either:

* complete the unfinished expression, or
* click in the R Console and press Escape to cancel it.

## Configuring R Session and RStudio

Upon startup, R and RStudio look for several files to control the behavior of your R session, such as setting options, environment variables, or package repositories.

### User and Project Level Configuration

#### .Rprofile

The `.Rprofile` file contains R code that is executed at the start of every R session. It's commonly used to set options (e.g., `options(digits = 3)`) or load frequently used packages.

* **Location**: Can be in your home directory (`~/.Rprofile`) for global settings or in your project's root directory for project-specific settings.
* **Behavior**: R only sources **one** `.Rprofile` file. If a project-level file exists, it will be used, and the user-level file will be ignored. To use both, you must explicitly source the user-level file at the top of your project-level `.Rprofile`: `source("~/.Rprofile")`.
* **Editing**: You can use `usethis::edit_r_profile()` to edit these files.

#### .Renviron

The `.Renviron` file is used to define environment variables. This is the preferred way to store credentials or API keys instead of hardcoding them in scripts.

* **Format**: Variables are defined in a key-value format: `API_KEY=your_secret_key`.
* **Location**: Like `.Rprofile`, it can be at the user or project level. If a project-level file exists, the user-level one is ignored.
* **Editing**: Use `usethis::edit_r_environ()` to edit.

### System-Wide Configuration

#### Rprofile.site and Renviron.site

These are the system-wide equivalents of `.Rprofile` and `.Renviron`. They are specific to a particular version of R and are usually managed by administrators.

* **Location**: They are located in the `R_HOME/etc/` directory. You can find `R_HOME` by running `R.home(component = "home")` in R.
* **Usage**: Often used to set default package repositories for all users of that R version.

#### rsession.conf and repos.conf

In RStudio Workbench or RStudio Server, administrators can configure server-wide package repositories using these files.

* `rsession.conf`: Used when only one repository is configured.
* `repos.conf`: Used when multiple repositories are needed.

## Using Tensorflow and Keras with RStudio

Tensorflow and Keras can be installed via miniconda in Rstudio. To install them, use the following steps:

1. Restart the R session to be in a clean setting (select Session > Quit Session on the top menu)
2. Make sure reticulate can use miniconda via running in the R commands:

```
Sys.setenv("RETICULATE_MINICONDA_ENABLED" = TRUE)
reticulate::install_miniconda()
```

3\. Install tensorflow R package and then call the `install_tensorflow()` function. If you would like to use GPU acceleration, run `install_tensorflow(version="gpu")`:

```
install.packages("tensorflow") 
library(tensorflow)
install_tensorflow() # use install_tensorflow(version = "gpu") for GPU support
```

4\. Install Keras R package and then call the install\_keras() function:

```
install.packages("keras")
library(keras)
install_keras()
```

To test the installation, follow the example from the RStudio website: <https://tensorflow.rstudio.com/guide/keras/#mnist-example>

### GitHub Copilot with RStudio

Starting with RStudio app version R 4.3.2 with RStudio 2023.09, GitHub Copilot can be configured in Global Options.

To use GitHub Copilot in RStudio:

1. Open Tools > Global Options.
2. Open the GitHub Copilot settings.
3. Sign in with your GitHub account and complete the authorization flow.
4. Confirm that your account has an active GitHub Copilot subscription.

{% hint style="info" %}
GitHub Copilot requires a GitHub account with an active GitHub Copilot subscription. It does not use an OpenAI API key. For OpenAI API-based workflows in RStudio, see the ellmer section instead.
{% endhint %}

## Using ellmer with OpenAI GPT-5.2 and other Large Language Models

The `ellmer` package provides a unified interface for interacting with large language models directly from R, including OpenAI's GPT-5.2. This allows you to leverage AI capabilities for code generation, data analysis assistance, and natural language processing tasks within your RStudio workflow.

### Installation

Install the `ellmer` package from CRAN:

```r
install.packages("ellmer")
library(ellmer)
```

### Configuration with OpenAI API

To use `ellmer` with OpenAI's GPT-5.2 model, you need to provide your API key.

{% hint style="warning" %}
You need an OpenAI API key from a paid OpenAI API account. A ChatGPT subscription is not sufficient - you must create an API key at [platform.openai.com/api-keys](https://platform.openai.com/api-keys).
{% endhint %}

We recommend storing your OpenAI API key as a Nuvolos secret, which will be automatically exposed as an environment variable in your application. See [Environment Variables and Secrets](/reference/configuration/environment-variables-and-secrets) for details on how to set up secrets.

Set up your `OPENAI_API_KEY` as a Nuvolos secret. Once configured, the secret will be available as an environment variable when your RStudio application starts, and `ellmer` will automatically detect it.

### Using ellmer with GPT-5.2

Create a chat object to interact with the GPT-5.2 model:

```r
library(ellmer)

# Set OpenAI API key from Nuvolos secret
Sys.setenv(OPENAI_API_KEY = readLines("/secrets/OPENAI_API_KEY", warn = FALSE))

# Create a chat instance with GPT-5.2
chat <- chat_openai(model = "gpt-5.2")

# Send a message and get a response
chat$chat("How do I create a scatter plot with ggplot2?")

# Continue the conversation with context
chat$chat("Can you add a regression line to that plot?")
```

You can also use `ellmer` for more advanced tasks:

```r
# Generate code completions
chat$chat("Write a function that calculates the mean of a numeric vector, handling NA values")

# Get help with data analysis
chat$chat("I have a dataframe with columns 'age', 'income', and 'education'. 
          What statistical tests should I use to analyze relationships?")

# Use streaming for longer responses
chat <- chat_openai(model = "gpt-5.2", stream = TRUE)
chat$chat("Explain the differences between linear and logistic regression")
```

### Additional Configuration

You can customize the model's behavior with additional parameters:

```r
# Configure temperature, max tokens, and other parameters
chat <- chat_openai(
  model = "gpt-5.2",
  temperature = 0.7,
  max_tokens = 2000,
  system_prompt = "You are an expert R programmer and statistician."
)
```

For more information about `ellmer`, consult the package documentation by running `?ellmer` in R or visiting the package's CRAN page.


# VSCode

Tips and tricks for VS Code applications on Nuvolos

VSCode applications are available on Nuvolos as the suggested GUI integrated development environment for Python. All VS Code applications come with a `conda` environment already in place in which you can [install your required packages](/reference/applications/install-a-software-package).

## Installing VSCode extensions

Nuvolos runs [code-server](https://github.com/coder/code-server) in VSCode applications. Because `code-server` uses its own extension marketplace, some extensions available in the [Visual Studio Code Marketplace](https://marketplace.visualstudio.com/) may not appear in the Nuvolos extension browser. Many extensions are also distributed as .vsix files and can be installed manually.&#x20;

To install an extension from a `.vsix` file:

1. Download the extension `.vsix` file.
2. Upload the file to Nuvolos.
3. In VS Code, open the Extensions view.
4. Open the extensions view menu and select Install from VSIX.
5. Choose the uploaded `.vsix` file and complete the installation.

## Persistent terminal sessions

By default, VSCode terminals are vanilla Bash sessions on Nuvolos, which are prone to stop when not used for a longer while. If you plan to run shell commands for hours and want to monitor their output, it's recommended to use [tmux](https://man7.org/linux/man-pages/man1/tmux.1.html) or screen.

### Set tmux as your default terminal

You can configure tmux as your default terminal in VSCode with the following steps

1. Verify with the command `which tmux` if tmux is installed already. If not, you can install it with `conda install tmux`
2. In VSCode, press `Ctrl + Shift + P` and search for `Open User Settings (JSON)`
3. In the opened JSON, add the following block

```
"terminal.integrated.profiles.linux": {
    "tmux": {
        "path": "tmux",
        "args": ["new-session", "-A", "-s", "${workspaceFolder}"],
        "icon": "terminal-tmux",
    },
},
"terminal.integrated.defaultProfile.linux": "tmux",
```

Now every time you open a new terminal, it'll be by default a tmux session. Every [workspace folder](https://code.visualstudio.com/docs/editing/workspaces/workspaces) will have a different named session with the above configuration, e.g.:

1. You can open folder `ABC` in VSCode and start a new terminal, start a long-running script there
2. Change workspace folder to `DEF` in VSCode and start a new terminal. You'll get a different tmux session here
3. Change back to folder `ABC` in VSCode. If you open a terminal, you should see the outputs of your long-running script

## Interactive Python development

The VS Code application is an excellent interactive development environment. You can find a detailed and complete guide for interactive development with IPython [here](https://code.visualstudio.com/docs/python/jupyter-support-py), the following documentation helps you get started quickly in the context of the Nuvolos apps.

### Creating an interactive IPython window in VS Code

VS Code comes equipped with a conda package manager. In order to be able to start interactive IPython windows, you will first need to install some packages into the VS Code app. To do so, take the following steps:

1. Open a VS Code command prompt either by finding **View > Command Palette** in the menu, or by hitting the **Ctrl + Shift + P** key combination.
2. In the VS Code command palette, type Jupyter: Create and the autocomplete should offer you the Create Interactive Window option.
3. You might be prompted to install ipykernel, in this case proceed to do so (this might take a minute or so to complete).\
   \
   **If you have omitted step 3, you can later:**
4. Open a terminal in VS Code. You can do this by finding **Terminal > New Terminal** in the menu or hitting the **Ctrl + Shift + \`** key combination. In the terminal type `conda install --freeze-installed ipykernel` and wait for the process to complete. After that, you should be able to perform steps 1 and 2 without any further issues.

## Accessing a local webserver in the browser

Sometimes you may need to run a local web server in your VS Code application, for example to view TensorBoard or a Streamlit app. Because Nuvolos applications are isolated from one another, you cannot access that server directly from your local browser. Instead, use VS Code port forwarding.

In most cases, VS Code forwards the port automatically after the server starts. To verify this, open the **Ports** tab and check whether the server port appears there.

For example, if you run:

```
python3 -m http.server 9000
```

VS Code should detect the server and show a notification with an option to open it in the browser. You can also open the forwarded service later from the **Ports** tab by selecting **Open in Browser** for that port.

## Debugging Python in VSCode

VS Code provides a visual debugger for Python scripts. To enable it in Nuvolos:

1. Install the [Python Debugger](https://open-vsx.org/extension/ms-python/debugpy) extension.
2. Open the **Run and Debug** view from the left sidebar.
3. Start with the default configuration if you want to debug the Python file currently open in the editor.
4. To create a custom configuration, select the settings or gear control next to **Run and Debug** and add a launch configuration in `launch.json`.
5. In the configuration dropdown, select the debug configuration you want to use, then start debugging.

A common setting to customize is the current working directory. If your script must run from a specific folder, set `cwd` explicitly or use `${fileDirname}` to use the folder of the file being debugged. For more advanced configuration options: <https://code.visualstudio.com/docs/editor/debugging#_launch-configurations>


# Stata

## Profile.do files

Stata is configured with a `sysprofile.do` file, which loads the Nuvolos database connection string into the global macro `conn_str`.

You might also want to specify your own startup Stata commands. This can be done by creating a do file under `~/ado/personal/profile.do`. The folder \~/ado/personal does not exist by default, you will have to create it once.

### Creating your personal folder

You can create your personal Stata startup folder directly from the Stata interface. Stata looks for personal startup files in `~/ado/personal`, so the folder must be created inside your home directory.

To set it up:

1. In Stata, create a new do-file.
2. Save the file in your home folder.
3. In the save dialog, create the folders `ado` and then `personal` if they do not already exist.
4. Save the file as:

```
~/ado/personal/profile.do
```

5. Add any startup commands you want Stata to run automatically when the application starts.

## Installing packages

When you install new packages in Stata using `scc install ...`, by default they are installed to your PLUS directory. This directory is inside your Linux home folder, and thus not visible for other Nuvolos users.

To install packages that are accessible for other Nuvolos users, you can

* Run Stata in [Shared mode](/reference/applications/configuring-applications#run-in-shared-mode). In this case, every Nuvolos user will interact with the same running application which will have its own Linux home folder, so installations in PLUS will be persistent between restarts and visible to all users
* Install the package into the SITE directory by issuing the following command: `net set ado SITE` . All subsequent `scc install` commands will now install to the SITE directory until you restart Stata. Packages installed to SITE will be visible to all users running the same Stata app, even without enabling Shared mode.

## Adding your Stata license file

The applications with description "Stata XX YY with license from Nuvolos secret" are all application images which can be configured to run with a license file provided by you. These application images will only work if there is a `STATA_LICENSE` secret configured in your project. The secret can be either a personal, a space-level or an organisation-level secret.

#### Step 0: Make sure you have a working stata.lic file

Make sure you have the contents of your `stata.lic` file. This file is always located in the Stata installation directory.

* On Windows usually under `C:\Program Files\StataXX`, where XX is the version number, e.g. Stata17, Stata18, etc.
* On Linux it's usually somewhere under `/usr/local/...` - but you can always use the `which` command to locate the Stata binary, and the license file is usually located in the same folder.

Regardless of operating system, the license file is a plain text file that you can open with notepad or your favourite text editor.

#### Step 1: Add your secret

The type of secret (personal, space-level, org-level) is a question of your license type and your personal preference.

{% hint style="info" %}
If multiple people in your project should use the same Stata license and your license terms allow it, it makes sense to configure a space level secret.
{% endhint %}

1. Navigate to the [secret creation](/reference/configuration/environment-variables-and-secrets) screen of your preference.
2. Make sure you name your secret `STATA_LICENSE`. The value of the secret should be the contents of your `stata.lic` file - copy-paste it from your favourite editor, make sure you have no trailing whitespace characters.<br>
3. Save the secret.

#### Step 2: Add the application

Make sure you [add any of the applications](/concepts/applications) with description "Stata XX YY with license from Nuvolos secret".


# MATLAB

MATLAB constructs like [parfor ](https://www.mathworks.com/help/parallel-computing/parfor.html)can be leveraged in applications using local [parallel pools](https://www.mathworks.com/help/parallel-computing/parpool.html).\
Nuvolos will configure MATLAB to use the appropriate number of CPUs automatically, so you can start your parpool with the command:

```
pp = parpool('local');
```

The pool will be deleted after 30 minutes of idle time or with an application restart. To delete it manually, use

```
pp.delete()
```

### Issue with starting the parallel pool

You might have encountered lately the following error message in MATLAB on Nuvolos when starting a new parallel pool:

> Mismatch between number of environment names and values

This is due to a recent change by MathWorks regarding the online login process. The workaround is to issue the following command in the MATLAB terminal:

```
parallel.internal.mwa.ensureLoggedIn()
```

This will open up a dialog where you need to enter again your MathWorks credentials. After that, MATLAB will be able to start the parallel pool.

{% hint style="info" %}
You might not see a blinking cursor in the textbox for your credentials in the popup, but you can still type there.
{% endhint %}

## Using OpenAI LLMs with MATLAB

The [llms-with-matlab](https://github.com/matlab-deep-learning/llms-with-matlab) repository provides a comprehensive interface for connecting MATLAB to large language models like OpenAI's GPT-5. This enables you to leverage AI capabilities for code generation, data analysis, and scientific research tasks directly within your MATLAB workflow.

### Installation

{% hint style="info" %}
The MATLAB R2025b app version in Nuvolos (updated 2026-01-08) already has the llms-with-matlab add-on pre-installed on startup. You can start using it immediately without manual installation.
{% endhint %}

If you're using an older MATLAB version or need to install manually, clone the llms-with-matlab repository and add it to your MATLAB path:

```matlab
% Clone the repository (run in terminal or use MATLAB's system command)
% git clone https://github.com/matlab-deep-learning/llms-with-matlab.git /files/.matlab/llms-with-matlab

% Add the repository to your MATLAB path
addpath('/files/.matlab/llms-with-matlab')
```

Alternatively, you can download the repository as a ZIP file and extract it to your workspace.

### Configuration with OpenAI API

To use the llms-with-matlab tools with OpenAI's GPT-5 model, you need to configure your API key.

{% hint style="warning" %}
You need an OpenAI API key from a paid OpenAI API account. A ChatGPT subscription is not sufficient - you must create an API key at [platform.openai.com/api-keys](https://platform.openai.com/api-keys).
{% endhint %}

We recommend storing your OpenAI API key as a Nuvolos secret, which will be automatically exposed as an environment variable in your MATLAB application. See [Environment Variables and Secrets](/reference/configuration/environment-variables-and-secrets) for details on how to set up secrets.

Set up your `OPENAI_API_KEY` as a Nuvolos secret. Once configured, the secret will be available as an environment variable when your MATLAB application starts.

You can verify the environment variable is available in MATLAB:

```matlab
% Check if the API key is set
getenv('OPENAI_API_KEY')
```

### Basic Chat Completion Example

Here's a simple example to get started with chat completions using GPT-5:

```matlab
% Create an openAIChat object with GPT-5
chat = openAIChat("You are a helpful MATLAB assistant.", ModelName="gpt-5");

% Generate a simple response
response = generate(chat, "How do I calculate the mean of a vector in MATLAB?")

% Continue the conversation with context
messages = messageHistory;
messages = addUserMessage(messages, "What is the best way to visualize data in MATLAB?");
[text, message] = generate(chat, messages);
disp(text);

% Generate code with specific constraints
codePrompt = "Write a MATLAB function that loads a CSV file and plots the first two columns.";
code = generate(chat, codePrompt, MaxNumTokens=500)
```

This will produce responses like:

```matlab
response = 
    "To calculate the mean of a vector in MATLAB, use the mean() function. 
     For example: x = [1, 2, 3, 4, 5]; avg = mean(x);"
```

### Example: Analyzing Scientific Papers and Generating Replication Code

This example demonstrates how to use the llms-with-matlab repository to analyze a scientific paper and generate MATLAB code for replicating the methodology. The example is based on the [AnalyzeScientificPapersUsingFunctionCalls](https://github.com/matlab-deep-learning/llms-with-matlab/blob/main/examples/AnalyzeScientificPapersUsingFunctionCalls.md) workflow.

#### Step 1: Set Up OpenAI Chat with Function Calling

Create an `openAIChat` object configured to interact with GPT-5 and define a custom function for extracting paper details:

```matlab
% Define a function to store paper analysis results
function storePaperAnalysis(paperTitle, methodology, matlabCode)
    filename = "paper_analysis.csv";
    T = table(paperTitle, methodology, matlabCode, ...
              VariableNames=["PaperTitle", "Methodology", "MATLABCode"]);
    writetable(T, filename, WriteMode="append");
end

% Create an openAIFunction to describe the analysis function
f = openAIFunction("storePaperAnalysis", ...
    "Function to store paper analysis including methodology and replication code.");
f = addParameter(f, "paperTitle", type="string", ...
    description="Title of the scientific paper.");
f = addParameter(f, "methodology", type="string", ...
    description="Summary of the paper's methodology.");
f = addParameter(f, "matlabCode", type="string", ...
    description="MATLAB code to replicate the paper's analysis.");

% Create chat objects with GPT-5
paperAnalyzer = openAIChat(...
    "You are an expert in analyzing scientific papers and generating MATLAB code. " + ...
    "Extract the methodology and generate clean, executable MATLAB code for replication.", ...
    Tools=f, ModelName="gpt-5");
```

#### Step 2: Analyze a Scientific Paper

Provide the paper content or URL to the model and request analysis:

```matlab
% Example: Analyze a paper on signal processing
paperContent = "Paper Title: Advanced Signal Processing Using Wavelet Transforms..." + newline + ...
    "Abstract: This paper presents a novel approach to signal denoising using " + ...
    "discrete wavelet transforms (DWT). We apply db4 wavelets with 5 decomposition " + ...
    "levels to noisy ECG signals..." + newline + ...
    "Methodology: 1) Load ECG signal, 2) Apply DWT with db4 wavelet, " + ...
    "3) Threshold detail coefficients, 4) Reconstruct signal using inverse DWT.";

% Request the model to analyze the paper
prompt = "Given the following paper:" + newline + paperContent + newline + ...
    "Extract the methodology and generate MATLAB code that replicates the analysis. " + ...
    "The code should be complete, executable, and include comments explaining each step.";

[text, response] = generate(paperAnalyzer, prompt);
```

#### Step 3: Handle Function Calls and Execute Code

Process the model's response and extract the generated MATLAB code:

```matlab
% Check if the model requested a function call
if isfield(response, "tool_calls")
    funCall = response.tool_calls;
    
    % Verify the function name
    if funCall.function.name == "storePaperAnalysis"
        % Parse the function arguments
        funArgs = jsondecode(funCall.function.arguments);
        
        % Display the generated MATLAB code
        disp("Generated MATLAB Code:");
        disp("=====================");
        disp(funArgs.matlabCode);
        
        % Optionally, save the analysis
        storePaperAnalysis(string(funArgs.paperTitle), ...
                          string(funArgs.methodology), ...
                          string(funArgs.matlabCode));
        
        % Execute the generated code (be cautious with this step)
        % eval(funArgs.matlabCode);
    end
end
```

#### Example Output

The model might generate MATLAB code like this:

```matlab
% Replication Code for: Advanced Signal Processing Using Wavelet Transforms
% This code replicates the wavelet-based signal denoising methodology

% Step 1: Load or generate a noisy ECG signal
fs = 1000; % Sampling frequency (Hz)
t = 0:1/fs:2; % Time vector (2 seconds)
cleanSignal = sin(2*pi*5*t) + sin(2*pi*15*t); % Simulated ECG
noisySignal = cleanSignal + 0.5*randn(size(t)); % Add noise

% Step 2: Apply Discrete Wavelet Transform (DWT)
waveletName = 'db4'; % Daubechies 4 wavelet
level = 5; % Decomposition level
[C, L] = wavedec(noisySignal, level, waveletName);

% Step 3: Threshold detail coefficients (soft thresholding)
sigma = median(abs(C))/0.6745; % Estimate noise level
threshold = sigma * sqrt(2*log(length(noisySignal)));
C_thresh = wthresh(C, 's', threshold); % Soft thresholding

% Step 4: Reconstruct the denoised signal
denoisedSignal = waverec(C_thresh, L, waveletName);

% Step 5: Visualize results
figure;
subplot(3,1,1); plot(t, cleanSignal); title('Clean Signal');
subplot(3,1,2); plot(t, noisySignal); title('Noisy Signal');
subplot(3,1,3); plot(t, denoisedSignal); title('Denoised Signal');
xlabel('Time (s)');
```

### Additional Use Cases

The llms-with-matlab repository supports many other applications:

* **Code optimization**: Ask the model to improve existing MATLAB code
* **Documentation generation**: Generate comments and help text for functions
* **Algorithm selection**: Get recommendations for appropriate algorithms based on your data
* **Debugging assistance**: Describe errors and get suggestions for fixes

For more examples and documentation, visit the [llms-with-matlab repository](https://github.com/matlab-deep-learning/llms-with-matlab).

## MATLAB Copilot

MATLAB Copilot is an AI assistant built for the MATLAB desktop environment. It helps with MATLAB workflows, code generation, code explanations, error troubleshooting, autocomplete, and test creation. It is included with campus-wide MATLAB licenses and does not require a GitHub account, OpenAI account, or API key.

{% hint style="info" %}
MATLAB Copilot is available as part of campus-wide MATLAB licenses and does not require a GitHub account, OpenAI account, or API key. It is a separate service from GitHub Copilot and the OpenAI API integration described above.
{% endhint %}

### Key Features

MATLAB Copilot offers several capabilities to enhance your MATLAB productivity:

* **Chat with MATLAB Copilot**: Ask questions and get responses based on MathWorks documentation and code examples
* **Generate or Modify Code**: Describe the code you want, and MATLAB Copilot will create new code or edit existing code
* **Code Explanations**: Get easy-to-follow explanations of unfamiliar code or add comments to your code
* **Error Explanations**: Receive explanations and troubleshooting recommendations for error messages
* **Autocomplete Code**: Save time with automatically generated code predictions as you type
* **Create Tests**: Generate test cases to verify code correctness (requires MATLAB Test)

### Getting Started

MATLAB Copilot is available in recent versions of MATLAB and requires a valid license. To start using MATLAB Copilot:

1. **Open Copilot Chat**: In the MATLAB desktop, access the Copilot Chat panel from the toolbar or use the keyboard shortcut
2. **Ask Questions**: Type your questions or requests in natural language
3. **Review Suggestions**: MATLAB Copilot will provide code snippets, explanations, or solutions based on your request
4. **Insert Code**: Accept suggestions to insert generated code directly into your scripts

### Example Usage

Here are some common ways to use MATLAB Copilot:

```matlab
% Example 1: Ask for help in Copilot Chat
% "How do I read a CSV file and plot the first two columns?"

% Example 2: Get code explanations
% Select code in the editor, right-click, and choose "Explain Code with Copilot"

% Example 3: Fix errors
% When an error occurs, click on the error message and select "Get help with Copilot"

% Example 4: Generate tests
% Right-click on a function and select "Generate Tests with Copilot"
```

### Best Practices

* **Be specific**: Provide clear and detailed descriptions of what you want to achieve
* **Iterate**: Refine your requests based on the initial responses
* **Verify**: Always review and test generated code before using it in production
* **Learn**: Use explanations to understand MATLAB concepts and improve your skills

For more information about MATLAB Copilot, including tutorials and detailed documentation, visit the [MATLAB Copilot product page](https://www.mathworks.com/products/matlab-copilot.html) or access the [Introduction to MATLAB Copilot course](https://www.coursera.org/learn/matlab-copilot).


# Terminal

The terminal application on Nuvolos is a `xterm` terminal emulator served directly in your browser. The terminal emulation runs the `bash` shell in a persistent tmux session, thus supporting long-running applications.

It also comes with persistent `conda` and `node.js` package managers (via nvm). This means, any packages that you install with these managers will persist between restarts.

## Important shortcuts and tricks

Here are some tips how to use the terminal effectively:

* **Ctrl + A**: Go to beginning of line
* **Ctrl + E**: Go to end of line
* **Ctrl + Left/Right arrow**: Move word-by-word instead of character-by-character
* **Ctrl + U**: Delete from cursor position to beginning of line
* **Ctrl + K**: Delete from cursor position to end of line
* `cd -` : Go back to last used directory

## Clipboard support

You can use `Ctrl + Shift + V` or `Shift + Insert` to paste into the terminal from your host machine's clipboard.

To copy text out from the terminal, highlight the text on the screen with the mouse.

## Exit the main session

When your Nuvolos app starts, a tmux session called `main` is created automatically. If you issue the `exit` command in this session, it'll kill it. This means the next time you try to open the app's window, you'll see a message

```
no sessions
```

Currently there is no way to restart the tmux session from such a state - if you encounter this, please restart the entire app.

## Configuring tmux

You can add your own configuration at `~/.tmux.conf` . The settings will be applied on the next restart of the Nuvolos application, or you can apply them to the current session via `tmux source-file <file>`.

## Tmux cheat sheet

If you need further guidance with tmux, check out this [cheat sheet](https://phoenixnap.com/kb/tmux-cheat-sheet).

## Configuring bashrc

Nuvolos treats .bashrc slightly different than a regular Linux system. Read the [documentation](https://docs.nuvolos.cloud/features/applications/create-a-persistent-.bashrc) on how to set up a persistent .bashrc for your terminal application.


# Terminal \[tmux]

Terminal emulator based on tmux

This terminal emulator is based on [tmux](https://man7.org/linux/man-pages/man1/tmux.1.html). Here are some useful tips for efficient use.

## Important shortcuts and tricks

Here are some tips how to use the terminal effectively:

* **Ctrl + A**: Go to beginning of line
* **Ctrl + E**: Go to end of line
* **Ctrl + Left/Right arrow**: Move word-by-word instead of character-by-character
* **Ctrl + U**: Delete from cursor position to beginning of line
* **Ctrl + K**: Delete from cursor position to end of line
* `cd -` : Go back to last used directory

## Clipboard support

You can use `Ctrl + Shift + V` or `Shift + Insert` to paste into the terminal from your host machine's clipboard.

To copy text out from the terminal, highlight the text on the screen with the mouse.

## Scroll terminal output

The easiest way to scroll up in tmux is to enter copy mode via

```
Ctrl + B, then [
```

Then you can use the arrows/mouse scroll to navigate the terminal output. You can exit copy mode by pressing `q`.

## Exit the main session

When your Nuvolos tmux app starts, a session called `main` is created automatically. If you issue the `exit` command in this session, it'll kill it. This means the next time you try to open the app's window, you'll see a message

```
no sessions
```

Currently there is no way to restart the tmux session from such a state - if you encounter this, please restart the entire app.

## Configuring tmux

You can add your own configuration at `~/.tmux.conf` . The settings will be applied on the next restart of the Nuvolos application, or you can apply them to the current session via `tmux source-file <file>`.

## Tmux cheat sheet

If you need further guidance with tmux, check out this [cheat sheet](https://phoenixnap.com/kb/tmux-cheat-sheet).


# Claude Code

The [Claude Code](https://docs.claude.com/en/docs/claude-code/overview) Nuvolos application enables you to install the popular AI Agent with one click. It is based on the Terminal application and supports long-running sessions.

## Authentication

Claude Code currently enforces a mandatory first-time setup procedure, which means it's not enough to configure the `ANTHROPIC_API_KEY` environment variable alone (although, claude will accept the environment variable without a first-time setup, when used in non-interactive mode: `claude -p your_prompt_here`).

### Configuration files

Claude stores your authentication setup in your HOME folder, in a `~/.claude.json` file. This means, every user using the same Claude app must authenticate themselves independently, when using the very same Nuvolos app.

If you need to, you can run the application in Shared mode. In this case, every Nuvolos user can use the same running application, with the same authentication setup. However, connecting with different users to the same tmux session can yield unexpected results, so use this at your own discretion.

### Skip first-time setup

As the results of the first-time setup configurations are stored in the `~/.claude.json` file, you can distribute this file from your Personal folder along with the Claude app to other instances to skip subsequent first-time setups.


# Gemini CLI

The [Gemini CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#gemini-cli) Nuvolos application enables you to install Google's AI Agent with one click. It is based on the Terminal application and supports long-running sessions.

## Authentication

Gemini CLI supports using an existing API key directly, which means it's enough to configure the `GEMINI_API_KEY` environment variable to use the application. We recommend to use [Nuvolos secrets](/reference/configuration/environment-variables-and-secrets) to store the API key securely.

By using space-level secrets, you can define a shared API key for everyone to use in a specific Nuvolos project.

## Configuration files

Gemini CLI stores your user configurations in your HOME folder, in a `.gemini` subfolder.


# OpenAI Codex

The [Codex CLI](https://github.com/openai/codex) Nuvolos application enables you to install OpenAI's open-source Agent with one click. It is based on the Terminal application and supports long-running sessions.

## Authentication

Codex CLI supports using an existing API key directly, which means it's enough to configure the `OPENAI_API_KEY` environment variable to use the application. We recommend to use [Nuvolos secrets](/reference/configuration/environment-variables-and-secrets) to store the API key securely.

By using space-level secrets, you can define a shared API key for everyone to use in a specific Nuvolos project.

## Configuration files

Codex CLI stores your user configurations in your HOME folder, in a `.codex` subfolder.


# cascadeflow

This guide describes how to configure and deploy **cascadeflow** within a Nuvolos application.

**cascadeflow** is an intelligent AI model cascading library designed to optimize both cost and latency for Large Language Model (LLM) interactions. It functions by dynamically selecting the most appropriate model for each query: simple tasks are handled by smaller, faster, cheaper models, while complex requests are automatically escalated to powerful flagship models only when necessary. By employing techniques like speculative execution and quality validation, cascadeflow can significantly reduce API costs—often by 40-85%—while delivering high-quality results.

## Why use cascadeflow on Nuvolos?

Deploying cascadeflow on the Nuvolos platform unlocks a powerful, hybrid AI development environment tailored for professional data science and research.

### Privacy-First Coding

Securely process code within your Nuvolos container. By routing autocomplete and basic logic tasks to local models (like `qwen3` or `ministral`) running directly in your workspace, sensitive code snippets never leave your secure environment.

### Hybrid Intelligence & Cost Optimization

Development involves thousands of queries, from simple syntax checks to complex architectural reasoning.

* **Zero Cost for Routine Tasks**: Use free, local models for autocomplete and simple edits.
* **Component-Level Routing**: Smartly escalate only the hardest problems to paid APIs (like Anthropic's Claude), significantly reducing API costs.

### High-Availability Performance

The configuration separates the autocomplete engine from the chat engine using parallel ports. This ensures that heavy reasoning tasks (chatting with the agent) never block the instantaneous feedback required for code completion while typing.

### Flexible Research Platform

Nuvolos provides the compute resources to run open-weights models effectively. This setup serves as a customizable template for testing "Mixture of Experts" strategies, allowing you to swap out models without changing your client-side configuration.

***

## Technical Architecture & Setup

This reference architecture implements a proxy layer that manages two parallel local Ollama instances and one external API provider.

<figure><img src="/files/MJD77czvbf45BANb5Ltf" alt=""><figcaption></figcaption></figure>

### Prerequisites

This case study uses the `cascadeflow-openai-proxy` repository available at <https://github.com/nuvolos-cloud/cascadeflow-openai-proxy/>.

### 1. Service Orchestration

To support this hybrid architecture, the workspace uses custom shell scripts to manage the lifecycle of the multiple required processes.

* **`cascadeflow-openai-proxy/start_services.sh`**:
  * Launches **Ollama Instance 1** (Port 11434) for low-latency autocomplete.
  * Launches **Ollama Instance 2** (Port 11435) for parallel processing of chat requests.
  * Initializes the **cascadeflow Proxy** (Port 8000).
  * Manages Python virtual environments and model pulling.
* **`cascadeflow-openai-proxy/stop_services.sh`**:
  * Performs a clean shutdown of all related processes (Proxy and Ollama instances) using tracked PIDs to prevent resource leaks.

### 2. Component Configuration

#### Continue Extension

*File: `/home/datahub/.continue/config.yaml`*

The client side is configured to treat the Proxy as a standard OpenAI provider. Note how tasks are split:

* **Autocomplete** connects directly to `localhost:11434` for maximum speed.
* **Chat/Edit** connects to the Proxy at `localhost:8000`.

```yaml
models:
  - name: cascadeflow
    provider: openai
    model: local-model
    apiBase: http://localhost:8000/v1
    roles: [chat, edit, apply]
  - name: Qwen3 1.7B
    provider: ollama
    model: qwen3:1.7b
    roles: [autocomplete, embed]
```

#### cascadeflow Proxy backend

*File: `cascadeflow-openai-proxy/config.yaml`*

The proxy defines the logic for available models and their costs. It aggregates the disparate providers (Local vs. Anthropic) into a unified list.

| Model Name         | Provider  | Endpoint          | Role                   |
| ------------------ | --------- | ----------------- | ---------------------- |
| **qwen3:1.7b**     | Ollama    | `localhost:11434` | Fast generic tasks     |
| **ministral-3:8b** | Ollama    | `localhost:11435` | Intermediate reasoning |
| **claude-sonnet**  | Anthropic | External API      | Complex coding tasks   |

## Getting Started

1. **Initialize Services**: Open a terminal in your Nuvolos workspace and run:

   ```bash
   ./cascadeflow-openai-proxy/start_services.sh
   ```

   *Wait for the logs to confirm that Ollama instances and the Proxy are active.*
2. **Verify Connections**: Open the **Continue** extension in VS Code. The models should now be available for selection.
3. **Shutdown**: When finished, ensure resources are released:

   ```bash
   ./cascadeflow-openai-proxy/stop_services.sh
   ```


# Apache Airflow

For researchers who require scheduled workflows, Nuvolos supports Airflow as a self-service application. Airflow runs inside a JupyterLab application, making it easy to edit Airflow DAG files, install packages and use the Nuvolos filesystem for data processing.

The JupyterLab application is collaborative, so DAGs can be worked on simultaneously by multiple users in a "Google Docs"-like fashion.

### Configuration

DAGs should be created as Python files in the `/files/airflow/dags` folder, [refer to Airflow documentation](https://airflow.apache.org/docs/apache-airflow/stable/tutorial.html) for an example.

#### Setting up your first DAG

1. Create a new Python file named `/files/airflow/dags/tutorial.py` and copy the contents of the tutorial DAG from [the Airflow tutorial](https://airflow.apache.org/docs/apache-airflow/stable/tutorial.html#example-pipeline-definition).
2. Click on the Airflow tab and click on the All DAGs filter selector on the UI, the DAG should show up on the list like on the screenshot below. It can take up to a minute for the DAG to show up on the list, as Airflow is periodically scanning Python files the `/files/airflow/dags` folder for new DAG definitions.
3. Click on the slider toggle next to the `tutorial` DAG name to enable the DAG and start the first execution.
4. You should quickly see that the DAG has executed successfully by seeing a *1* in a green circle in the *Runs* column.

Airlfow Connections and Variables can be configured on the Airflow UI.

Airflow on Nuvolos uses a CeleryExecutor back-end to be able to execute tasks in parallel.

### Installing packages

To install packages used in DAGs, open a JupyterLab terminal and pip / conda / mamba install the required package. See the [Install a software package](/reference/applications/install-a-software-package) chapter for detailed instructions.

### Logs

Task execution, scheduler and DAG bag update logs are in `/files/airflow/logs`.

### Saving data to Nuvolos

The following example DAG downloads CSV-style time series data from an API, saves it as a compressed Parquet file, and uploads it as a Nuvolos table. Airflow uses the database credentials of the user who started the application.

#### Prerequisites

1. Create and start a new Airflow application in your working instance.
2. Open a new terminal tab and install the required packages:
   1. `mamba install -y --freeze-installed -c conda-forge pandas-datareader`
   2. `mamba install -y --freeze-installed -c conda-forge pyarrow`
3. Save the example script as `/files/airflow/dags/csv_to_nuvolos`. After saving the file, wait a few seconds for the new DAG to appear in the Airflow tab.

```python
""" Example DAG to demonstrate how to download a time series as a CSV file, 
convert it to Parquet then upload it to Nuvolos. """
from datetime import datetime, timedelta

from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.models import Variable


def export_to_parquet(series, start, end):
    """ Downloads a time-series from St. Luis FRED and exports it as a Parquet file. """
    import pandas_datareader as pdr

    df = pdr.get_data_fred(series, start=datetime.strptime(start, "%Y-%m-%d"), end=datetime.strptime(end, "%Y-%m-%d"))
    df.reset_index(inplace=True)
    df.to_parquet("/files/fred_data.parquet")
    

def upload_data():
    from nuvolos import get_connection, to_sql
    import pandas as pd
    
    df = pd.read_parquet("/files/fred_data.parquet")
    with get_connection() as conn:
        to_sql(df=df, name="fred_data", con=conn, if_exists='replace', index=False)


default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'email': ['airflow@example.com'],
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5),
}

with DAG(
    'csv_to_nuvolos',
    default_args=default_args,
    description='CSV upload to Nuvolos example DAG',
    schedule_interval=None,
    start_date=datetime(2021, 1, 1),
    catchup=False,
    tags=['example'],
) as dag:
    
    t1 = PythonOperator(
        task_id='export_to_parquet',
        python_callable=export_to_parquet,
        op_kwargs = {
            "series" : ['TB3MS'],
            "start" : "1934-01-01",
            "end" : "2021-10-01"
        },
    )
    t1.doc_md = """#### FRED data download
Downloads time-series data from FRED and saves them to /files/fred_data.parquet.
"""

    t2 = PythonOperator(
        task_id='upload_to_nuvolos',
        python_callable=upload_data
    )
    t2.doc_md = """#### Data upload to Nuvolos
Uses the [to_sql function](https://docs.nuvolos.cloud/data/upload-data-to-nuvolos#1.-python) of the Nuvolos connector to upload the data as a Nuvolos table.
"""
    t1 >> t2
```

4. Enable the `csv_to_nuvolos` DAG with the **toggle switch** next to its name.
5. Select the **play** button to trigger a DAG run manually.
6. Select the DAG name to open its detail view and monitor task progress. Completed tasks appear in dark green.
7. After the DAG succeeds, open the **Tables** view to verify that the output table was created.

### Airflow with VSCode

Airflow is also available bundled with VSCode, which can make DAG development easier. To use it:

1. In the applications gallery, choose the latest **Airflow + Code-server + Python** application.
2. After the application starts, open the **Command Palette** with `Ctrl + Shift + P` on Windows/Linux or `Command + Shift + P` on macOS.
3. Search for **Airflow** and select **Airflow: Show Airflow**.
4. Airflow opens in a new VSCode tab. Use that tab to view and manage DAGs.
5. To install additional Python dependencies, open a **Terminal** in VSCode and run:

   ```
   mamba install -y -c conda-forge --freeze-installed <package_name>
   ```


# PXDesign and Protenix

[PXDesign](https://github.com/nuvolos-cloud/PXDesign) is a model suite for de novo protein-binder design. It combines a diffusion generator (PXDesign-d) with [Protenix](https://github.com/bytedance/Protenix) and AlphaFold2-IG (AF2-IG) confidence models to score and rank generated binders. Across seven benchmark targets, PXDesign delivers 17–82% nanomolar hits on six.

On Nuvolos, `pxdesign` is pre-installed in a dedicated conda environment along with all required model weights for Protenix and AlphaFold2. No additional installation or weight downloads are needed.

## Quick Start

This guide walks you through a complete binder-design task using the bundled PDL1 demo input.

### Step 1: Open a Terminal and activate the environment

Launch a **Terminal** application on Nuvolos and activate the `pxdesign` conda environment:

```bash
conda activate pxdesign
```

All subsequent commands assume this environment is active.

### Step 2: Prepare the input YAML

Create a YAML file that describes your design task. You can copy the template below, or use the pre-built demo file at `/files/example/PDL1_quick_start.yaml`.

```yaml
target:
  file: "/files/example/5o45.cif"       # Path to the target structure (CIF or PDB)
  chains:
    A:
      crop: ["1-116"]                    # Region of chain A to keep
      hotspots: [40, 99, 107]            # Interface residues that guide diffusion
      msa: "/files/example/msa/PDL1/0"  # Pre-computed MSA directory (recommended)

binder_length: 80                        # Length of the binder to design (residues)
```

> **Tip:** Before running a full job, validate your YAML with:
>
> ```bash
> pxdesign check-input --yaml /files/example/PDL1_quick_start.yaml
> ```

### Step 3: Run the pipeline

Execute the full pipeline in **extended mode** (Protenix + AF2-IG evaluation). The command below runs 10 samples as a quick test:

```bash
pxdesign pipeline \
  --preset extended \
  -i /files/example/PDL1_quick_start.yaml \
  -o /files/example/test_run \
  --N_sample 10 \
  --dtype bf16 \
  --use_fast_ln True \
  --use_deepspeed_evo_attention True
```

| Flag                            | Recommended value                | Notes                                                       |
| ------------------------------- | -------------------------------- | ----------------------------------------------------------- |
| `--preset`                      | `extended`                       | Full pipeline with AF2-IG + Protenix evaluation             |
| `--N_sample`                    | 10 (test) / 10 000+ (production) | More samples → higher chance of finding nanomolar binders   |
| `--dtype`                       | `bf16`                           | Use `fp32` on older GPUs (e.g., V100)                       |
| `--use_fast_ln`                 | `True`                           | Optimized LayerNorm kernels; generally safe to keep enabled |
| `--use_deepspeed_evo_attention` | `True`                           | DeepSpeed Evo attention for Protenix; requires CUTLASS      |

> **First-run notice:** The very first execution performs one-time kernel compilation. Subsequent runs are significantly faster.

### Step 4: Check the results

Results are written to `<out_dir>/design_outputs/<task_name>/`. Open `summary.csv` to see all ranked binder candidates:

```
/files/example/test_run/design_outputs/PDL1_quick_start/
├── summary.csv                  ← Master ranked list with all scores
├── server_xx_mode.png           ← Diagnostic plot showing task difficulty
├── task_info.json               ← Run metadata
├── orig_designed/               ← Raw backbone structures from the diffusion model
├── passing-AF2-IG-easy/         ← Designs passing the AF2-IG-easy filter
└── passing-Protenix-basic/      ← Designs passing the Protenix-basic filter
```

The `summary.csv` contains boolean `*-success` columns for each filter. Use these to quickly select candidates:

| Filter                   | Criteria                              |
| ------------------------ | ------------------------------------- |
| `AF2-IG-easy-success`    | ipAE < 10.85, ipTM > 0.5, pLDDT > 0.8 |
| `AF2-IG-success`         | ipAE < 7.0, pLDDT > 0.9               |
| `Protenix-basic-success` | binder ipTM > 0.8, binder pTM > 0.8   |
| `Protenix-success`       | binder ipTM > 0.85, binder pTM > 0.88 |

## Example files

The `/files/example/` directory contains everything needed to run the PDL1 demo out of the box:

| Path                                   | Description                      |
| -------------------------------------- | -------------------------------- |
| `/files/example/PDL1_quick_start.yaml` | Ready-to-use input configuration |
| `/files/example/5o45.cif`              | PDL1 target structure (mmCIF)    |
| `/files/example/msa/PDL1/0`            | Pre-computed MSA for chain A     |

## Further reference

For detailed documentation on input preparation, running modes, output interpretation, and wet-lab validation workflows, refer to the [PXDesign README on GitHub](https://github.com/nuvolos-cloud/PXDesign?tab=readme-ov-file).


# Apache Superset

## Starting out with Superset

Superset is available in Nuvolos spaces where Tables are activated.&#x20;

To add it to your instance, open **Applications**, select **Superset**, choose the latest available version, and enter a name for the application. After the application is added, start it. If your instance already contains many tables, the initial load may take a few minutes.

When the application opens, sign in with:

* **Username:** `admin`
* **Password:** `admin`

### Running queries

After you sign in, the Nuvolos connection is already configured in Superset as a Database, and the tables in your instance are already available as Datasets. Open a dataset to preview and query its data without writing SQL. You can also export the query results as a CSV file.

### SQL Lab

To write SQL queries or execute SQL DDL statements, open the SQL editor from the SQL Lab menu. If you want to use a query result for charting, select Explore to save that query as a virtual dataset.

### Uploading CSV files

To upload a CSV file as a dataset, open Data > Upload a CSV. Superset supports small CSV uploads of fewer than 1 million rows. When naming the target table, use an UPPERCASE table name.

### Creating charts and dashboards

You can create charts from either:

* pre-created Datasets based on Nuvolos tables, or
* saved SQL Lab queries that have been stored as virtual datasets.

To create a chart:

1. Open Charts.
2. Select + CHART.
3. Choose the dataset you want to use.
4. Select the chart type.
5. Configure the fields to plot, including the series, grouping, aggregations, and values.

After creating the charts you need, create a dashboard and arrange the charts in the desired layout.

### Further reference

The official Apache Superset documentation is available at: <https://superset.apache.org/docs>.


# D-Wave Inspector

### Prerequisites

You need a D-Wave API key to submit jobs to D-Wave Cloud. You can create a trial account and copy your API key from [D-Wave LEAP.](https://cloud.dwavesys.com/leap/)

To prepare the Nuvolos environment:

1. Open Applications and add a new VSCode app of type Code-Server 4.8.3 +D-Wave to your working instance.
2. Start the application. It creates a demo script at `/files/dwave_test.py`.
3. Open a Terminal and configure your D-Wave Cloud connection with the command:

   ```
   dwave config create
   ```
4. When prompted, paste your D-Wave API key from the [LEAP dashboard](https://cloud.dwavesys.com/leap/).

### Running your first computing job

In the terminal, once you have configured your D-Wave cloud access, run the demo Python script with `python dwave_test.py`.

The following script runs a very simple computation on D-Wave's QPU in the cloud:

```python
import dwave.systemimport dwave.inspector
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite

sampler = EmbeddingComposite(DWaveSampler())
h = {'a': -1., 'b': 2}
J = {('a', 'b'): 1.5}
response = sampler.sample_ising(h, J)

# Inspect
dwave.inspector.show(response, block=dwave.inspector.Block.FOREVER)
```

The last line of the script will open D-Wave Inspector in a new editor tab and block until CTRL+D or CTRL+C is pressed. The D-Wave Inspector application only runs until the script is terminated.


# MLFlow

### Adding an MLFlow app

To add MLflow to your working instance, open **Applications** and select **MLFlow 2.13 + Jupyter**. Start the application, and MLflow opens in a new **JupyterLab editor tab**. If you close that tab, reopen MLflow from the **JupyterLab Command Palette** with `Command/Ctrl+Shift+C`, then run the MLflow command shown there.

### MLFlow in Visual Studio Code

MLflow is also available in the VS Code-based application. To use it, open the VS Code app that includes MLflow, then open the Command Palette and run the MLflow command shown on the page to open MLflow in a new VS Code tab.

### Tracking model training

{% hint style="info" %}
MLFlow server runs on port <http://127.0.0.1:8080>, you will need to set this tracking server in your code with:

`import mlflow`\
`mlflow.set_tracking_uri("http://localhost:8080")`
{% endhint %}

The following tutorial, adapted from the MLFlow documentation, shows how to track model training and register the trained model with MLFlow on Nuvolos:

<pre class="language-python"><code class="lang-python"><strong># The data set used in this example is from http://archive.ics.uci.edu/ml/datasets/Wine+Quality
</strong># P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis.
# Modeling wine preferences by data mining from physicochemical properties. In Decision Support Systems, Elsevier, 47(4):547-553, 2009.

import os
import warnings
import sys

import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import ElasticNet
from urllib.parse import urlparse
import mlflow
import mlflow.sklearn

import logging

logging.basicConfig(level=logging.WARN)
logger = logging.getLogger(__name__)


def eval_metrics(actual, pred):
    rmse = np.sqrt(mean_squared_error(actual, pred))
    mae = mean_absolute_error(actual, pred)
    r2 = r2_score(actual, pred)
    return rmse, mae, r2


if __name__ == "__main__":
    mlflow.set_tracking_uri("http://localhost:8080")
    mlflow.set_experiment("Wine Quality")
    warnings.filterwarnings("ignore")
    np.random.seed(40)

    # Read the wine-quality csv file from the URL
    csv_url = (
        "http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
    )
    try:
        data = pd.read_csv(csv_url, sep=";")
    except Exception as e:
        logger.exception(
            "Unable to download training &#x26; test CSV, check your internet connection. Error: %s", e
        )

    # Split the data into training and test sets. (0.75, 0.25) split.
    train, test = train_test_split(data)

    # The predicted column is "quality" which is a scalar from [3, 9]
    train_x = train.drop(["quality"], axis=1)
    test_x = test.drop(["quality"], axis=1)
    train_y = train[["quality"]]
    test_y = test[["quality"]]

    alpha = float(sys.argv[1]) if len(sys.argv) > 1 else 0.5
    l1_ratio = float(sys.argv[2]) if len(sys.argv) > 2 else 0.5

    with mlflow.start_run():
        lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
        lr.fit(train_x, train_y)

        predicted_qualities = lr.predict(test_x)

        (rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)

        print("Elasticnet model (alpha=%f, l1_ratio=%f):" % (alpha, l1_ratio))
        print("  RMSE: %s" % rmse)
        print("  MAE: %s" % mae)
        print("  R2: %s" % r2)

        mlflow.log_param("alpha", alpha)
        mlflow.log_param("l1_ratio", l1_ratio)
        mlflow.log_metric("rmse", rmse)
        mlflow.log_metric("r2", r2)
        mlflow.log_metric("mae", mae)

        tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme

        # Model registry does not work with file store
        if tracking_url_type_store != "file":

            # Register the model
            # There are other ways to use the Model Registry, which depends on the use case,
            # please refer to the doc for more information:
            # https://mlflow.org/docs/latest/model-registry.html#api-workflow
            mlflow.sklearn.log_model(lr, "model", registered_model_name="ElasticnetWineModel")
        else:
            mlflow.sklearn.log_model(lr, "model")
</code></pre>


# Open WebUI

[Open WebUI](https://docs.openwebui.com/) is an extensible, feature-rich, and user-friendly self-hosted AI platform designed to operate entirely offline. It supports various LLM runners like Ollama and OpenAI-compatible APIs, with built-in inference engine for RAG, making it a powerful AI deployment solution.

### Open WebUI and MCP

Open WebUI is suitable for supporting [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) which is Anthropic's popular framework for connecting AI agents to external tools. Thus, the Open WebUI application offers a user-friendly interface just like that of the web-accessable ChatGPT, Gemini...etc., but with two major advantages. First, the user can access any kind of AI model (OpenAI, Google, Anthropic...) within the same interface. Second, it can be directly connected to external sources that the user wants the agent to see.

### Setting Up Agents in Open WebUI

To add model providers, open Open WebUI, select your user menu in the lower-left corner, and open Admin Panel. Then go to Settings > Connections. Add the API endpoint and API key for the provider you want to use. Open WebUI supports OpenAI-compatible API connections, so OpenAI models can be added directly, while other providers such as Anthropic or Google may require OpenAI-compatible endpoints and explicit Model IDs. For OpenAI models, specifying Model IDs is not required

The specific models can be selected from the LLM providers' sites.\
**Anthropic:**\
<https://docs.anthropic.com/en/docs/about-claude/models/overview>

Google Gemini:\
<https://ai.google.dev/gemini-api/docs/models>

### Setting Up MCP Servers in Open WebUI

Adding MCP servers to Open WebUI has two steps:

1. Create the JSON configuration file that defines the MCP servers, including their source code paths, required packages, and optional port values. When Open WebUI starts, a startup script reads this JSON file and configures the servers from it. If you switch to a different JSON file, update the script accordingly.
2. In Open WebUI, open Settings > Tools and add each MCP server as a tool. For each one:
   * set the URL to the server address and port, for example `http://0.0.0.0:8002`
   * enter a clear Name
   * set Visibility to Public

### Using Open WebUI

#### Turning on Tools

Tools can be enabled or disabled separately for each chat. To choose which MCP servers are available in a conversation, select the + button in the lower-left corner of the chat window and choose the tools you want to use. This is especially useful when multiple tools provide overlapping functionality. For best results, open Chat Controls near the profile icon in the upper-right corner of the chat and set Function *Calling* to *Native*.

#### System Prompts

System prompts provide persistent instructions that influence agent behavior. In Open WebUI, chats can be organized into folders, and each folder can have its own system prompt. Any chat placed in that folder inherits the folder’s system prompt behavior.

### Error Handling, Debugging

If Open WebUI cannot connect to MCP servers or fails to configure agents correctly, review the application logs. Open the Sessions view and select SEE LOGS to inspect startup and runtime messages and identify the root cause.


# Databricks Connect

Nuvolos now offers a VSCode application with Python 3.9 and R 4.2 and Databricks Connect (`databrics-connect`) pre-installed. From this application, you can submit Spark jobs to Databrics-hosted Spark clusters.

[PySpark](https://spark.apache.org/docs/latest/api/python/) and [sparklyR](https://spark.rstudio.com/) are both installed in the application.

### Prerequisites

{% hint style="info" %}
[Databricks Connect](https://docs.databricks.com/dev-tools/databricks-connect.html) supports Databricks clusters up to 10.4 LTS.
{% endhint %}

To configure the connection, you need:

* the URL of your Databricks cluster, and
* a [personal access token](https://docs.databricks.com/dev-tools/api/latest/authentication.html#token-management).\
  Personal access tokens are not available in Databricks Community Edition.

To connect from Nuvolos:

1. Create a **Databricks 10.4 LTS + Py39 + R 4.2** application.
2. Start the application.
3. Open a terminal and run:

   ```
   databricks-connect configure
   ```
4. Enter the [Databricks cluster URL](https://docs.databricks.com/dev-tools/databricks-connect.html#step-2-configure-connection-properties) and your [personal access token](https://docs.databricks.com/dev-tools/api/latest/authentication.html#token-management) when prompted.
5. Verify the setup with:

   ```
   databricks-connect test
   ```

### Python example

To run the example, please install the `slugify` Python package with the following command:

`conda install -y -c conda-forge python-slugify`

Once you have configured the Databricks connection, you can try the following simple example to create a Databricks table and run a SQL query on the table:

```python
import pandas as pd
from pyspark.sql import SparkSession
from slugify import slugify

spark = SparkSession.builder.getOrCreate()
spark.conf.set("spark.sql.execution.arrow.pyspark.enabled","true")

# Use NYC Squirrel Census data
df = pd.read_csv("https://data.wa.gov/api/views/f6w7-q2d2/rows.csv?accessType=DOWNLOAD")
df.columns = [slugify(c, separator="_") for c in df.columns]
df = df.drop(columns=["vehicle_location", "electric_utility"])

df = spark.createDataFrame(df)
df.write.mode('overwrite').saveAsTable('ev_data')

spark.sql('select make, model, count(*) as registered from ev_data group by make, model order by registered desc').show(10)
```

### R example

The `sparklyr` package is pre-installed in the application which allows you to connect to Databricks Spark clusters, configured with `databricks-connect.`

You can run the following R script example to run a simple job on your Databricks cluster:

```r
library(sparklyr)
library(dplyr)

databricks_connect_spark_home <- system("databricks-connect get-spark-home", intern = TRUE)
sc <- spark_connect(method = "databricks", spark_home = databricks_connect_spark_home)

cars_tbl <- copy_to(sc, mtcars, overwrite = TRUE)

cars_tbl %>% 
  group_by(cyl) %>% 
  summarise(
    mean_mpg = mean(mpg, na.rm = TRUE),
    mean_hp  = mean(hp, na.rm = TRUE)
    )

print(as_tibble(cars_tbl), n = 10)

spark_disconnect(sc)
```


# Dynare.jl

### Prerequisites

Nuvolos provides a pre-built application with **Dynare 5.3**, **Julia 1.8**, and the **Dynare.jl** package pre-installed. To get started, add a **Dynare 5.3 + Julia 1.8 + VSCode** application to your working instance.

### Dynare.jl example

Start the application and create a new Julia file `dynare_demo.jl` with the following contents:

```julia
cp("/usr/local/lib/dynare/examples/example2.mod","/files/example2.mod", force=true)

using Dynare

context = @dynare "example2.mod";

using JLD2
DD = load("example2/output/example2.jld2")
```

This example will copy one of the example models provided with Dynare to the Files area (`/files` ) parse and run the calculations on the model. You can run the example either from the command line with the `julia /files/dynare_demo.jl` command, or using VSCode's debugger by pressing the `F5` key.

The output will be saved under `/files/example2/output/example2.jld2` in JLD2 format, which can be processed with the [JLD2 Julia library](https://github.com/JuliaIO/JLD2.jl).

Plots are available under the `/files/example2/output/graphs` folder.

{% hint style="info" %}
This application does not provide a Linux X window display. The plots will not be automatically opened. You can open them with VSCode by double-clicking on the .png files in the file navigator tree view.
{% endhint %}


# CloudBeaver

CloudBeaver is a lightweight web application designed for comprehensive data management. It allows you to work with various data sources, including SQL, NoSQL, and cloud databases, all through a single secure cloud solution accessible via a browser.

## Saving connection details

CloudBeaver runs on Nuvolos in anonymous mode because authentication is handled by Nuvolos. As a result, connections created in the Private project do not persist after the application restarts. To save a connection for reuse, create it in the Shared project instead.

{% hint style="info" %}
If you create a new connection in the Shared project, any user having access to the application (Instance Editors and Space Admins) will be able to see it.
{% endhint %}


# InveLab

The Nuvolos team created InveLab to apply advanced finance models with real financial data to allow students to learn finance concepts intuitively and practically. Among other things, this platform lets students develop the following skills:

* Visualising real financial data.
* Understanding the process of portfolio construction, in-sample & out-of-sample back-testing, international diversification and currency hedging.
* Analysing investable assets, including hedge funds, to assess their ability to generate abnormal performance (alpha).
* Modelling and measuring the dependence among risks, such as Value-at-Risk and Expected Shortfall.
* Practicing various quantitative investment strategies, including factor investments, factor-tilting, etc.

### InveLab editions

The fundamental building blocks in InveLab are *modules*, which represent different operations on financial data. One module might enable visualising a dataset, while another might use the same dataset to compute portfolio weights. Since they generally depend on each other, you don't directly work with individual modules in InveLab. Rather, we have created bundles of modules called *editions.* Editions tell a complete story about some aspect of financial analysis, and guide you through the various modules intuitively.

Each InveLab edition can be installed as an independent Nuvolos application. Currently Nuvolos offers the following editions:

* Alternative Investments
* Global Asset Allocation and Management
* Risk Management in Private Banking
* Data Analysis & Advanced Modelling
* Unified course application
* Regression application

### Workflows

To work with InveLab modules within a given edition, first you need to start a *workflow*. A workflow is a named container for all the objects you work with during your analysis. Whenever you add/modify data in any of the modules, the new state of your workflow will be saved. For this reason, there is no explicit save button in InveLab - anytime you change some objects, a new save is created automatically.

The next time you start InveLab, you can resume your work from where you left off. You can also start multiple workflows in parallel, and run different analysis on them in the same edition.

#### Distributing workflows

In a teaching setting, it can be useful for instructions to prepare workflows for students that already have some prepared data in them, so the students only need to focus on the modules that consume the prepared data.

This can be achieved on Nuvolos in just a few steps:

1. The instructor prepares the workflow(s) in the InveLab edition running in the Master instance of the course space;
2. The instructor distributes the application for all students;
3. Students see the prepared workflows and can work with them.

When distributing an InveLab application, all saved workflows in the Master instance are distributed to student instances, with the following features:

* Workflows can be distributed throughout the course, but students might need to restart their applications to register new incoming workflows
* It is safe for instructors to modify workflows that have already been distributed to students. The next time the application is distributed, the instructor’s changes will not overwrite any changes students have made in their own instances.
* It is not possible to distribute updates to a workflow that has already been distributed once. However, you can duplicate an existing workflow and distribute it as a brand new workflow.

### InveLab modules

Within editions, the structure of InveLab is divided into *objects*, representing financial data types, and *modules*, representing different operations of financial analysis. Modules operate on objects. Some modules have dependencies on others.

Here are some general tips for how to work with InveLab modules:

* Each module requires an input to activate. Certain operations generate and save an output, which can then be used for other modules or functions as an input.
* A new workflow always starts with selecting a dataset (except the valuation module). If an input is missing, the module will show in grey and cannot be entered.
* In any input or output field, you can click the object for operations to **show object information**, **show related objects**, or **delete the object**.
* Deleting the parent object will also delete all child objects.

This table describes the allowed input objects for each module (for object names, please read the **object name** section), where "Y" means that this object category can activate the module as the input:

| Module                    | D | RD/RR | URD | ERD/ERR | PTS | RP/RPP | M | R | MC | SRD | Special Reqs                                                                     |
| ------------------------- | - | ----- | --- | ------- | --- | ------ | - | - | -- | --- | -------------------------------------------------------------------------------- |
| Time-Series Visualisation | Y | Y     | Y   | Y       |     | Y      |   | Y | Y  | Y   |                                                                                  |
| Moment                    |   | Y     | Y   | Y       |     |        |   |   |    |     |                                                                                  |
| Black-Litterman           |   |       |     |         |     |        | Y |   | Y  |     | Both M and MC needed                                                             |
| Dynamic Strategy          |   | Y     | Y   |         |     |        |   |   |    |     |                                                                                  |
| Portfolio Analysis        |   |       |     |         | Y   |        |   |   |    |     |                                                                                  |
| Carry Trade Strategy      | Y |       |     |         |     |        |   |   |    |     | Must have both "Interest Rate 1- Month Monthly" and "Spot Exchange Rate monthly" |
| Conditional Volatility    |   | Y     |     |         |     |        |   |   |    |     |                                                                                  |
| Risk Measures             |   | Y     |     |         |     |        |   |   |    | Y   |                                                                                  |
| Frontiers                 |   | Y     |     |         |     |        |   |   |    | Y   |                                                                                  |
| Mean-Variance Frontiers   |   |       |     |         |     |        | Y |   |    |     |                                                                                  |
| Performance Analysis      | Y | Y     | Y   | Y       |     |        |   |   |    |     |                                                                                  |
| Replication               |   | Y     |     |         |     |        |   |   |    |     |                                                                                  |
| Factor Tilting            |   | Y     |     |         |     |        |   |   |    |     |                                                                                  |
| Factor Factory            |   |       | Y   |         |     |        |   |   |    |     |                                                                                  |
| Benchmarking              |   | Y     |     |         |     |        |   |   |    |     |                                                                                  |

Note that some modules have special requirements for their inputs.

### InveLab objects

The object abbreviations given above correspond to the following meanings:

| Abbreviation | Data type/object category                                 |
| ------------ | --------------------------------------------------------- |
| D            | non-return variables (balanced dataset)                   |
| RD           | total return; return without dividends (balanced dataset) |
| RR           | return reference (one RD)                                 |
| URD          | total return (unbalanced dataset)                         |
| ERD          | excess return                                             |
| ERR          | excess return reference (one ER)                          |
| PTS          | portfolio                                                 |
| RP           | random portfolio                                          |
| RPP          | random portfolio plot                                     |
| M            | moment                                                    |
| R            | non-return reference (one D)                              |
| MC           | market capitalization                                     |
| SRD          | scaled return                                             |
| FR           | frontier (generated via return)                           |
| MFR          | frontier (generated via moments)                          |
| MR           | moving risk                                               |
| CD           | characteristics (e.g. hedge fund's strategy)              |
| UD           | non-total-return variables (unbalanced dataset)           |
| FM           | factor model                                              |

### Basic operations

Below is some additional info for basic operations in InveLab.

#### Date:

**Date range selection** allows you to select the calendar day/month/year to input. You can also write the date directly in the date field with the format yyyy-mm-dd.

**Restrict to periods** can limit the dataset into certain pre-defined date ranges, including:

* Dotcom Bubble (2001)
* Euro-Sovereign Debt Crisis (2010-2012)
* The Great Recession (2007-2009)
* All NBER Recessions

#### Save:

When you can save an object, it is optional to provide a description of the saved object and then save. This will show in the object information.

#### Compare:

When comparing objects, you can choose the same or different objects on the left and right sides for different operations.

### Further information

For a more detailed module-by-module guide to InveLab, please see the [application reference](broken://pages/Qnnr1vzeY1o8HBGz8l0X) section of the documentation.


# Dataset selection

InveLab works by selecting a dataset and a dataset-specific time range (the input), in order to perform operations on it. The result can then be used for further operations (the output). The list of available datasets and valid time ranges is as follows, where **asterisks indicate default values**:

|                                     |                  |                                                                                           |                                                |                                                                                                                                                                                                                                                                                     |
| ----------------------------------- | ---------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Dataset**                         | **Resources**    | **Time Range (Frequency)**                                                                | **Currency**                                   | **Data Type**                                                                                                                                                                                                                                                                       |
| Chinese Equity\*                    | RESSET & WIND    | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>CNY\*</li><li>USD</li></ul>            | <ul><li>Total return\*</li><li>Market cap</li><li>Price adjusted</li><li>Price unadjusted</li><li>Return w/o dividends</li><li>Shares outstanding</li><li>Trading volume</li></ul>                                                                                                  |
| Chinese Index                       | RESSET & WIND    | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>CNY\*</li><li>USD</li></ul>            | <ul><li>Total return\*</li><li>Price adjusted</li></ul>                                                                                                                                                                                                                             |
| Chinese Industry Portfolios         | RESSET & WIND    | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>CNY\*</li><li>USD</li></ul>            | <ul><li>Total return\*</li><li>Price adjusted</li></ul>                                                                                                                                                                                                                             |
| CN Equity Unbalanced                | RESSET & WIND    | <ul><li>Monthly\*</li></ul>                                                               | <ul><li>CNY\*</li></ul>                        | <ul><li>Total return\*</li><li>Average return T-2-12</li><li>Book-to-Market ratio</li><li>Market Cap T-1</li><li>Market Cap</li><li>Price adjusted</li><li>Price unadjusted</li><li>Return without dividends</li><li>Shares outstanding</li><li>Trading volume</li></ul>            |
| CN Factors                          | RESSET & WIND    | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li></ul>                                  | <ul><li>CNY\*</li></ul>                        | <ul><li>Total return\*</li><li>Excess return</li></ul>                                                                                                                                                                                                                              |
| CN Hedge Fund                       | SUNTIME & WIND   | <ul><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul>                              | <ul><li>CNY\*</li></ul>                        | <ul><li>Total return\*</li><li>Net asset value</li><li>Strategy</li></ul>                                                                                                                                                                                                           |
| CN Hedge Fund Index                 | SUNTIME          | <ul><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul>               | <ul><li>CNY\*</li></ul>                        | <ul><li>Total return\*</li><li>Price adjusted</li></ul>                                                                                                                                                                                                                             |
| CN Replication                      | Multiple         | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>CNY\*</li></ul>                        | <ul><li>Total return\*</li></ul>                                                                                                                                                                                                                                                    |
| Exchange Rate                       | Refinitiv        | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>USD\*</li></ul>                        | <ul><li>Carry Trade Return\*</li><li>CIP Excess Return</li><li>Forward 1-Month</li><li>Forward 1-Week</li><li>Forward 3-Month</li><li>Spot Exchange Rate</li><li>Spot Total Return</li></ul>                                                                                        |
| Global Equity Index                 | Refinitiv        | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>Local currency\*</li><li>USD</li></ul> | <ul><li>Total return\*</li><li>Index level</li></ul>                                                                                                                                                                                                                                |
| Global Sovereign Bonds              | Refinitiv        | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>Local currency\*</li><li>USD</li></ul> | <ul><li>Total return\*</li><li>Index level</li></ul>                                                                                                                                                                                                                                |
| Interest Rate                       | Refinitiv        | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Yearly</li></ul>                   | <ul><li>Local currency\*</li></ul>             | <ul><li>Interest rate 1-month\*</li><li>Interest rate 1-week</li><li>Interest rate 2-month</li><li>Interest rate 2-week</li><li>Interest rate 3-month</li><li>Interest rate 6-month</li><li>Interest rate overnight</li></ul>                                                       |
| US Book-to-Market Sorted Portfolios | Fama-French      | <ul><li>Daily</li><li>Monthly\*</li><li>Yearly</li></ul>                                  | <ul><li>USD\*</li><li>CNY</li></ul>            | <ul><li>Total return\*</li></ul>                                                                                                                                                                                                                                                    |
| US Equity                           | Compustat & CRSP | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>USD\*</li><li>CNY</li></ul>            | <ul><li>Total return\*</li><li>Market capitalization</li><li>Price adjusted</li><li>Price unadjusted</li><li>Return without dividends</li><li>Shares outstanding</li><li>Trading volume</li></ul>                                                                                   |
| US Equity Unbalanced                | Compustat & CRSP | <ul><li>Monthly\*</li></ul>                                                               | <ul><li>USD\*</li></ul>                        | <ul><li>Total return\*</li><li>Average return T-2-12</li><li>Book-to-market ratio</li><li>Market cap T-1</li><li>Market capitalization</li><li>Price adjusted</li><li>Price unadjusted</li><li>Return without dividends</li><li>Shares outstanding</li><li>Trading volume</li></ul> |
| US ETF                              | Yahoo Finance    | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>USD\*</li></ul>                        | <ul><li>Total return\*</li><li>Price adjusted</li></ul>                                                                                                                                                                                                                             |
| US Factors                          | Fama-French      | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li></ul>                                  | <ul><li>USD\*</li></ul>                        | <ul><li>Total return\*</li><li>Price adjusted</li></ul>                                                                                                                                                                                                                             |
| US Hedge Fund                       | TASS             | <ul><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul>                              | <ul><li>USD\*</li></ul>                        | <ul><li>Total return\*</li><li>Asset under management</li><li>Net asset value</li><li>Strategy</li></ul>                                                                                                                                                                            |
| US Hedge Fund Index                 | Credit Suisse HF | <ul><li>Monthly\*</li></ul>                                                               | <ul><li>USD\*</li></ul>                        | <ul><li>Total return\*</li><li>Assets under management</li></ul>                                                                                                                                                                                                                    |
| US Index                            | Compustat & CRSP | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>USD\*</li><li>CNY</li></ul>            | <ul><li>Total return\*</li><li>Price adjusted</li></ul>                                                                                                                                                                                                                             |
| US Industry Portfolios              | Fama-French      | <ul><li>Monthly\*</li><li>Yearly</li></ul>                                                | <ul><li>USD\*</li><li>CNY</li></ul>            | <ul><li>Total return\*</li></ul>                                                                                                                                                                                                                                                    |
| US Replication                      | Multiple         | <ul><li>Daily</li><li>Weekly</li><li>Monthly\*</li><li>Quarterly</li><li>Yearly</li></ul> | <ul><li>USD\*</li></ul>                        | <ul><li>Total return\*</li></ul>                                                                                                                                                                                                                                                    |


# Modules

In this section you find module-specific instructions for InveLab.


# Time-series visualisation

1. **Time-series**. The user needs to first select the overall dataset in the header section as the asset pool, and then the user can select specific data series in this section. It can plot one or multiple assets:
   * Summary Table: at the bottom of the page, this section calculates the summary statistics of selected assets.
   * Boxplot: this section draws the box plot with min, lower fence, 25%, median, 75%, upper fence and max.
2. **Autocorrelation functions**. This section plots the autocorrelation between selected data series.
3. **Rolling functions**. This section needs to select one benchmark series and the comparison series first, then it will show the **length of the rolling window** for calculation. It supports two calculation methods:
   * Correlation: simple Pearson correlation for each rolling window
   * CoVar: calculate the risk dependency between assets by filtering the return series lower (higher) than or equal to the target quantile number value.
4. **Scatter plots**. This section plots the multiple assets return series jointly
   * Joint Distribution: the shadow field represents the loess regression fitting (refer to: <https://rdrr.io/r/stats/loess.html>)
   * Joint Risk Metrics: it supports only two assets. The visualization provides VaR, CoVaR, ES, and MES.
5. **Time-series differential**. This section only uses for currency-related visualization with **\[D\_]** type objects:
   * *Select series a* from a Forward exchange rate (e.g. currency X)
   * *Select series b* from a Spot exchange rate (same currency X)
   * *Select series c* from a USD interest rate (USD)
   * *Select series d* from a Foreign currency interest rate (same currency X)
   * All series should use the same duration (e.g. 1-Month or 3-Month, etc.)
   * The *Difference plot* section plots the 1-month forward spread in log **(named e)**, e.g. ``e=log(`AUD:[D_9]`) - log(`AUD:[D_10]`); and the 1-month interest rate differential in log``` `**`(named f)`**``, e.g. f= log(1+`USD:[R_1]`/12) - log(1+`AUD:[D_7]`/12)\`\`. It also provides summary statistics and the box plots of the spread and the differential series.
   * The *Difference regression* section regresses f on e with their joint distribution.
   * The *Residual plot* section shows the time series plot of the regression residual.
6. **Compare random portfolios**: it supports only **\[RP\_]** type objects. This section plots the number of portfolio constituents in each random portfolio on the corresponding standard deviations. The shadow field represents the loess regression fitting.
7. **Dependency**. This section calculates the overall correlation and tail correlation between one asset and other assets, then plots and compares the difference between the overall correlation and the tail correlation:
   * It supports two methods of correlation calculation: Pearson correlation and Spearman correlation.
   * It also supports Value-at-Risk and CoVaR.




---

[Next Page](/llms-full.txt/1)

