Skip to content

Aurora

Reference doc for the `sst.aws.Aurora` component.

The Aurora component lets you add a Aurora Postgres or MySQL cluster to your app using Amazon Aurora Serverless v2.

Create an Aurora Postgres cluster

sst.config.ts
const vpc = new sst.aws.Vpc("MyVpc");
const database = new sst.aws.Aurora("MyDatabase", {
engine: "postgres",
vpc
});

Create an Aurora MySQL cluster

sst.config.ts
const vpc = new sst.aws.Vpc("MyVpc");
const database = new sst.aws.Aurora("MyDatabase", {
engine: "mysql",
vpc
});

Change the scaling config

sst.config.ts
new sst.aws.Aurora("MyDatabase", {
engine: "postgres",
scaling: {
min: "2 ACU",
max: "128 ACU"
},
vpc
});

You can link your database to other resources, like a function or your Next.js app.

sst.config.ts
new sst.aws.Nextjs("MyWeb", {
link: [database],
vpc
});

Once linked, you can connect to it from your function code.

app/page.tsx
import { Resource } from "sst";
import postgres from "postgres";
const sql = postgres({
username: Resource.MyDatabase.username,
password: Resource.MyDatabase.password,
database: Resource.MyDatabase.database,
host: Resource.MyDatabase.host,
port: Resource.MyDatabase.port
});

Enable the RDS Data API

sst.config.ts
new sst.aws.Aurora("MyDatabase", {
engine: "postgres",
dataApi: true,
vpc
});

When using the Data API, connecting to the database does not require a persistent connection, and works over HTTP. You also don’t need the sst tunnel or a VPN to connect to it from your local machine.

app/page.tsx
import { Resource } from "sst";
import { drizzle } from "drizzle-orm/aws-data-api/pg";
import { RDSDataClient } from "@aws-sdk/client-rds-data";
drizzle(new RDSDataClient({}), {
database: Resource.MyDatabase.database,
secretArn: Resource.MyDatabase.secretArn,
resourceArn: Resource.MyDatabase.clusterArn
});

Running locally

By default, your Aurora database is deployed in sst dev. But let’s say you are running Postgres locally.

Terminal window
docker run \
--rm \
-p 5432:5432 \
-v $(pwd)/.sst/storage/postgres:/var/lib/postgresql/data \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=local \
postgres:16.4

You can connect to it in sst dev by configuring the dev prop.

sst.config.ts
new sst.aws.Aurora("MyDatabase", {
engine: "postgres",
vpc,
dev: {
username: "postgres",
password: "password",
database: "local",
port: 5432
}
});

This will skip deploying the database and link to the locally running Postgres database instead. Check out the full example.


Cost

This component has one DB instance that is used for both writes and reads. The instance can scale from the minimum number of ACUs to the maximum number of ACUs. By default, this uses a min of 0 ACUs and a max of 4 ACUs.

When the database is paused, you are not charged for the ACUs.

Each ACU costs $0.12 per hour for both postgres and mysql engine. The storage costs $0.01 per GB per month for standard storage.

So if your database is constantly using 1GB of memory or 0.5 ACUs, then you are charged $0.12 x 0.5 x 24 x 30 or $43 per month. And add the storage costs to this as well.

The above are rough estimates for us-east-1, check out the Amazon Aurora pricing for more details.

RDS Proxy

If you enable the proxy, it uses Aurora Capacity Units with a minumum of 8 ACUs at $0.015 per ACU hour.

That works out to an additional $0.015 x 8 x 24 x 30 or $86 per month. Adjust this if you end up using more than 8 ACUs.

The above are rough estimates for us-east-1, check out the RDS Proxy pricing for more details.

RDS Data API

If you enable dataApi, you get charged an additional $0.35 per million requests for the first billion requests. After that, it’s $0.20 per million requests.

Check out the RDS Data API pricing for more details.


Constructor

new Aurora(name, args, opts?)

Parameters

AuroraArgs

dataApi?

Type Input<boolean>

Default false

Enable RDS Data API for the database.

The RDS Data API provides a secure HTTP endpoint and does not need a persistent connection. You also doesn’t need the sst tunnel or a VPN to connect to it from your local machine.

RDS Data API is billed per request. Check out the RDS Data API pricing for more details.

{
dataApi: true
}

database?

Type Input<string>

Default Based on the name of the current app

Name of a database that is automatically created inside the cluster.

The name must begin with a letter and contain only lowercase letters, numbers, or underscores.

By default, it takes the name of the app, and replaces the hyphens with underscores.

{
databaseName: "acme"
}

dev?

Type Object

Configure how this component works in sst dev.

By default, your Aurora database is deployed in sst dev. But if you want to instead connect to a locally running database, you can configure the dev prop.

This will skip deploying an Aurora database and link to the locally running database instead.

Setting the dev prop also means that any linked resources will connect to the right database both in sst dev and sst deploy.

{
dev: {
username: "postgres",
password: "password",
database: "postgres",
host: "localhost",
port: 5432
}
}

dev.database?

Type Input<string>

Default Inherit from the top-level database.

The database of the local database to connect to when running in dev.

dev.host?

Type Input<string>

Default “localhost”

The host of the local database to connect to when running in dev.

dev.password?

Type Input<string>

Default Inherit from the top-level password.

The password of the local database to connect to when running in dev.

dev.port?

Type Input<number>

Default 5432

The port of the local database to connect to when running in dev.

dev.username?

Type Input<string>

Default Inherit from the top-level username.

The username of the local database to connect to when running in dev.

engine

Type Input<postgres | mysql>

The Aurora engine to use.

{
engine: "postgres"
}

password?

Type Input<string>

Default A random password is generated.

The password of the master user.

{
password: "Passw0rd!"
}

You can use a Secret to manage the password.

{
password: (new sst.Secret("MyDBPassword")).value
}

proxy?

Type Input<boolean | Object>

Default false

Enable RDS Proxy for the database.

Amazon RDS Proxy sits between your application and the database and manages connections to it. It’s useful for serverless applications, or Lambda functions where each invocation might create a new connection.

There’s an extra cost attached to enabling this. Check out the RDS Proxy pricing for more details.

{
proxy: true
}

proxy.credentials?

Type Input<Input<Object>[]>

Add extra credentials the proxy can use to connect to the database.

Your app will use the master username and password. So you don’t need to specify them here.

These credentials are for any other services that need to connect to your database directly.

These credentials are not automatically created. You’ll need to create these credentials manually in the database.

{
credentials: [
{
username: "metabase",
password: "Passw0rd!"
}
]
}

You can use a Secret to manage the password.

{
credentials: [
{
username: "metabase",
password: (new sst.Secret("MyDBPassword")).value
}
]
}
proxy.credentials[].password

Type Input<string>

The password of the user.

proxy.credentials[].username

Type Input<string>

The username of the user.

scaling?

Type Input<Object>

Default {min: “0 ACU”, max: “4 ACU”}

The Aurora Serverless v2 scaling config.

By default, the cluster has one DB instance that is used for both writes and reads. The instance can scale from a minimum number of ACUs to the maximum number of ACUs.

An ACU or Aurora Capacity Unit is roughly equivalent to 2 GB of memory and a corresponding amount of CPU and network resources. So pick the minimum and maximum based on the baseline and peak memory usage of your app.

If you set a min of 0 ACUs, the database will be paused when there are no active connections in the pauseAfter specified time period.

This is useful for dev environments since you are not charged when the database is paused. But it’s not recommended for production environments because it takes around 15 seconds for the database to resume.

scaling.max?

Type Input<${number} ACU>

Default 4 ACU

The maximum number of ACUs or Aurora Capacity Units. Ranges from 1 to 128, in increments of 0.5. Where each ACU is roughly equivalent to 2 GB of memory.

{
scaling: {
max: "128 ACU"
}
}

scaling.min?

Type Input<${number} ACU>

Default 0.5 ACU

The minimum number of ACUs or Aurora Capacity Units. Ranges from 0 to 256, in increments of 0.5. Where each ACU is roughly equivalent to 2 GB of memory.

If you set this to 0 ACUs, the database will be paused when there are no active connections in the pauseAfter specified time period.

On the next database connection, the database will resume. It takes about 15 seconds for the database to resume.

For your production workloads, setting a minimum of 0.5 ACUs might not be a great idea because:

  1. It takes longer to scale from a low number of ACUs to a much higher number.
  2. Query performance depends on the buffer cache. So if frequently accessed data cannot fit into the buffer cache, you might see uneven performance.
  3. The max connections for a 0.5 ACU instance is capped at 2000.

You can read more here.

{
scaling: {
min: "2 ACU"
}
}

scaling.pauseAfter?

Type Input<${number} minute | ${number} minutes | ${number} hour | ${number} hours | ${number} second | ${number} seconds>

Default “5 minutes”

The amount of time before the database is paused when there are no active connections. Only applies when the min is set to 0 ACUs.

Must be between "5 minutes" and "60 minutes" or "1 hour". So if the min is set to 0 ACUs, by default, the database will be auto-paused after "5 minutes".

When the database is paused, you are not charged for the ACUs. On the next database connection, the database will resume. It takes about 15 seconds for the database to resume.

Auto-pause is useful for minimizing costs in the development environments where the database is not used frequently. It’s not recommended for production environments.

{
scaling: {
pauseAfter: "20 minutes"
}
}

transform?

Type Object

Transform how this component creates its underlying resources.

transform.cluster?

Type ClusterArgs | (args: ClusterArgs, opts: ComponentResourceOptions, name: string) => void

Transform the RDS Cluster.

transform.clusterParameterGroup?

Type ClusterParameterGroupArgs | (args: ClusterParameterGroupArgs, opts: ComponentResourceOptions, name: string) => void

Transform the RDS cluster parameter group.

transform.instance?

Type ClusterInstanceArgs | (args: ClusterInstanceArgs, opts: ComponentResourceOptions, name: string) => void

Transform the database instance in the RDS Cluster.

transform.instanceParameterGroup?

Type ParameterGroupArgs | (args: ParameterGroupArgs, opts: ComponentResourceOptions, name: string) => void

Transform the RDS instance parameter group.

transform.proxy?

Type ProxyArgs | (args: ProxyArgs, opts: ComponentResourceOptions, name: string) => void

Transform the RDS Proxy.

transform.subnetGroup?

Type SubnetGroupArgs | (args: SubnetGroupArgs, opts: ComponentResourceOptions, name: string) => void

Transform the RDS subnet group.

username?

Type Input<string>

Default "postgres" for Postgres, "root" for MySQL

The username of the master user.

{
username: "admin"
}

version?

Type Input<string>

Default "16.4" for Postgres, "3.08.0" for MySQL

The version of the Aurora engine.

The default is "16.4" for Postgres and "3.08.0" for MySQL.

Check out the available Postgres versions and available MySQL versions in your region.

Auto-pause and resume is only supported in the following versions:

  • Aurora PostgresSQL 16.3 and higher
  • Aurora PostgresSQL 15.7 and higher
  • Aurora PostgresSQL 14.12 and higher
  • Aurora PostgresSQL 13.15 and higher
  • Aurora MySQL 3.08.0 and higher
{
version: "16.3"
}

vpc

Type Vpc | Input<Object>

The VPC to use for the database cluster.

Create a VPC component.

const myVpc = new sst.aws.Vpc("MyVpc");

And pass it in.

{
vpc: myVpc
}

Or pass in a custom VPC configuration.

{
vpc: {
subnets: ["subnet-0db7376a7ad4db5fd ", "subnet-06fc7ee8319b2c0ce"],
securityGroups: ["sg-0399348378a4c256c"]
}
}

vpc.securityGroups

Type Input<Input<string>[]>

A list of VPC security group IDs.

vpc.subnets

Type Input<Input<string>[]>

A list of subnet IDs in the VPC to deploy the Aurora cluster in.

Properties

clusterArn

Type Output<string>

The ARN of the RDS Cluster.

database

Type Output<string>

The name of the database.

host

Type Output<string>

The host of the database.

id

Type Output<string>

The ID of the RDS Cluster.

nodes

Type Object

nodes.cluster

Type undefined | Cluster

nodes.instance

Type undefined | ClusterInstance

password

Type Output<string>

The password of the master user.

port

Type Output<number>

The port of the database.

secretArn

Type Output<string>

The ARN of the master user secret.

username

Type Output<string>

The username of the master user.

SDK

Use the SDK in your runtime to interact with your infrastructure.


This is accessible through the Resource object in the SDK.

  • clusterArn string

    The ARN of the RDS Cluster.

  • database string

    The name of the database.

  • host string

    The host of the database.

  • password string

    The password of the master user.

  • port number

    The port of the database.

  • secretArn string

    The ARN of the master user secret.

  • username string

    The username of the master user.

Methods

static get

Aurora.get(name, id, opts?)

Parameters

  • name string

    The name of the component.
  • id Input<string>

    The ID of the existing Aurora cluster.
  • opts? ComponentResourceOptions

Returns Aurora

Reference an existing Aurora cluster with its RDS cluster ID. This is useful when you create a Aurora cluster in one stage and want to share it in another. It avoids having to create a new Aurora cluster in the other stage.

Imagine you create a cluster in the dev stage. And in your personal stage frank, instead of creating a new cluster, you want to share the same cluster from dev.

sst.config.ts
const database = $app.stage === "frank"
? sst.aws.Aurora.get("MyDatabase", "app-dev-mydatabase")
: new sst.aws.Aurora("MyDatabase");

Here app-dev-mydatabase is the ID of the cluster created in the dev stage. You can find this by outputting the cluster ID in the dev stage.

sst.config.ts
return database.id;