Chroma or VecturaDB on an AWS EC2 instance

One server in your own AWS account, with its data on an EBS volume, HTTPS, allowed IP addresses and snapshots. From about 12.50 USD a month on your AWS bill.

Disclaimer. This template and its scripts are provided as is, without warranty of any kind, as stated in the Apache License 2.0. The numbers on this page are what we measured on 29 October 2026 in eu-west-1: your region, sizes, data and versions may behave differently. You are responsible for your data: back it up, and test a restore on a copy before you rely on it.

Not sure about your case? Open an issue in the VecturaDB repository, describe your data and your setup, and we will take a look on a best-effort basis.

What it creates

The template runs one of two servers:

Both keep the Chroma API: the Chroma clients connect with the URL of the stack. In our tests the Python (chromadb 1.5.9) and JavaScript (chromadb 3.5.0) clients and a .NET client gave the same results on the two servers.

ResourceNotes
EC2 instance, Ubuntu 24.04Docker runs the server; Caddy serves HTTPS in front of it
EBS data volume, gp3Mounted at /var/lib/chroma; 16 GiB by default, encrypted
Security groupOpens only what the access mode needs
VPC, subnet and internet gateway10.42.0.0/16, in the first availability zone of the region
Elastic IPThe address for HTTPS, and the way out to the package and image registries
IAM role of the instanceSystems Manager runs the configuration and the restore: there is no SSH
Systems Manager documents and associationThe configuration, run at the creation and at every update that changes it; the restore
Secrets Manager secretOnly VecturaDB with an API key
Data Lifecycle Manager policyOnly with backups on: snapshots of the data volume

Deploy

Launch Stack

The button opens the quick-create page of CloudFormation in eu-west-1, with the template of the tag aws-v1.2.2 and the name of the stack already filled in. CloudFormation reads templates from Amazon S3, so the button uses a copy of the template in a public bucket.

  1. Fill the parameters, in three groups: Server (engine, images, instance type, size of the data volume), Access (access mode, allowed IP ranges, API key, domain, email for Let's Encrypt) and Backups.
  2. Under “Capabilities and transforms”, tick the three acknowledgements: IAM resources, IAM resources with custom names, and CAPABILITY_AUTO_EXPAND.
  3. Choose “Create stack”. When the status is CREATE_COMPLETE, the Outputs tab has the Url for the clients.

Most of the creation is the first boot of the instance, which installs Docker and Caddy.

With the AWS CLI:

aws cloudformation create-stack --region eu-west-1 --stack-name my-chroma \
  --template-url https://vecturadb-deploy.s3.eu-west-1.amazonaws.com/aws-v1.2.2/vm/template.yaml \
  --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND \
  --parameters ParameterKey=Access,ParameterValue=allowed-ips \
               ParameterKey=AllowedIpRanges,ParameterValue=203.0.113.10/32
aws cloudformation wait stack-create-complete --region eu-west-1 --stack-name my-chroma
aws cloudformation describe-stacks --region eu-west-1 --stack-name my-chroma --query "Stacks[0].Outputs"

For VecturaDB with an API key, add ParameterKey=Engine,ParameterValue=vecturadb ParameterKey=ApiKey,ParameterValue=<your key>. The template and its README are in the VecturaDB.Deploy repository, under aws/vm.

Access and HTTPS

AccessWhat is openAddress
Allowed IP addresses443 from your IP ranges; 80 for the certificate onlyhttps://, with the Elastic IP or your domain
Public443 and 80 from anywhere; VecturaDB with an API key onlyhttps://
InternalNothing from the internet; port 8000 inside the VPChttp://, on the private address
On the instance, against the server on 127.0.0.1 (median of 20 runs, t4g.micro)Time
Query2.2 ms
Get4.2 ms
Add of 2 records35 ms
8 concurrent writers, in all6.1 s

Cost

The sizes we tested, with the list prices of eu-west-1 in USD for 730 hours a month, on 29 October 2026:

SizeCPU, memoryInstanceRoot volume 8 GiBData volume 16 GiBPublic IPv4Total a month
t4g.micro (default, Arm)2, 1 GiB6.720.701.413.6512.48
t4g.small (Arm)2, 2 GiB13.430.701.413.6519.19

Backups and restore

Restore

  1. Create a volume from a snapshot in the availability zone of the instance, and attach it.
  2. Run the RestoreDocument of the stack: it stops the server, replaces the data with the data of the snapshot, and starts the server again.
  3. Detach and delete the volume.
STACK=my-chroma; SNAPSHOT=<snapshot id>
out() { aws cloudformation describe-stacks --stack-name $STACK --query "Stacks[0].Outputs[?OutputKey=='$1'].OutputValue" --output text; }
INSTANCE=$(out InstanceId); DOCUMENT=$(out RestoreDocument)
AZ=$(aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[0].Instances[0].Placement.AvailabilityZone" --output text)
VOLUME=$(aws ec2 create-volume --snapshot-id $SNAPSHOT --availability-zone $AZ --volume-type gp3 --encrypted --query VolumeId --output text)
aws ec2 wait volume-available --volume-ids $VOLUME
aws ec2 attach-volume --volume-id $VOLUME --instance-id $INSTANCE --device /dev/sdg
aws ec2 wait volume-in-use --volume-ids $VOLUME
COMMAND=$(aws ssm send-command --document-name $DOCUMENT --instance-ids $INSTANCE --parameters volumeId=$VOLUME --query Command.CommandId --output text)
until aws ssm get-command-invocation --command-id $COMMAND --instance-id $INSTANCE --query Status --output text 2>/dev/null | grep -qE 'Success|Failed|Cancelled|TimedOut'; do sleep 5; done
aws ssm get-command-invocation --command-id $COMMAND --instance-id $INSTANCE --query "[Status,StandardOutputContent]" --output text
aws ec2 detach-volume --volume-id $VOLUME
aws ec2 wait volume-available --volume-ids $VOLUME
aws ec2 delete-volume --volume-id $VOLUME

The data written after the snapshot is lost: take a snapshot first if you may want it back. The data volume stays the same, so the snapshots go on.

Updates

Delete everything

Deleting the stack deletes the instance, the data volume, the network, the Elastic IP, the roles, the documents and the secret. The snapshots stay: delete them yourself, after the stack, so that no new snapshot comes after the cleanup.

In the console

  1. In CloudFormation, select the stack, choose Delete and type the name of the stack to confirm.
  2. In EC2, under Snapshots, delete the snapshots with the tag chroma-backup equal to the name of the stack.

With the AWS CLI

aws cloudformation delete-stack --region eu-west-1 --stack-name my-chroma
aws cloudformation wait stack-delete-complete --region eu-west-1 --stack-name my-chroma
for s in $(aws ec2 describe-snapshots --region eu-west-1 --owner-ids self \
    --filters Name=tag:chroma-backup,Values=my-chroma --query "Snapshots[].SnapshotId" --output text); do
  aws ec2 delete-snapshot --region eu-west-1 --snapshot-id $s
done

In our tests the deletion of the stack took 64 seconds with the CLI, and afterwards nothing of the stack was left in the region.

Limits

VecturaDB is an independent fork of Chroma, under the Apache License 2.0. The original code is copyright Chroma Inc. and its contributors.

Not affiliated with, endorsed by or sponsored by Chroma Inc. CHROMA is a registered trademark of Chroma Inc., used here only to describe compatibility.