aws-optimization-sst

AWS Optimization with SST

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "aws-optimization-sst" with this command: npx skills add tejovanthn/rasikalife/tejovanthn-rasikalife-aws-optimization-sst

AWS Optimization with SST

This skill covers best practices for optimizing AWS resources using SST, focusing on performance, cost, and developer experience.

Core Principles

  • Right-size resources: Don't over-provision

  • Use SST's defaults: They're already optimized

  • Leverage caching: Reduce redundant work

  • Optimize cold starts: Minimize Lambda initialization time

  • Monitor and iterate: Use data to guide optimization

Lambda Function Optimization

Pattern 1: Function Configuration

// sst.config.ts new sst.aws.Function("Api", { handler: "src/api.handler", memory: "512 MB", // Start here, adjust based on metrics timeout: "30 seconds", // Don't use default 3 seconds architecture: "arm64", // 20% cheaper and often faster nodejs: { esbuild: { minify: true, // Smaller bundle external: [ // Don't bundle AWS SDK v3 "@aws-sdk/*" ] } } });

Memory considerations:

  • Start with 512 MB

  • Monitor execution time vs cost

  • More memory = more CPU = faster execution

  • Sometimes higher memory is cheaper (finishes faster)

Architecture:

  • Use arm64 (Graviton2) for 20% cost savings

  • Same or better performance

  • Works for most workloads

Pattern 2: Bundle Size Optimization

// Optimize imports - tree-shaking friendly ✅ import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; ❌ import * as AWS from "aws-sdk";

// Use specific SDK clients ✅ import { GetCommand } from "@aws-sdk/lib-dynamodb"; ❌ import { DocumentClient } from "aws-sdk/clients/dynamodb";

Bundle size tips:

  • Use AWS SDK v3 (modular)

  • Import only what you need

  • Mark heavy deps as external

  • Use dynamic imports for large libraries

// Dynamic import for rarely-used code export async function generatePDF(data: Data) { const puppeteer = await import("puppeteer"); // Only loads when actually called }

Pattern 3: Connection Reuse

// ✅ Initialize outside handler (reused across invocations) import { DynamoDBClient } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient({ maxAttempts: 3, requestHandler: { connectionTimeout: 3000, socketTimeout: 3000 } });

export async function handler(event) { // Use client here }

// ❌ Don't initialize inside handler export async function handler(event) { const client = new DynamoDBClient({}); // Creates new connection every time }

Pattern 4: Provisioned Concurrency

For consistently high traffic:

new sst.aws.Function("HighTraffic", { handler: "src/api.handler", transform: { function: { reservedConcurrentExecutions: 10, // Provisioned concurrency keeps instances warm } } });

When to use:

  • Consistent traffic patterns

  • Latency-sensitive applications

  • Cost justified by reduced cold starts

DynamoDB Optimization

Pattern 1: Table Configuration

const table = new sst.aws.Dynamo("Database", { fields: { pk: "string", sk: "string" }, primaryIndex: { hashKey: "pk", rangeKey: "sk" },

// Use on-demand for variable traffic // Use provisioned for predictable traffic stream: "new-and-old-images", // Only if needed for triggers

transform: { table: { // Enable point-in-time recovery for production pointInTimeRecovery: $app.stage === "production" ? { enabled: true } : undefined,

  // TTL for automatic data expiration
  timeToLiveAttribute: "expiresAt"
}

} });

Pattern 2: Query Optimization

// ✅ Use Query with specific partition key await client.send(new QueryCommand({ TableName: Resource.Database.name, KeyConditionExpression: "pk = :pk", ExpressionAttributeValues: { ":pk": "USER#123" } }));

// ❌ Don't use Scan unless absolutely necessary await client.send(new ScanCommand({ TableName: Resource.Database.name })); // Scans entire table - expensive and slow!

Pattern 3: Batch Operations

// Write multiple items efficiently import { BatchWriteCommand } from "@aws-sdk/lib-dynamodb";

// Batch up to 25 items per request const batches = chunk(items, 25);

for (const batch of batches) { await client.send(new BatchWriteCommand({ RequestItems: { [Resource.Database.name]: batch.map(item => ({ PutRequest: { Item: item } })) } })); }

Pattern 4: Projection Expressions

// Only fetch fields you need await client.send(new GetCommand({ TableName: Resource.Database.name, Key: { pk: "USER#123", sk: "PROFILE" }, ProjectionExpression: "name, email" // Don't fetch everything }));

Pattern 5: GSI Design

// Sparse indexes save cost const table = new sst.aws.Dynamo("Database", { fields: { pk: "string", sk: "string", gsi1pk: "string", // Only set on items that need indexing gsi1sk: "string" }, primaryIndex: { hashKey: "pk", rangeKey: "sk" }, globalIndexes: { gsi1: { hashKey: "gsi1pk", rangeKey: "gsi1sk", projection: "keys_only" // Cheapest option } } });

// Only active users have gsi1pk { pk: "USER#123", sk: "PROFILE", status: "active", gsi1pk: "ACTIVE#USER", // Only active users gsi1sk: "USER#123" }

S3 Optimization

Pattern 1: Bucket Configuration

const bucket = new sst.aws.Bucket("Uploads", { transform: { bucket: { // Lifecycle rules for cost savings lifecycleConfiguration: { rules: [ { id: "archive-old-files", status: "Enabled", transitions: [ { days: 30, storageClass: "INTELLIGENT_TIERING" }, { days: 90, storageClass: "GLACIER" } ] }, { id: "delete-temp-files", status: "Enabled", expiration: { days: 7 }, filter: { prefix: "temp/" } } ] } } } });

Pattern 2: Intelligent Tiering

// Automatically moves objects between access tiers { storageClass: "INTELLIGENT_TIERING" }

// Tiers: // - Frequent Access (default) // - Infrequent Access (30 days) // - Archive Instant Access (90 days) // - Archive Access (90+ days) // - Deep Archive Access (180+ days)

Pattern 3: CloudFront for Static Assets

const cdn = new sst.aws.Router("CDN", { routes: { "/*": { bucket: bucket } }, transform: { distribution: { defaultCacheBehavior: { compress: true, // Enable compression viewerProtocolPolicy: "redirect-to-https", cachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6" // CachingOptimized } } } });

Pattern 4: Presigned URLs

import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import { GetObjectCommand } from "@aws-sdk/client-s3";

// Generate time-limited URL const url = await getSignedUrl( s3Client, new GetObjectCommand({ Bucket: Resource.Uploads.name, Key: fileKey }), { expiresIn: 3600 } // 1 hour );

// No Lambda invocation needed for downloads

API Gateway Optimization

Pattern 1: HTTP API vs REST API

// Use HTTP API (cheaper, faster) new sst.aws.ApiGatewayV2("Api", { routes: { "GET /posts": "src/posts.list", "POST /posts": "src/posts.create" } });

// HTTP API is 71% cheaper than REST API // Same features for most use cases

Pattern 2: Response Caching

new sst.aws.ApiGatewayV2("Api", { routes: { "GET /posts": { function: "src/posts.list", // Cache at API Gateway level cache: { ttl: "5 minutes" } } } });

Pattern 3: Request Validation

// Reject invalid requests early (before Lambda invocation) new sst.aws.ApiGatewayV2("Api", { routes: { "POST /posts": { function: "src/posts.create", authorizer: "iam", // Validate request before invoking Lambda } } });

Remix Optimization with SST

Pattern 1: Server Bundle Optimization

// remix.config.js export default { serverBuildPath: "build/server/index.mjs", serverMinify: true, serverModuleFormat: "esm", // Don't bundle Node.js built-ins serverDependenciesToBundle: [ /^(?!node:)/, // Bundle everything except node: imports ] };

Pattern 2: Asset Optimization

const remix = new sst.aws.Remix("Web", { environment: { ASSET_URL: cdn.url // Serve assets from CloudFront }, transform: { server: { // Optimize Lambda memory: "512 MB", architecture: "arm64" } } });

Pattern 3: Edge Caching

// Use CloudFront for edge caching export const headers = () => ({ "Cache-Control": "public, max-age=3600, s-maxage=86400" });

// Cache at edge for 24 hours // Browser cache for 1 hour

Cost Monitoring

Pattern 1: Resource Tagging

new sst.aws.Function("Api", { handler: "src/api.handler", transform: { function: { tags: { Environment: $app.stage, Service: "api", CostCenter: "engineering" } } } });

Pattern 2: Budget Alerts

// Use AWS Budgets to track costs // Set up alerts when approaching limits // Review CloudWatch metrics regularly

Pattern 3: Cost Allocation

// Tag all resources consistently const tags = { Project: "my-app", Environment: $app.stage, Team: "engineering" };

// Apply to all resources new sst.aws.Function("Api", { transform: { function: { tags } } });

Performance Monitoring

Pattern 1: X-Ray Tracing

new sst.aws.Function("Api", { handler: "src/api.handler", transform: { function: { tracingConfig: { mode: "Active" // Enable X-Ray tracing } } } });

// In code import { captureAWS } from "aws-xray-sdk-core"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";

const client = captureAWS(new DynamoDBClient({}));

Pattern 2: CloudWatch Metrics

import { CloudWatchClient, PutMetricDataCommand } from "@aws-sdk/client-cloudwatch";

const cloudwatch = new CloudWatchClient({});

await cloudwatch.send(new PutMetricDataCommand({ Namespace: "MyApp", MetricData: [{ MetricName: "ProcessingTime", Value: duration, Unit: "Milliseconds" }] }));

Environment-Specific Optimization

Pattern 1: Development Environment

if ($app.stage === "dev") { // Smaller, cheaper resources for dev new sst.aws.Function("Api", { memory: "256 MB", timeout: "10 seconds" }); }

Pattern 2: Production Environment

if ($app.stage === "production") { new sst.aws.Function("Api", { memory: "1024 MB", // More resources timeout: "30 seconds", transform: { function: { reservedConcurrentExecutions: 10, pointInTimeRecovery: { enabled: true } } } }); }

Best Practices Checklist

Lambda Functions

  • Use ARM64 architecture

  • Minimize bundle size

  • Reuse connections

  • Set appropriate memory

  • Set appropriate timeout

  • Use environment variables for config

DynamoDB

  • Use single table design

  • Query instead of Scan

  • Use batch operations

  • Design GSIs carefully

  • Enable TTL for expiring data

  • Use projection expressions

S3

  • Set lifecycle policies

  • Use Intelligent Tiering

  • Enable CloudFront for static assets

  • Use presigned URLs

  • Compress files before upload

API Gateway

  • Use HTTP API over REST API

  • Enable response caching

  • Validate requests early

  • Use custom domains

Monitoring

  • Tag all resources

  • Set up CloudWatch alarms

  • Enable X-Ray tracing

  • Review Cost Explorer monthly

  • Set budget alerts

Cost Optimization Strategies

  1. Right-Size Resources

Monitor and adjust:

Check Lambda memory usage

If max memory used < 60% of allocated, reduce

  1. Use Reserved Capacity

For predictable workloads:

  • DynamoDB Reserved Capacity

  • Lambda Provisioned Concurrency

  • Savings Plans

  1. Cleanup Unused Resources

Regular audit

sst remove --stage old-feature

  1. Optimize Data Transfer
  • Use CloudFront for global distribution

  • Keep data in same region

  • Use VPC endpoints for AWS services

Common Anti-Patterns

❌ Don't:

  • Over-provision memory "just in case"

  • Use Scan on large tables

  • Keep all data forever

  • Ignore CloudWatch metrics

  • Deploy to multiple regions unnecessarily

  • Use REST API when HTTP API works

✅ Do:

  • Start small, scale based on metrics

  • Use Query with partition keys

  • Set up lifecycle policies

  • Monitor and optimize regularly

  • Deploy to one region initially

  • Use HTTP API by default

Further Reading

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

email-templates

No summary provided by upstream source.

Repository SourceNeeds Review
General

marketing-copy

No summary provided by upstream source.

Repository SourceNeeds Review
General

conform

No summary provided by upstream source.

Repository SourceNeeds Review