Skip to content

Assets

To share common data across builds and experiences, ReSim supports assets.

Why use assets?

Consider a simulation stack that requires a large HD map, 3D environment meshes, and ML model weights. Every experience in your test suite needs this data, but none of it changes between experiences, it only changes when your simulation environment or models are updated.

Without assets, you have two options, neither ideal:

  • Bake the data into your Docker image - This can bloat the image, slow down CI builds, and force a full image rebuild every time a map or model is updated even if the code hasn't changed
  • Duplicate the data across experience locations - This can waste storage, make updates error-prone, and increase data transfer costs

Assets solve this by letting you define shared data once, revision it independently of your code, and mount it into any build at runtime. Your Docker image stays lean, your experiences stay focused on per-test inputs, and your shared data is versioned and cached.

flowchart LR
    Asset["Asset\n(e.g. HD Map)"] -->|"linked to"| Build[Build]
    Experience["Experience\n(e.g. Scenario)"] -->|"run with"| Test[Test]
    Build -->|"run in"| Test
    Test -->|"part of"| Batch[Test Batch]

    subgraph container ["Container at Runtime"]
        AssetMount["/tmp/resim/assets/world/"]
        InputMount["/tmp/resim/inputs/"]
    end

    Asset -->|"mounted at"| AssetMount
    Experience -->|"mounted at"| InputMount

Prerequisites

Assets are stored in cloud blob storage, using the same data sources as experiences. If you have already configured access for your experience data, no additional setup is needed.

If not, see the Experience Data Sources guide for instructions on setting up access to:

Asset locations

Each asset can have multiple locations. ReSim supports the same location prefixes as experiences:

Source Prefix Example
AWS S3 s3:// s3://my-bucket/assets/sim-world/
Google Cloud Storage gs:// gs://my-bucket/assets/sim-world/
Local None /assets/sim-world/

For cloud storage locations, each location should have a unique prefix containing the asset files. Anything within that prefix will be synced. We recommend a prefix structure that mirrors your ReSim projects:

πŸ“‚ .
└── πŸ“‚ my-project
   └── πŸ“‚ assets
      β”œβ”€β”€ πŸ“‚ sim-world
      β”‚  β”œβ”€β”€ πŸ—ΊοΈ hd_map.bin
      β”‚  └── πŸ“‚ meshes
      β”‚     └── πŸ™οΈ urban_env.glb
      └── πŸ“‚ ml-models
         └── πŸ€– perception_v3.onnx

How asset files are accessed

For cloud-based assets, files are synced from cloud storage and mounted read-only at /tmp/resim/assets/<mountFolder>/ when a build runs. The mountFolder is specified when creating the asset and determines where inside the container the files appear.

For example, an asset with mountFolder set to world and location s3://my-bucket/assets/sim-world/ results in:

/tmp/resim/assets/world/
β”œβ”€β”€ hd_map.bin
└── meshes/
    └── urban_env.glb

Your entrypoint script can then read from /tmp/resim/assets/world/ just as it would from any local directory.

If an asset has multiple locations, all files are synced into the same mount directory. Take care to avoid file or directory name clashes at the root of the locations, just as with experience locations.

Asset caching is enabled by default, so only files that have been added or changed since the last run are downloaded.

Note

Because assets are shared across potentially concurrent jobs, the /tmp/resim/assets/<mountFolder>/ directory is mounted read-only. If your workload needs to modify asset data, copy the files to a writable location first.

Creating an asset

You can create a new asset like so:

resim assets create \
    --project "my-project" \
    --name "Simulation World" \
    --description "HD map and 3D meshes for urban simulation environment" \
    --locations "s3://my-assets-bucket/my-project/assets/sim-world/" \
    --mount-folder "world" \
    --version "1.0.0"

This command returns the UUID and revision number of the created asset. The asset starts at revision 0. Revisions are automatically incremented.

Flag Required Description
--name Yes A human-readable name for the asset
--description Yes A description of what the asset contains
--locations Yes One or more cloud storage locations
--mount-folder Yes The subdirectory name under /tmp/resim/assets/
--version Yes A version string (e.g. 1.0.0, v2, a commit SHA)
--cache-exempt No If set, the asset will not be cached between runs

Examples with different sources

AWS S3:

resim assets create \
    --project "my-project" \
    --name "ML Models" \
    --description "Perception model weights" \
    --locations "s3://my-bucket/assets/ml-models/" \
    --mount-folder "models" \
    --version "v3.1"
!!! example "AWS S3"
    ```shell
    resim assets create \
        --project "my-project" \
        --name "ML Models" \
        --description "Perception model weights" \
        --locations "s3://my-bucket/assets/ml-models/" \
        --mount-folder "models" \
        --version "v3.1"
    ```

**Google Cloud Storage:**
```shell
resim assets create \
    --project "my-project" \
    --name "Calibration Data" \
    --description "Sensor calibration parameters" \
    --locations "gs://my-gcs-bucket/assets/calibration/" \
    --mount-folder "calibration" \
    --version "2024-Q4"
!!! example "Google Cloud Storage"
    ```shell
    resim assets create \
        --project "my-project" \
        --name "Calibration Data" \
        --description "Sensor calibration parameters" \
        --locations "gs://my-gcs-bucket/assets/calibration/" \
        --mount-folder "calibration" \
        --version "2024-Q4"
    ```

## Revising an asset

When the underlying data changes (e.g. a new map version or updated model weights), we create a **new revision** of
the asset rather than modifying it in place. This preserves an immutable history of every version of the asset data,
enabling reproducibility.

```shell
resim assets revise \
    --project "my-project" \
    --asset "Simulation World" \
    --locations "s3://my-assets-bucket/my-project/assets/sim-world-v2/" \
    --version "2.0.0"

Each revision increments the revision number (0, 1, 2, ...). The --version flag is required when revising -- it should reflect the new state of the data (e.g. a semantic version, date, or commit SHA). You can also optionally update the mountFolder:

resim assets revise \
    --project "my-project" \
    --asset "Simulation World" \
    --locations "s3://my-assets-bucket/my-project/assets/sim-world-v2/" \
    --mount-folder "world-v2" \
    --version "2.0.0"

You can list all revisions of an asset:

resim assets list-revisions \
    --project "my-project" \
    --asset "Simulation World"

Updating asset metadata

To update an asset's name or description without changing its data:

resim assets update \
    --project "my-project" \
    --asset "Simulation World" \
    --name "Urban Simulation World" \
    --description "HD map and 3D meshes for the urban simulation environment (downtown)"

Associating assets with builds

Assets must be explicitly linked to a build before they are available at runtime. This association specifies which asset revision the build should use.

The simplest approach is to attach assets when you create the build. The resim builds create command accepts an --assets flag with a comma-separated list of asset references:

resim builds create \
    --image "123456789.dkr.ecr.us-east-1.amazonaws.com/my-sim:abc1234" \
    --version "abc1234" \
    --name "Autonomy Build" \
    --description "Path planning v2.3" \
    --branch "my-branch" \
    --project "my-project" \
    --system "full-stack" \
    --auto-create-branch \
    --assets "Simulation World:2,ML Models:5"

This creates the build and links the specified asset revisions in a single step. Each asset will be mounted at its respective mountFolder when the build runs.

Each entry in the comma-separated list can take one of four forms where the uuid is the revision ID:

Format Example Behaviour
name Simulation World Links the latest revision
name:revision Simulation World:2 Links a specific revision
uuid a1b2c3d4-... Links the latest revision
uuid:revision a1b2c3d4-...:2 Links a specific revision

When the revision is omitted, the latest revision at the time of build creation is used as the static revision for that build. We recommend pinning explicit revision numbers in CI/CD for reproducibility.

Adding assets to an existing build

If you need to add assets to a build after it has been created, use resim builds add-assets:

resim builds add-assets \
    --project "my-project" \
    --build "<build-name-or-id>" \
    --assets "Simulation World:2"

Listing assets for a build

resim builds list-assets \
    --project "my-project" \
    --build "<build-name-or-id>"

Removing assets from a build

resim builds remove-assets \
    --project "my-project" \
    --build "<build-name-or-id>" \
    --asset "Simulation World"

Querying which builds use an asset

resim assets list-builds \
    --project "my-project" \
    --asset "Simulation World"

Archiving assets

Assets that are no longer needed can be archived. Archived assets are hidden from default list views but are not deleted.

resim assets archive \
    --project "my-project" \
    --asset "Simulation World"

To restore an archived asset:

resim assets restore \
    --project "my-project" \
    --asset "Simulation World"

To include archived assets in a list:

resim assets list \
    --project "my-project" \
    --archived

We recommend associating assets with builds as part of your CI/CD pipeline. This ensures that every build is pinned to specific asset revisions, making test results fully reproducible.

A typical workflow:

  1. Create and revise assets independently of your code - When a map, model, or calibration dataset is updated, create a new asset revision. This can be done manually or in a separate pipeline triggered by changes to your data repository

  2. Pin asset revisions in CI - When your CI pipeline creates a new build, associate it with the desired asset revisions. Store the asset revision numbers as CI variables or derive them from a configuration file in your repository

  3. Update asset revisions deliberately - When you want to test against a new map or model, bump the revision number in your CI configuration and let the pipeline pick it up

GitHub Actions example

Extending the GitHub Actions workflow, you can pass asset revisions directly when creating the build using the --assets flag:

- name: Create build with assets and launch batch
  env:
    RESIM_CLIENT_ID: ${{ secrets.RESIM_CLIENT_ID }}
    RESIM_CLIENT_SECRET: ${{ secrets.RESIM_CLIENT_SECRET }}
  run: |
    resim builds create \
      --project "my-project" \
      --system "full-stack" \
      --image "${{ steps.docker_meta.outputs.tags }}" \
      --version "${{ github.sha }}" \
      --branch "${{ github.head_ref || github.ref_name }}" \
      --auto-create-branch \
      --assets "Simulation World:${{ vars.SIM_WORLD_REVISION }},ML Models:${{ vars.ML_MODELS_REVISION }}"

Store SIM_WORLD_REVISION and ML_MODELS_REVISION as GitHub Actions variables so they can be updated without changing the workflow file.

Tip

Separating asset revisions from code changes means you can update your simulation environment without rebuilding your Docker image, and vice versa. This significantly speeds up iteration when only data has changed.

End-to-end example

Here is a complete walkthrough using a simulation world asset shared across many experiences.

1. Create the asset

resim assets create \
    --project "my-project" \
    --name "Simulation World" \
    --description "Downtown urban environment: HD map, 3D meshes, traffic light configs" \
    --locations "s3://my-assets-bucket/my-project/assets/sim-world/" \
    --mount-folder "world" \
    --version "1.0.0"

2. Create a build with the asset attached

resim builds create \
    --image "123456789.dkr.ecr.us-east-1.amazonaws.com/my-sim:abc1234" \
    --version "abc1234" \
    --name "Autonomy Build" \
    --description "Path planning v2.3" \
    --branch "my-branch" \
    --project "my-project" \
    --system "full-stack" \
    --auto-create-branch \
    --assets "Simulation World:0"

3. Run a batch

resim batches create \
    --project "my-project" \
    --build "Autonomy Build" \
    --test-suite "Nightly Regression"

When each test in the batch runs, the simulation world data is automatically mounted at /tmp/resim/assets/world/.

4. Access asset data in your entrypoint

import pathlib

map_path = pathlib.Path("/tmp/resim/assets/world/hd_map.bin")
mesh_dir = pathlib.Path("/tmp/resim/assets/world/meshes/")

map_data = map_path.read_bytes()
meshes = list(mesh_dir.glob("*.glb"))

Every experience in the test suite gets the same simulation world without any duplication.