Skip to content
Helicarrier Developers
DOCUMENTATION

Object storage (Heli Bucket)

S3-compatible object storage for uploads, backups, and static assets — with a size you choose and a hard cap so it can't run away.

A Heli Bucket is S3-compatible object storage for the things that don’t belong in a database — user uploads, generated files, exports, backups, images.

It speaks the S3 API, so anything that already talks to S3 works unchanged: the AWS SDKs, aws s3, mc, boto3, rclone, and most upload libraries. You point them at your bucket’s endpoint and keys.

Add a Bucket from the New service menu and pick a size between 1 and 64 GB. That size is what you’re billed for, and it’s a hard cap — see Size and cost.

You can also set your own access key and secret key at creation. Leave them blank and we generate a secret and use your bucket’s name as the access key.

The service’s Connect tab has everything your app needs:

Endpointthe address to point your S3 client at
Bucketyour bucket’s name
Access keyyour S3 access key ID
Secret keyyour S3 secret access key

Use the internal endpoint from apps running on Helicarrier — the traffic stays on the private network and never leaves the platform. The external endpoint is there for tools on your laptop or systems elsewhere.

A typical client setup:

import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://<your-endpoint>",
aws_access_key_id="<access key>",
aws_secret_access_key="<secret key>",
)
s3.upload_file("photo.jpg", "<bucket>", "uploads/photo.jpg")

Two things that trip people up with S3-compatible storage generally:

  • Set the endpoint explicitly. Without it, SDKs default to AWS.
  • Use path-style addressing if your client offers the choice.

Each Heli Bucket service gives you exactly one bucket, and your keys are scoped to it — you can’t create additional buckets with them. That’s deliberate: the size you pay for is the storage you can use, with no way to quietly spill into more.

If you need to organise objects, use key prefixes as folders — uploads/2026/photo.jpg — which is how S3 works anyway. Every S3 tool treats prefixes as directories.

Need genuinely separate storage? Create a second Bucket service.

You’re billed on the size you provision, not what you happen to be using — so the cost is predictable and doesn’t move with your traffic.

The size is a hard quota. When the bucket is full, uploads are rejected with Bucket quota exceeded rather than silently costing you more. Handle that error in code the way you’d handle any failed upload.

Resizing. Change the size any time from the Connect tab. It applies immediately and the bill re-prices on the new size.

Auto-expand (optional). Turn it on and set a step, and when the bucket reaches about 90% full it grows by that step on its own, up to the 64 GB maximum. Useful when running out is worse than paying for the next increment — but remember it raises your bill without asking, so set a step you’re comfortable with.

If a key leaks, or you just want to change it, use Rotate access keys on the bucket’s Connect tab. You can change the secret alone, or the access key and secret together.

  • Your objects are untouched — this changes credentials, not data.
  • The old key stops working immediately. Anything still using it starts getting Access Denied, so update your apps and secrets in the same window.
  • Access keys are 3–64 characters, using letters, numbers, dot, dash or underscore. Secrets must be at least 8 characters.

If your app reads the keys from a reference to the bucket service, it picks up the new values on its next deploy — so redeploy it after rotating.

  • Backups are yours to run. Unlike managed databases, a bucket isn’t backed up for you. If its contents matter, sync them somewhere else (rclone, mc mirror, or a scheduled cron job).
  • Deleting the service deletes the objects. There’s no separate retention for bucket data — export anything you need first.
  • It’s private by default. Objects aren’t publicly readable; your app serves them, or hands out pre-signed URLs.