Skip to main content
Object storage on Upsun adds to your application an S3-compatible bucket. You enable it by setting an object-storage size on the app’s resources. Upsun provisions the bucket and connects it to your app.
The Object Storage is currently a prerelease feature. If you want to use it - please contact Upsun support team.

When to use object storage

Use object storage when your app needs to store large or growing volumes of unstructured data (uploads, media, backups, generated artifacts) and you want to reach it through the S3 API. For small amounts of file data that a single instance reads and writes through the filesystem, a persistent mount is usually a better fit.

Enable object storage

Set an object-storage size on an app. The size is in MB, in the app:size format. Run upsun resources:set with the --object-storage option:
Terminal
upsun resources:set --object-storage <APP_NAME>:<SIZE_IN_MB>
For example, to give the myapp app 512 GB (524288 MB) of object storage:
Terminal
upsun resources:set --object-storage myapp:524288
To view the current allocation, run upsun resources:get. When an app has object storage, the output includes an Object storage (MB) column.

Sizing rules

Object storage is allocated in fixed steps, within a minimum and a maximum. The size you request must be a multiple of the step and fall within these bounds:
RuleValue
Step524288 MB (512 GB)
Minimum524288 MB (512 GB)
Maximum10485760 MB (10 TB)

Connect from your app

Enabling object storage adds a relationship named object-storage to your app. This relationship name is reserved, if your configuration already declares a relationship called object-storage, the deployment fails and asks you to rename it. At runtime the relationship is exposed through the PLATFORM_RELATIONSHIPS environment variable. The object-storage entry provides the connection details for an S3-compatible endpoint:
FieldValue
schemehttp
hostinternal hostname of the service
portport of the service
The endpoint URL is http://<HOST>:<PORT>. The endpoint is reachable over your project’s internal network only and isn’t exposed publicly. A single bucket is created per app, named after the app. So an app named myapp reaches its bucket at http://<HOST>:<PORT>/myapp/<KEY>. When configuring your S3 client, note two requirements:
  • Use path-style addressing. The bucket name goes in the URL path (http://<HOST>:<PORT>/myapp/object.txt), not the hostname. Disable virtual-hosted-style addressing.
  • No credentials are required. The endpoint doesn’t use access keys. Configure your client with empty credentials and any placeholder region.

Example (Python, boto3)

import base64
import json
import os

import boto3

relationships = json.loads(base64.b64decode(os.environ["PLATFORM_RELATIONSHIPS"]))
endpoint = relationships["object-storage"][0]

s3 = boto3.client(
    "s3",
    endpoint_url=f"http://{endpoint['host']}:{endpoint['port']}",
    aws_access_key_id="",
    aws_secret_access_key="",
    region_name="us-east-1",  # Placeholder; not used.
    config=boto3.session.Config(s3={"addressing_style": "path"}),
)

s3.put_object(Bucket="myapp", Key="hello.txt", Body=b"Hello, World!")

Share a bucket across containers

Other containers can use an app’s bucket through a relationship:
  • A worker that doesn’t declare its own relationships block inherits the parent app’s relationships, including object-storage, with no extra configuration.
  • A worker with its own relationships block, another application, or a task can reach an application’s bucket by targeting that app’s object-storage endpoint:
.upsun/config.yaml
applications:
  myapp:
    # ...
    workers:
      queue:
        relationships:
          bucket: 'myapp:object-storage'
The relationship name on the left (bucket here) is yours to choose. Targeting an app that doesn’t have object storage configured fails the deployment.

Resize and remove

Change the size the same way you set it, requesting another valid multiple of the step:
Terminal
upsun resources:set --object-storage myapp:1048576
Set the size to 0 to remove object storage from the app:
Terminal
upsun resources:set --object-storage myapp:0
Setting the size to 0, or removing the app, deletes the bucket and all of its contents on the next deployment. There’s no soft-delete or retention period. Back up any data you need before removing.
When you branch an environment and clone its data, the object-storage size is inherited along with the data, so the new environment keeps its bucket.

Limitations

  • Each app gets a single bucket, named after the app. Multiple buckets per app aren’t supported.
  • A bucket belongs to one app. Other containers can share it through a relationship, but buckets can’t be reassigned between apps.
  • The endpoint is internal to the project and isn’t exposed publicly.
  • The following S3 features aren’t implemented: bucket versioning, object locking, server-side encryption (SSE), access control lists (ACLs), bucket policies, and lifecycle policies. Requests for them return a “not implemented” error.
  • Concurrent writes to the same object are last-write-wins with no object locking.

Inspect the bucket from an SSH session

You can explore your bucket directly from a running container using the AWS CLI. Because the CLI isn’t available in the container image, install it temporarily in /tmp — this location is always writable and doesn’t require root.

Install the AWS CLI

Terminal
cd /tmp
wget https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip
unzip awscli-exe-linux-x86_64.zip
./aws/install -i /tmp/aws-cli -b /tmp/bin

Run S3 commands

The endpoint requires no real credentials — set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION to any arbitrary value. Use http://<HOST>:<PORT> as the endpoint URL, as described above.
Terminal
AWS_ACCESS_KEY_ID=fake \
AWS_SECRET_ACCESS_KEY=fake \
AWS_DEFAULT_REGION=fake \
/tmp/bin/aws s3 --endpoint-url http://<HOST>:<PORT> \
  ls s3://<APP_NAME>/
Other standard S3 commands work the same way:
GoalCommand
List objectsls s3://<APP_NAME>/
Download a filecp s3://<APP_NAME>/path/to/file ./local-file
Upload a filecp ./local-file s3://<APP_NAME>/path/to/file
Sync a directorysync ./local-dir s3://<APP_NAME>/prefix/
Delete an objectrm s3://<APP_NAME>/path/to/file
Files installed in /tmp are ephemeral. The CLI won’t persist across instance restarts.
Last modified on June 5, 2026