- AWS
- GCP
- Azure
Deploy the Braintrust data plane in your AWS account using the Braintrust Terraform module. This is the recommended way to self-host Braintrust on AWS.Braintrust recommends deploying in a dedicated AWS account. AWS enforces account-level Lambda concurrency limits, and Braintrust runs Lambda functions for user-defined functions (scorers and tools) and for the AI proxy that serves their LLM calls. Sharing an account with other workloads can lead to throttling and service disruptions. A dedicated account also aligns with AWS best practices for workload isolation and security.This will create all necessary AWS resources including:You should see output similar to:Save this URL. You’ll need it to configure your Braintrust organization.For example, to dump 60 minutes of logs for the This will save logs for all services to a Your existing VPC must have:These tags will be applied to all resources including Brainstore EC2 instances, volumes, and ENIs. The deployment name variable automatically prefixes resource names and applies a
1. Configure the Terraform module
The Braintrust Terraform module contains all the necessary resources for a self-hosted Braintrust data plane.-
Copy the entire contents of the
examples/braintrust-data-planedirectory from the terraform-aws-braintrust-data-plane repository into your own repository. -
In
provider.tf, configure your AWS account and region. Supported regions:ap-northeast-1,ap-south-1,ap-southeast-2,ca-central-1,eu-central-1,eu-west-1,eu-west-2,eu-west-3,sa-east-1,us-east-1,us-east-2, andus-west-2. If you require support for a different region, contact Braintrust. -
In
terraform.tf, set up your remote backend (typically S3 and DynamoDB). -
In
main.tf, append?ref=with a version tag to the modulesourceto pin the module version. Use v6.5.0 or later, the minimum recommended version for new deployments: -
In
main.tf, setenable_ecs_api = trueto serve API traffic from ECS. The example configuration does not set this variable, which leaves API traffic on the Lambda path. ECS is the recommended runtime and costs about 90% less than Lambda for high-traffic data planes. To size the ECS services, see Scaling and storage. -
In
main.tf, customize the remaining Braintrust deployment settings. The defaults are suitable for a large production-sized deployment. Adjust them based on your needs, but keep in mind the hardware requirements.
To keep LLM requests and cached completions on your own infrastructure, you can also run the Braintrust Gateway in your data plane. See Deploy the Braintrust Gateway for the prerequisites and values.
2. Initialize AWS account
If you’re using a new AWS account, run thecreate-service-linked-roles.sh script to create all necessary IAM service-linked roles for the deployment:3. Configure Brainstore license
Your deployment includes Brainstore, a high-performance query engine for real-time trace ingestion. Brainstore requires a license key.-
Go to Settings > Data plane.
Only organization owners can access this page. If you don’t see your data plane configuration, contact Braintrust to enable self-hosting.
- Copy your Brainstore license.
-
Pass the key to Terraform. The recommended approach is to store the license key in AWS Secrets Manager and reference it using a Terraform data source:
Then pass
data.aws_secretsmanager_secret_version.brainstore_license.secret_stringas thebrainstore_license_keyvalue in the module. Alternatively, you can pass the key without storing it in Secrets Manager:- Set
TF_VAR_brainstore_license_key=your-keyin your environment. - Pass it via command line:
terraform apply -var 'brainstore_license_key=your-key'. - Add it to an uncommitted
terraform.tfvarsor.auto.tfvarsfile.
- Set
4. Deploy the module
Initialize and apply the Terraform configuration:The first
terraform apply may fail with transient errors such as ASG health check timeouts (while instances are still booting) or Lambda rate limits. Re-running terraform apply resolves these.- Two isolated VPCs:
- Main VPC: Hosts Braintrust services (API, database, Redis, Brainstore)
- Quarantine VPC: Runs user-defined functions (scorers, tools) in network isolation. This creates ~30 Lambda functions across multiple runtimes. This is required for most production use cases.
- ECS services and Lambda functions for the Braintrust API
- Public CloudFront endpoint, API Gateway, and an internal Application Load Balancer
- EC2 Auto-scaling group for Brainstore
- PostgreSQL database, Redis cache, and S3 buckets
- KMS key for encryption
enable_ecs_api = true, CloudFront routes API traffic to the internal load balancer in front of the ECS services. The API Gateway and API Lambda functions are still provisioned and kept warm for rollback. A future module release removes them.5. Get your API URL
After the deployment completes, get your API URL from the Terraform outputs:6. Configure your organization
Connect your Braintrust organization to your newly deployed data plane.-
Go to Settings > Data plane.
Only organization owners can access this page.
- In API URL area, select Edit.
- Enter the API URL from the last step.
- Leave the other fields blank.
- If your deployment is accessed through a VPN or is otherwise on a private network (not accessible from the public internet), enable Data plane is on a private network. This enables Chrome’s Local Network Access permission handling, which is required for browser access to private network resources. When enabled, Chrome will prompt users to grant permission for the Braintrust UI to access your self-hosted data plane. See Grant browser permissions for details.
- Select Save.
Debug issues
If you encounter issues, you can use thedump-logs.sh script to collect logs:bt-sandbox deployment, run:logs-<deployment_name> directory, which you can share with the Braintrust team for debugging.Customize the infrastructure
These options control what the Terraform module provisions in your AWS account, such as deploying into an existing VPC, KMS encryption keys, and resource tags. To tune how a running deployment behaves, including access control, connectivity, scaling, and telemetry, see Configure your deployment.Use an existing VPC
To deploy into an existing VPC instead of creating a new one, setcreate_vpc = false and provide your VPC and subnet IDs:- At least 3 private subnets across different availability zones
- At least 1 public subnet
- Internet and NAT gateways with properly configured route tables
existing_quarantine_vpc_id and the corresponding existing_quarantine_private_subnet_*_id variables.Use custom tags
To apply custom tags to all resources, pass thecustom_tags parameter to the Braintrust module:BraintrustDeploymentName tag across all resources.Use the
custom_tags parameter instead of the AWS provider’s default_tags configuration. Due to a Terraform limitation, default_tags are not applied to resources that use launch templates, such as Brainstore instances.Redis instance sizing
Lambda memory limits
The API Handler and AI Proxy Lambda functions default to 10240 MB (the Lambda maximum). You can reduce these to lower costs in environments with tighter memory quotas, though Braintrust recommends keeping the defaults for production workloads.Which variable matters depends on where API traffic runs:api_handler_memory_limitapplies only while API traffic runs on the Lambda path. Withenable_ecs_api = true, size the ECS services instead. See Scaling and storage.ai_proxy_memory_limitapplies even with API traffic on ECS. As of Terraform module v6.5.0, LLM calls from user-authored scorers and tools running in the quarantine environment route through the AI Proxy Lambda.
RDS backup and maintenance windows
postgres_backup_window and postgres_maintenance_window, added in Terraform module v6.5.1, shift the RDS backup and maintenance windows to times that avoid peak traffic for your deployment. They default to "00:00-00:30" for daily backups and "Mon:08:00-Mon:11:00" for weekly maintenance, both in UTC. AWS requires that the two windows not overlap.WAL footer version
Thebrainstore_wal_footer_version variable controls the WAL footer format written by Brainstore. It defaults to "" (unset) and should not be changed outside of a planned upgrade sequence.See Enable efficient WAL format in the v2.0 upgrade guide for the correct migration steps.KMS encryption
Whenkms_key_arn is configured, all managed S3 buckets (Brainstore, code-bundle, and Lambda responses) enforce blocked_encryption_types = ["NONE"], preventing unencrypted object uploads. This policy is applied automatically as of v4.5.0 — upgrading from an earlier version will include this change in your terraform plan.AI Proxy CORS headers
As of v4.5.0, thex-bt-use-gateway header is included in the AI Proxy Lambda function URL CORS allowed headers. Browser clients can send this header without triggering a CORS preflight rejection. When the Braintrust Gateway is enabled, requests route through it by default, and x-bt-use-gateway: false sends an individual request straight to the provider instead.Next steps
- Upgrade your deployment — learn how to keep your data plane up to date
- Configuration — configure telemetry, network and URL security, rate limiting, and other options