Skip to content
Development
Skill

/aws-aurora

AWS Aurora Serverless v2, RDS Proxy, Data API, connection pooling

From plugin
maggy
70568 skills7 agents25 commands1 hook
Install
$ npx -y skills add alinaqi/maggy --skill aws-aurora --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/aws-aurora

Context preview

The summary Claude sees to decide when to auto-load this skill.

AWS Aurora Serverless v2, RDS Proxy, Data API, connection pooling

SKILL.md

aws-aurora.SKILL.md
name: aws-aurora
description: AWS Aurora Serverless v2, RDS Proxy, Data API, connection pooling
when-to-use: When working with AWS Aurora/RDS databases
user-invocable: false
paths: ["**/rds*", "**/aurora*", "serverless.*", "template.yaml"]
effort: medium

AWS Aurora Skill

Amazon Aurora is a MySQL/PostgreSQL-compatible relational database with serverless scaling, high availability, and enterprise features.

**Sources:** [Aurora Docs](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/) | [Serverless v2](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.html) | [RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html)

---

Core Principle

**Use RDS Proxy for serverless, Data API for simplicity, connection pooling always.**

Aurora excels at ACID-compliant workloads. For serverless architectures (Lambda), always use RDS Proxy or Data API to handle connection management. Never open raw connections from Lambda functions.

---

Aurora Options

| Option | Best For | |--------|----------| | **Aurora Serverless v2** | Variable workloads, auto-scaling (0.5-128 ACUs) | | **Aurora Provisioned** | Predictable workloads, maximum performance | | **Aurora Global** | Multi-region, disaster recovery | | **Data API** | Serverless without VPC, simple HTTP access | | **RDS Proxy** | Connection pooling for Lambda, high concurrency |

---

Connection Strategies

Strategy 1: RDS Proxy (Recommended for Lambda)

Lambda → RDS Proxy → Aurora
         (pool)
  • Connection pooling and reuse
  • Automatic failover handling
  • IAM authentication support
  • Works with existing SQL clients

Strategy 2: Data API (Simplest for Serverless)

Lambda → Data API (HTTP) → Aurora
  • No VPC required
  • No connection management
  • Higher latency per query
  • Limited to Aurora Serverless

Strategy 3: Direct Connection (Not for Lambda)

App Server → Aurora
(persistent connection)
  • Only for long-running servers (ECS, EC2)
  • Manage connection pool yourself
  • Not suitable for serverless

---

RDS Proxy Setup

Create Proxy (AWS Console/CDK)

// CDK example
import * as rds from 'aws-cdk-lib/aws-rds';

const proxy = new rds.DatabaseProxy(this, 'Proxy', {
  proxyTarget: rds.ProxyTarget.fromCluster(cluster),
  secrets: [cluster.secret!],
  vpc,
  securityGroups: [proxySecurityGroup],
  requireTLS: true,
  idleClientTimeout: cdk.Duration.minutes(30),
  maxConnectionsPercent: 90,
  maxIdleConnectionsPercent: 10,
  borrowTimeout: cdk.Duration.seconds(30)
});

Connect via Proxy (TypeScript/Node.js)

// lib/db.ts
import { Pool } from 'pg';
import { Signer } from '@aws-sdk/rds-signer';

const signer = new Signer({
  hostname: process.env.RDS_PROXY_ENDPOINT!,
  port: 5432,
  username: process.env.DB_USER!,
  region: process.env.AWS_REGION!
});

// IAM authentication
async function getPool(): Promise<Pool> {
  const token = await signer.getAuthToken();

  return new Pool({
    host: process.env.RDS_PROXY_ENDPOINT,
    port: 5432,
    database: process.env.DB_NAME,
    user: process.env.DB_USER,
    password: token,
    ssl: { rejectUnauthorized: true },
    max: 1,  // Single connection for Lambda
    idleTimeoutMillis: 120000,
    connectionTimeoutMillis: 10000
  });
}

// Usage in Lambda
let pool: Pool | null = null;

export async function handler(event: any) {
  if (!pool) {
    pool = await getPool();
  }

  const result = await pool.query('SELECT * FROM users WHERE id = $1', [event.userId]);
  return result.rows[0];
}

Proxy Configuration Best Practices

# Key settings for Lambda workloads
MaxConnectionsPercent: 90        # Use most of DB connections
MaxIdleConnectionsPercent: 10    # Keep some idle for bursts
ConnectionBorrowTimeout: 30s     # Wait for available connection
IdleClientTimeout: 30min         # Close idle proxy connections

# Monitor these CloudWatch metrics:
# - DatabaseConnectionsCurrentlyBorrowed
# - DatabaseConnectionsCurrentlySessionPinned
# - QueryDatabaseResponseLatency

---

Data API (HTTP-based)

Enable Data API

# Must be Aurora Serverless
aws rds modify-db-cluster \
  --db-cluster-identifier my-cluster \
  --enable-http-endpoint

TypeScript with Data API Client v2

npm install data-api-client
// lib/db.ts
import DataAPIClient from 'data-api-client';

const db = DataAPIClient({
  secretArn: process.env.DB_SECRET_ARN!,
  resourceArn: process.env.DB_CLUSTER_ARN!,
  database: process.env.DB_NAME!,
  region: process.env.AWS_REGION!
});

// Simple query
const users = await db.query('SELECT * FROM users WHERE active = :active', {
  active: true
});

// Insert with returning
const result = await db.query(
  'INSERT INTO users (email, name) VALUES (:email, :name) RETURNING *',
  { email: 'user@test.com', name: 'Test User' }
);

// Transaction
const transaction = await db.transaction();
try {
  await transaction.query('UPDATE accounts SET balance = balance - :amount WHERE id = :from', {
    amount: 100, from: 1
  });
  await transaction.query('UPDATE accounts SET balance = balance + :amount WHERE id = :to', {
    amount: 100, to: 2
  });
  await transaction.commit();
} catch (error) {
  await transaction.rollback();
  throw error;
}

Python with boto3

# requirements.txt
boto3>=1.34.0

# db.py
import boto3
import os

rds_data = boto3.client('rds-data')

CLUSTER_ARN = os.environ['DB_CLUSTER_ARN']
SECRET_ARN = os.environ['DB_SECRET_ARN']
DATABASE = os.environ['DB_NAME']


def execute_sql(sql: str, parameters: list = None):
    """Execute SQL via Data API."""
    params = {
        'resourceArn': CLUSTER_ARN,
        'secretArn': SECRET_ARN,
        'database': DATABASE,
        'sql': sql
    }

    if parameters:
        params['parameters'] = parameters

    return rds_data.execute_statement(**params)


def get_user(user_id: int):
    result = execute_sql(
        'SELECT * FROM users WHER
Read more
Ships withmaggy

Turn Claude Code into a self-reviewing, test-enforced engineering system that remembers context across sessions — then route work across 13 models from a single dashboard.

Get the whole plugin