{"id":"f96c0a07-bf58-4678-a121-57a21e057956","shortId":"dbdahg","kind":"skill","title":"aws-serverless","tagline":"Specialized skill for building production-ready serverless","description":"# AWS Serverless\n\nSpecialized skill for building production-ready serverless applications on AWS.\nCovers Lambda functions, API Gateway, DynamoDB, SQS/SNS event-driven patterns,\nSAM/CDK deployment, and cold start optimization.\n\n## Principles\n\n- Right-size memory and timeout (measure before optimizing)\n- Minimize cold starts for latency-sensitive workloads\n- Use SnapStart for Java/.NET functions\n- Prefer HTTP API over REST API for simple use cases\n- Design for failure with DLQs and retries\n- Keep deployment packages small\n- Use environment variables for configuration\n- Implement structured logging with correlation IDs\n\n## Patterns\n\n### Lambda Handler Pattern\n\nProper Lambda function structure with error handling\n\n**When to use**: Any Lambda function implementation,API handlers, event processors, scheduled tasks\n\n```javascript\n// Node.js Lambda Handler\n// handler.js\n\n// Initialize outside handler (reused across invocations)\nconst { DynamoDBClient } = require('@aws-sdk/client-dynamodb');\nconst { DynamoDBDocumentClient, GetCommand } = require('@aws-sdk/lib-dynamodb');\n\nconst client = new DynamoDBClient({});\nconst docClient = DynamoDBDocumentClient.from(client);\n\n// Handler function\nexports.handler = async (event, context) => {\n  // Optional: Don't wait for event loop to clear (Node.js)\n  context.callbackWaitsForEmptyEventLoop = false;\n\n  try {\n    // Parse input based on event source\n    const body = typeof event.body === 'string'\n      ? JSON.parse(event.body)\n      : event.body;\n\n    // Business logic\n    const result = await processRequest(body);\n\n    // Return API Gateway compatible response\n    return {\n      statusCode: 200,\n      headers: {\n        'Content-Type': 'application/json',\n        'Access-Control-Allow-Origin': '*'\n      },\n      body: JSON.stringify(result)\n    };\n  } catch (error) {\n    console.error('Error:', JSON.stringify({\n      error: error.message,\n      stack: error.stack,\n      requestId: context.awsRequestId\n    }));\n\n    return {\n      statusCode: error.statusCode || 500,\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        error: error.message || 'Internal server error'\n      })\n    };\n  }\n};\n\nasync function processRequest(data) {\n  // Your business logic here\n  const result = await docClient.send(new GetCommand({\n    TableName: process.env.TABLE_NAME,\n    Key: { id: data.id }\n  }));\n  return result.Item;\n}\n```\n\n```python\n# Python Lambda Handler\n# handler.py\n\nimport json\nimport os\nimport logging\nimport boto3\nfrom botocore.exceptions import ClientError\n\n# Initialize outside handler (reused across invocations)\nlogger = logging.getLogger()\nlogger.setLevel(logging.INFO)\n\ndynamodb = boto3.resource('dynamodb')\ntable = dynamodb.Table(os.environ['TABLE_NAME'])\n\ndef handler(event, context):\n    try:\n        # Parse input\n        body = json.loads(event.get('body', '{}')) if isinstance(event.get('body'), str) else event.get('body', {})\n\n        # Business logic\n        result = process_request(body)\n\n        return {\n            'statusCode': 200,\n            'headers': {\n                'Content-Type': 'application/json',\n                'Access-Control-Allow-Origin': '*'\n            },\n            'body': json.dumps(result)\n        }\n\n    except ClientError as e:\n        logger.error(f\"DynamoDB error: {e.response['Error']['Message']}\")\n        return error_response(500, 'Database error')\n\n    except json.JSONDecodeError:\n        return error_response(400, 'Invalid JSON')\n\n    except Exception as e:\n        logger.error(f\"Unexpected error: {str(e)}\", exc_info=True)\n        return error_response(500, 'Internal server error')\n\ndef process_request(data):\n    response = table.get_item(Key={'id': data['id']})\n    return response.get('Item')\n\ndef error_response(status_code, message):\n    return {\n        'statusCode': status_code,\n        'headers': {'Content-Type': 'application/json'},\n        'body': json.dumps({'error': message})\n    }\n```\n\n### Best_practices\n\n- Initialize clients outside handler (reused across warm invocations)\n- Always return proper API Gateway response format\n- Log with structured JSON for CloudWatch Insights\n- Include request ID in error logs for tracing\n\n### API Gateway Integration Pattern\n\nREST API and HTTP API integration with Lambda\n\n**When to use**: Building REST APIs backed by Lambda,Need HTTP endpoints for functions\n\n```yaml\n# template.yaml (SAM)\nAWSTemplateFormatVersion: '2010-09-09'\nTransform: AWS::Serverless-2016-10-31\n\nGlobals:\n  Function:\n    Runtime: nodejs20.x\n    Timeout: 30\n    MemorySize: 256\n    Environment:\n      Variables:\n        TABLE_NAME: !Ref ItemsTable\n\nResources:\n  # HTTP API (recommended for simple use cases)\n  HttpApi:\n    Type: AWS::Serverless::HttpApi\n    Properties:\n      StageName: prod\n      CorsConfiguration:\n        AllowOrigins:\n          - \"*\"\n        AllowMethods:\n          - GET\n          - POST\n          - DELETE\n        AllowHeaders:\n          - \"*\"\n\n  # Lambda Functions\n  GetItemFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Handler: src/handlers/get.handler\n      Events:\n        GetItem:\n          Type: HttpApi\n          Properties:\n            ApiId: !Ref HttpApi\n            Path: /items/{id}\n            Method: GET\n      Policies:\n        - DynamoDBReadPolicy:\n            TableName: !Ref ItemsTable\n\n  CreateItemFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Handler: src/handlers/create.handler\n      Events:\n        CreateItem:\n          Type: HttpApi\n          Properties:\n            ApiId: !Ref HttpApi\n            Path: /items\n            Method: POST\n      Policies:\n        - DynamoDBCrudPolicy:\n            TableName: !Ref ItemsTable\n\n  # DynamoDB Table\n  ItemsTable:\n    Type: AWS::DynamoDB::Table\n    Properties:\n      AttributeDefinitions:\n        - AttributeName: id\n          AttributeType: S\n      KeySchema:\n        - AttributeName: id\n          KeyType: HASH\n      BillingMode: PAY_PER_REQUEST\n\nOutputs:\n  ApiUrl:\n    Value: !Sub \"https://${HttpApi}.execute-api.${AWS::Region}.amazonaws.com/prod\"\n```\n\n```javascript\n// src/handlers/get.js\nconst { getItem } = require('../lib/dynamodb');\n\nexports.handler = async (event) => {\n  const id = event.pathParameters?.id;\n\n  if (!id) {\n    return {\n      statusCode: 400,\n      body: JSON.stringify({ error: 'Missing id parameter' })\n    };\n  }\n\n  const item = await getItem(id);\n\n  if (!item) {\n    return {\n      statusCode: 404,\n      body: JSON.stringify({ error: 'Item not found' })\n    };\n  }\n\n  return {\n    statusCode: 200,\n    body: JSON.stringify(item)\n  };\n};\n```\n\n### Structure\n\nproject/\n├── template.yaml      # SAM template\n├── src/\n│   ├── handlers/\n│   │   ├── get.js\n│   │   ├── create.js\n│   │   └── delete.js\n│   └── lib/\n│       └── dynamodb.js\n└── events/\n    └── event.json     # Test events\n\n### Api_comparison\n\n- Http_api:\n  - Lower latency (~10ms)\n  - Lower cost (50-70% cheaper)\n  - Simpler, fewer features\n  - Best for: Most REST APIs\n- Rest_api:\n  - More features (caching, request validation, WAF)\n  - Usage plans and API keys\n  - Request/response transformation\n  - Best for: Complex APIs, enterprise features\n\n### Event-Driven SQS Pattern\n\nLambda triggered by SQS for reliable async processing\n\n**When to use**: Decoupled, asynchronous processing,Need retry logic and DLQ,Processing messages in batches\n\n```yaml\n# template.yaml\nResources:\n  ProcessorFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Handler: src/handlers/processor.handler\n      Events:\n        SQSEvent:\n          Type: SQS\n          Properties:\n            Queue: !GetAtt ProcessingQueue.Arn\n            BatchSize: 10\n            FunctionResponseTypes:\n              - ReportBatchItemFailures  # Partial batch failure handling\n\n  ProcessingQueue:\n    Type: AWS::SQS::Queue\n    Properties:\n      VisibilityTimeout: 180  # 6x Lambda timeout\n      RedrivePolicy:\n        deadLetterTargetArn: !GetAtt DeadLetterQueue.Arn\n        maxReceiveCount: 3\n\n  DeadLetterQueue:\n    Type: AWS::SQS::Queue\n    Properties:\n      MessageRetentionPeriod: 1209600  # 14 days\n```\n\n```javascript\n// src/handlers/processor.js\nexports.handler = async (event) => {\n  const batchItemFailures = [];\n\n  for (const record of event.Records) {\n    try {\n      const body = JSON.parse(record.body);\n      await processMessage(body);\n    } catch (error) {\n      console.error(`Failed to process message ${record.messageId}:`, error);\n      // Report this item as failed (will be retried)\n      batchItemFailures.push({\n        itemIdentifier: record.messageId\n      });\n    }\n  }\n\n  // Return failed items for retry\n  return { batchItemFailures };\n};\n\nasync function processMessage(message) {\n  // Your processing logic\n  console.log('Processing:', message);\n\n  // Simulate work\n  await saveToDatabase(message);\n}\n```\n\n```python\n# Python version\nimport json\nimport logging\n\nlogger = logging.getLogger()\n\ndef handler(event, context):\n    batch_item_failures = []\n\n    for record in event['Records']:\n        try:\n            body = json.loads(record['body'])\n            process_message(body)\n        except Exception as e:\n            logger.error(f\"Failed to process {record['messageId']}: {e}\")\n            batch_item_failures.append({\n                'itemIdentifier': record['messageId']\n            })\n\n    return {'batchItemFailures': batch_item_failures}\n```\n\n### Best_practices\n\n- Set VisibilityTimeout to 6x Lambda timeout\n- Use ReportBatchItemFailures for partial batch failure\n- Always configure a DLQ for poison messages\n- Process messages idempotently\n\n### DynamoDB Streams Pattern\n\nReact to DynamoDB table changes with Lambda\n\n**When to use**: Real-time reactions to data changes,Cross-region replication,Audit logging, notifications\n\n```yaml\n# template.yaml\nResources:\n  ItemsTable:\n    Type: AWS::DynamoDB::Table\n    Properties:\n      TableName: items\n      AttributeDefinitions:\n        - AttributeName: id\n          AttributeType: S\n      KeySchema:\n        - AttributeName: id\n          KeyType: HASH\n      BillingMode: PAY_PER_REQUEST\n      StreamSpecification:\n        StreamViewType: NEW_AND_OLD_IMAGES\n\n  StreamProcessorFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Handler: src/handlers/stream.handler\n      Events:\n        Stream:\n          Type: DynamoDB\n          Properties:\n            Stream: !GetAtt ItemsTable.StreamArn\n            StartingPosition: TRIM_HORIZON\n            BatchSize: 100\n            MaximumRetryAttempts: 3\n            DestinationConfig:\n              OnFailure:\n                Destination: !GetAtt StreamDLQ.Arn\n\n  StreamDLQ:\n    Type: AWS::SQS::Queue\n```\n\n```javascript\n// src/handlers/stream.js\nexports.handler = async (event) => {\n  for (const record of event.Records) {\n    const eventName = record.eventName;  // INSERT, MODIFY, REMOVE\n\n    // Unmarshall DynamoDB format to plain JS objects\n    const newImage = record.dynamodb.NewImage\n      ? unmarshall(record.dynamodb.NewImage)\n      : null;\n    const oldImage = record.dynamodb.OldImage\n      ? unmarshall(record.dynamodb.OldImage)\n      : null;\n\n    console.log(`${eventName}: `, { newImage, oldImage });\n\n    switch (eventName) {\n      case 'INSERT':\n        await handleInsert(newImage);\n        break;\n      case 'MODIFY':\n        await handleModify(oldImage, newImage);\n        break;\n      case 'REMOVE':\n        await handleRemove(oldImage);\n        break;\n    }\n  }\n};\n\n// Use AWS SDK v3 unmarshall\nconst { unmarshall } = require('@aws-sdk/util-dynamodb');\n```\n\n### Stream_view_types\n\n- KEYS_ONLY: Only key attributes\n- NEW_IMAGE: After modification\n- OLD_IMAGE: Before modification\n- NEW_AND_OLD_IMAGES: Both before and after\n\n### Cold Start Optimization Pattern\n\nMinimize Lambda cold start latency\n\n**When to use**: Latency-sensitive applications,User-facing APIs,High-traffic functions\n\n## 1. Optimize Package Size\n\n```javascript\n// Use modular AWS SDK v3 imports\n// GOOD - only imports what you need\nconst { DynamoDBClient } = require('@aws-sdk/client-dynamodb');\nconst { DynamoDBDocumentClient, GetCommand } = require('@aws-sdk/lib-dynamodb');\n\n// BAD - imports entire SDK\nconst AWS = require('aws-sdk');  // Don't do this!\n```\n\n## 2. Use SnapStart (Java/.NET)\n\n```yaml\n# template.yaml\nResources:\n  JavaFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Handler: com.example.Handler::handleRequest\n      Runtime: java21\n      SnapStart:\n        ApplyOn: PublishedVersions  # Enable SnapStart\n      AutoPublishAlias: live\n```\n\n## 3. Right-size Memory\n\n```yaml\n# More memory = more CPU = faster init\nResources:\n  FastFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      MemorySize: 1024  # 1GB gets full vCPU\n      Timeout: 30\n```\n\n## 4. Provisioned Concurrency (when needed)\n\n```yaml\nResources:\n  CriticalFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Handler: src/handlers/critical.handler\n      AutoPublishAlias: live\n\n  ProvisionedConcurrency:\n    Type: AWS::Lambda::ProvisionedConcurrencyConfig\n    Properties:\n      FunctionName: !Ref CriticalFunction\n      Qualifier: live\n      ProvisionedConcurrentExecutions: 5\n```\n\n## 5. Keep Init Light\n\n```python\n# GOOD - Lazy initialization\n_table = None\n\ndef get_table():\n    global _table\n    if _table is None:\n        dynamodb = boto3.resource('dynamodb')\n        _table = dynamodb.Table(os.environ['TABLE_NAME'])\n    return _table\n\ndef handler(event, context):\n    table = get_table()  # Only initializes on first use\n    # ...\n```\n\n### Optimization_priority\n\n- 1: Reduce package size (biggest impact)\n- 2: Use SnapStart for Java/.NET\n- 3: Increase memory for faster init\n- 4: Delay heavy imports\n- 5: Provisioned concurrency (last resort)\n\n### SAM Local Development Pattern\n\nLocal testing and debugging with SAM CLI\n\n**When to use**: Local development and testing,Debugging Lambda functions,Testing API Gateway locally\n\n```bash\n# Install SAM CLI\npip install aws-sam-cli\n\n# Initialize new project\nsam init --runtime nodejs20.x --name my-api\n\n# Build the project\nsam build\n\n# Run locally\nsam local start-api\n\n# Invoke single function\nsam local invoke GetItemFunction --event events/get.json\n\n# Local debugging (Node.js with VS Code)\nsam local invoke --debug-port 5858 GetItemFunction\n\n# Deploy\nsam deploy --guided\n```\n\n```json\n// events/get.json (test event)\n{\n  \"pathParameters\": {\n    \"id\": \"123\"\n  },\n  \"httpMethod\": \"GET\",\n  \"path\": \"/items/123\"\n}\n```\n\n```json\n// .vscode/launch.json (for debugging)\n{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Attach to SAM CLI\",\n      \"type\": \"node\",\n      \"request\": \"attach\",\n      \"address\": \"localhost\",\n      \"port\": 5858,\n      \"localRoot\": \"${workspaceRoot}/src\",\n      \"remoteRoot\": \"/var/task/src\",\n      \"protocol\": \"inspector\"\n    }\n  ]\n}\n```\n\n### Commands\n\n- Sam_build: Build Lambda deployment packages\n- Sam_local_start_api: Start local API Gateway\n- Sam_local_invoke: Invoke single function\n- Sam_deploy: Deploy to AWS\n- Sam_logs: Tail CloudWatch logs\n\n### CDK Serverless Pattern\n\nInfrastructure as code with AWS CDK\n\n**When to use**: Complex infrastructure beyond Lambda,Prefer programming languages over YAML,Need reusable constructs\n\n```typescript\n// lib/api-stack.ts\nimport * as cdk from 'aws-cdk-lib';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport * as apigateway from 'aws-cdk-lib/aws-apigateway';\nimport * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport { Construct } from 'constructs';\n\nexport class ApiStack extends cdk.Stack {\n  constructor(scope: Construct, id: string, props?: cdk.StackProps) {\n    super(scope, id, props);\n\n    // DynamoDB Table\n    const table = new dynamodb.Table(this, 'ItemsTable', {\n      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },\n      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,\n      removalPolicy: cdk.RemovalPolicy.DESTROY, // For dev only\n    });\n\n    // Lambda Function\n    const getItemFn = new lambda.Function(this, 'GetItemFunction', {\n      runtime: lambda.Runtime.NODEJS_20_X,\n      handler: 'get.handler',\n      code: lambda.Code.fromAsset('src/handlers'),\n      environment: {\n        TABLE_NAME: table.tableName,\n      },\n      memorySize: 256,\n      timeout: cdk.Duration.seconds(30),\n    });\n\n    // Grant permissions\n    table.grantReadData(getItemFn);\n\n    // API Gateway\n    const api = new apigateway.RestApi(this, 'ItemsApi', {\n      restApiName: 'Items Service',\n      defaultCorsPreflightOptions: {\n        allowOrigins: apigateway.Cors.ALL_ORIGINS,\n        allowMethods: apigateway.Cors.ALL_METHODS,\n      },\n    });\n\n    const items = api.root.addResource('items');\n    const item = items.addResource('{id}');\n\n    item.addMethod('GET', new apigateway.LambdaIntegration(getItemFn));\n\n    // Output API URL\n    new cdk.CfnOutput(this, 'ApiUrl', {\n      value: api.url,\n    });\n  }\n}\n```\n\n```bash\n# CDK commands\nnpm install -g aws-cdk\ncdk init app --language typescript\ncdk synth    # Generate CloudFormation\ncdk diff     # Show changes\ncdk deploy   # Deploy to AWS\n```\n\n## Sharp Edges\n\n### Cold Start INIT Phase Now Billed (Aug 2025)\n\nSeverity: HIGH\n\nSituation: Running Lambda functions in production\n\nSymptoms:\nUnexplained increase in Lambda costs (10-50% higher).\nBill includes charges for function initialization.\nFunctions with heavy startup logic cost more than expected.\n\nWhy this breaks:\nAs of August 1, 2025, AWS bills the INIT phase the same way it bills\ninvocation duration. Previously, cold start initialization wasn't billed\nfor the full duration.\n\nThis affects functions with:\n- Heavy dependency loading (large packages)\n- Slow initialization code\n- Frequent cold starts (low traffic or poor concurrency)\n\nCold starts now directly impact your bill, not just latency.\n\nRecommended fix:\n\n## Measure your INIT phase\n\n```bash\n# Check CloudWatch Logs for INIT_REPORT\n# Look for Init Duration in milliseconds\n\n# Example log line:\n# INIT_REPORT Init Duration: 423.45 ms\n```\n\n## Reduce INIT duration\n\n```javascript\n// 1. Minimize package size\n// Use tree shaking, exclude dev dependencies\n// npm prune --production\n\n// 2. Lazy load heavy dependencies\nlet heavyLib = null;\nfunction getHeavyLib() {\n  if (!heavyLib) {\n    heavyLib = require('heavy-library');\n  }\n  return heavyLib;\n}\n\n// 3. Use AWS SDK v3 modular imports\nconst { S3Client } = require('@aws-sdk/client-s3');\n// NOT: const AWS = require('aws-sdk');\n```\n\n## Use SnapStart for Java/.NET\n\n```yaml\nResources:\n  JavaFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Runtime: java21\n      SnapStart:\n        ApplyOn: PublishedVersions\n```\n\n## Monitor cold start frequency\n\n```javascript\n// Track cold starts with custom metric\nlet isColdStart = true;\n\nexports.handler = async (event) => {\n  if (isColdStart) {\n    console.log('COLD_START');\n    // CloudWatch custom metric here\n    isColdStart = false;\n  }\n  // ...\n};\n```\n\n### Lambda Timeout Misconfiguration\n\nSeverity: HIGH\n\nSituation: Running Lambda functions, especially with external calls\n\nSymptoms:\nFunction times out unexpectedly.\n\"Task timed out after X seconds\" in logs.\nPartial processing with no response.\nSilent failures with no error caught.\n\nWhy this breaks:\nDefault Lambda timeout is only 3 seconds. Maximum is 15 minutes.\n\nCommon timeout causes:\n- Default timeout too short for workload\n- Downstream service taking longer than expected\n- Network issues in VPC\n- Infinite loops or blocking operations\n- S3 downloads larger than expected\n\nLambda terminates at timeout without graceful shutdown.\n\nRecommended fix:\n\n## Set appropriate timeout\n\n```yaml\n# template.yaml\nResources:\n  MyFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      Timeout: 30  # Seconds (max 900)\n      # Set to expected duration + buffer\n```\n\n## Implement timeout awareness\n\n```javascript\nexports.handler = async (event, context) => {\n  // Get remaining time\n  const remainingTime = context.getRemainingTimeInMillis();\n\n  // If running low on time, fail gracefully\n  if (remainingTime < 5000) {\n    console.warn('Running low on time, aborting');\n    throw new Error('Insufficient time remaining');\n  }\n\n  // For long operations, check periodically\n  for (const item of items) {\n    if (context.getRemainingTimeInMillis() < 10000) {\n      // Save progress and exit gracefully\n      await saveProgress(processedItems);\n      throw new Error('Timeout approaching, saved progress');\n    }\n    await processItem(item);\n  }\n};\n```\n\n## Set downstream timeouts\n\n```javascript\nconst axios = require('axios');\n\n// Always set timeouts on HTTP calls\nconst response = await axios.get('https://api.example.com/data', {\n  timeout: 5000  // 5 seconds\n});\n```\n\n### Out of Memory (OOM) Crash\n\nSeverity: HIGH\n\nSituation: Lambda function processing data\n\nSymptoms:\nFunction stops abruptly without error.\nCloudWatch logs appear truncated.\n\"Max Memory Used\" hits configured limit.\nInconsistent behavior under load.\n\nWhy this breaks:\nWhen Lambda exceeds memory allocation, AWS forcibly terminates\nthe runtime. This happens without raising a catchable exception.\n\nCommon causes:\n- Processing large files in memory\n- Memory leaks across invocations\n- Buffering entire response bodies\n- Heavy libraries consuming too much memory\n\nRecommended fix:\n\n## Increase memory allocation\n\n```yaml\nResources:\n  MyFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      MemorySize: 1024  # MB (128-10240)\n      # More memory = more CPU too\n```\n\n## Stream large data\n\n```javascript\n// BAD - loads entire file into memory\nconst data = await s3.getObject(params).promise();\nconst content = data.Body.toString();\n\n// GOOD - stream processing\nconst { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');\nconst s3 = new S3Client({});\n\nconst response = await s3.send(new GetObjectCommand(params));\nconst stream = response.Body;\n\n// Process stream in chunks\nfor await (const chunk of stream) {\n  await processChunk(chunk);\n}\n```\n\n## Monitor memory usage\n\n```javascript\nexports.handler = async (event, context) => {\n  const used = process.memoryUsage();\n  console.log('Memory:', {\n    heapUsed: Math.round(used.heapUsed / 1024 / 1024) + 'MB',\n    heapTotal: Math.round(used.heapTotal / 1024 / 1024) + 'MB'\n  });\n  // ...\n};\n```\n\n## Use Lambda Power Tuning\n\n```bash\n# Find optimal memory setting\n# https://github.com/alexcasalboni/aws-lambda-power-tuning\n```\n\n### VPC-Attached Lambda Cold Start Delay\n\nSeverity: MEDIUM\n\nSituation: Lambda functions in VPC accessing private resources\n\nSymptoms:\nExtremely slow cold starts (was 10+ seconds, now ~100ms).\nTimeouts on first invocation after idle period.\nFunctions work in VPC but slow compared to non-VPC.\n\nWhy this breaks:\nLambda functions in VPC need Elastic Network Interfaces (ENIs).\nAWS improved this significantly with Hyperplane ENIs, but:\n\n- First cold start in VPC still has overhead\n- NAT Gateway issues can cause timeouts\n- Security group misconfig blocks traffic\n- DNS resolution can be slow\n\nRecommended fix:\n\n## Verify VPC configuration\n\n```yaml\nResources:\n  MyFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      VpcConfig:\n        SecurityGroupIds:\n          - !Ref LambdaSecurityGroup\n        SubnetIds:\n          - !Ref PrivateSubnet1\n          - !Ref PrivateSubnet2  # Multiple AZs\n\n  LambdaSecurityGroup:\n    Type: AWS::EC2::SecurityGroup\n    Properties:\n      GroupDescription: Lambda SG\n      VpcId: !Ref VPC\n      SecurityGroupEgress:\n        - IpProtocol: tcp\n          FromPort: 443\n          ToPort: 443\n          CidrIp: 0.0.0.0/0  # Allow HTTPS outbound\n```\n\n## Use VPC endpoints for AWS services\n\n```yaml\n# Avoid NAT Gateway for AWS service calls\nDynamoDBEndpoint:\n  Type: AWS::EC2::VPCEndpoint\n  Properties:\n    ServiceName: !Sub com.amazonaws.${AWS::Region}.dynamodb\n    VpcId: !Ref VPC\n    RouteTableIds:\n      - !Ref PrivateRouteTable\n    VpcEndpointType: Gateway\n\nS3Endpoint:\n  Type: AWS::EC2::VPCEndpoint\n  Properties:\n    ServiceName: !Sub com.amazonaws.${AWS::Region}.s3\n    VpcId: !Ref VPC\n    VpcEndpointType: Gateway\n```\n\n## Only use VPC when necessary\n\nDon't attach Lambda to VPC unless you need:\n- Access to RDS/ElastiCache in VPC\n- Access to private EC2 instances\n- Compliance requirements\n\nMost AWS services can be accessed without VPC.\n\n### Node.js Event Loop Not Cleared\n\nSeverity: MEDIUM\n\nSituation: Node.js Lambda function with callbacks or timers\n\nSymptoms:\nFunction takes full timeout duration to return.\n\"Task timed out\" even though logic completed.\nExtra billing for idle time.\n\nWhy this breaks:\nBy default, Lambda waits for the Node.js event loop to be empty\nbefore returning. If you have:\n- Unresolved setTimeout/setInterval\n- Dangling database connections\n- Pending callbacks\n\nLambda waits until timeout, even if your response was ready.\n\nRecommended fix:\n\n## Tell Lambda not to wait for event loop\n\n```javascript\nexports.handler = async (event, context) => {\n  // Don't wait for event loop to clear\n  context.callbackWaitsForEmptyEventLoop = false;\n\n  // Your code here\n  const result = await processRequest(event);\n\n  return {\n    statusCode: 200,\n    body: JSON.stringify(result)\n  };\n};\n```\n\n## Close connections properly\n\n```javascript\n// For database connections, use connection pooling\n// or close connections explicitly\n\nconst mysql = require('mysql2/promise');\n\nexports.handler = async (event, context) => {\n  context.callbackWaitsForEmptyEventLoop = false;\n\n  const connection = await mysql.createConnection({...});\n  try {\n    const [rows] = await connection.query('SELECT * FROM users');\n    return { statusCode: 200, body: JSON.stringify(rows) };\n  } finally {\n    await connection.end();  // Always close\n  }\n};\n```\n\n### API Gateway Payload Size Limits\n\nSeverity: MEDIUM\n\nSituation: Returning large responses or receiving large requests\n\nSymptoms:\n\"413 Request Entity Too Large\" error\n\"Execution failed due to configuration error: Malformed Lambda proxy response\"\nResponse truncated or failed\n\nWhy this breaks:\nAPI Gateway has hard payload limits:\n- REST API: 10 MB request/response\n- HTTP API: 10 MB request/response\n- Lambda itself: 6 MB sync response, 256 KB async\n\nExceeding these causes failures that may not be obvious.\n\nRecommended fix:\n\n## For large file uploads\n\n```javascript\n// Use presigned S3 URLs instead of passing through API Gateway\n\nconst { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');\nconst { getSignedUrl } = require('@aws-sdk/s3-request-presigner');\n\nexports.handler = async (event) => {\n  const s3 = new S3Client({});\n\n  const command = new PutObjectCommand({\n    Bucket: process.env.BUCKET_NAME,\n    Key: `uploads/${Date.now()}.file`\n  });\n\n  const uploadUrl = await getSignedUrl(s3, command, { expiresIn: 300 });\n\n  return {\n    statusCode: 200,\n    body: JSON.stringify({ uploadUrl })\n  };\n};\n```\n\n## For large responses\n\n```javascript\n// Store in S3, return presigned download URL\nexports.handler = async (event) => {\n  const largeData = await generateLargeReport();\n\n  await s3.send(new PutObjectCommand({\n    Bucket: process.env.BUCKET_NAME,\n    Key: `reports/${reportId}.json`,\n    Body: JSON.stringify(largeData)\n  }));\n\n  const downloadUrl = await getSignedUrl(s3,\n    new GetObjectCommand({\n      Bucket: process.env.BUCKET_NAME,\n      Key: `reports/${reportId}.json`\n    }),\n    { expiresIn: 3600 }\n  );\n\n  return {\n    statusCode: 200,\n    body: JSON.stringify({ downloadUrl })\n  };\n};\n```\n\n### Infinite Loop or Recursive Invocation\n\nSeverity: HIGH\n\nSituation: Lambda triggered by events\n\nSymptoms:\nRunaway costs.\nThousands of invocations in minutes.\nCloudWatch logs show repeated invocations.\nLambda writing to source bucket/table that triggers it.\n\nWhy this breaks:\nLambda can accidentally trigger itself:\n- S3 trigger writes back to same bucket\n- DynamoDB trigger updates same table\n- SNS publishes to topic that triggers it\n- Step Functions with wrong error handling\n\nRecommended fix:\n\n## Use different buckets/prefixes\n\n```yaml\n# S3 trigger with prefix filter\nEvents:\n  S3Event:\n    Type: S3\n    Properties:\n      Bucket: !Ref InputBucket\n      Events: s3:ObjectCreated:*\n      Filter:\n        S3Key:\n          Rules:\n            - Name: prefix\n              Value: uploads/  # Only trigger on uploads/\n\n# Output to different bucket or prefix\n# OutputBucket or processed/ prefix\n```\n\n## Add idempotency checks\n\n```javascript\nexports.handler = async (event) => {\n  for (const record of event.Records) {\n    const key = record.s3.object.key;\n\n    // Skip if this is a processed file\n    if (key.startsWith('processed/')) {\n      console.log('Skipping already processed file:', key);\n      continue;\n    }\n\n    // Process and write to different location\n    await processFile(key);\n    await writeToS3(`processed/${key}`, result);\n  }\n};\n```\n\n## Set reserved concurrency as circuit breaker\n\n```yaml\nResources:\n  RiskyFunction:\n    Type: AWS::Serverless::Function\n    Properties:\n      ReservedConcurrentExecutions: 10  # Max 10 parallel\n      # Limits blast radius of runaway invocations\n```\n\n## Monitor with CloudWatch alarms\n\n```yaml\nInvocationAlarm:\n  Type: AWS::CloudWatch::Alarm\n  Properties:\n    MetricName: Invocations\n    Namespace: AWS/Lambda\n    Statistic: Sum\n    Period: 60\n    EvaluationPeriods: 1\n    Threshold: 1000  # Alert if >1000 invocations/min\n    ComparisonOperator: GreaterThanThreshold\n```\n\n## Validation Checks\n\n### Hardcoded AWS Credentials\n\nSeverity: ERROR\n\nAWS credentials must never be hardcoded\n\nMessage: Hardcoded AWS access key detected. Use IAM roles or environment variables.\n\n### AWS Secret Key in Source Code\n\nSeverity: ERROR\n\nSecret keys should use Secrets Manager or environment variables\n\nMessage: Hardcoded AWS secret key. Use IAM roles or Secrets Manager.\n\n### Overly Permissive IAM Policy\n\nSeverity: WARNING\n\nAvoid wildcard permissions in Lambda IAM roles\n\nMessage: Overly permissive IAM policy. Use least privilege principle.\n\n### Lambda Handler Without Error Handling\n\nSeverity: WARNING\n\nLambda handlers should have try/catch for graceful errors\n\nMessage: Lambda handler without error handling. Add try/catch.\n\n### Missing callbackWaitsForEmptyEventLoop\n\nSeverity: INFO\n\nNode.js handlers should set callbackWaitsForEmptyEventLoop\n\nMessage: Consider setting context.callbackWaitsForEmptyEventLoop = false\n\n### Default Memory Configuration\n\nSeverity: INFO\n\nDefault 128MB may be too low for many workloads\n\nMessage: Using default 128MB memory. Consider increasing for better performance.\n\n### Low Timeout Configuration\n\nSeverity: WARNING\n\nVery low timeout may cause unexpected failures\n\nMessage: Timeout of 1-3 seconds may be too low. Increase if making external calls.\n\n### No Dead Letter Queue Configuration\n\nSeverity: WARNING\n\nAsync functions should have DLQ for failed invocations\n\nMessage: No DLQ configured. Add for async invocations.\n\n### Importing Full AWS SDK v2\n\nSeverity: WARNING\n\nImport specific clients from AWS SDK v3 for smaller packages\n\nMessage: Importing full AWS SDK. Use modular SDK v3 imports for smaller packages.\n\n### Hardcoded DynamoDB Table Name\n\nSeverity: WARNING\n\nTable names should come from environment variables\n\nMessage: Hardcoded table name. Use environment variable for portability.\n\n## Collaboration\n\n### Delegation Triggers\n\n- user needs GCP serverless -> gcp-cloud-run (Cloud Run for containers, Cloud Functions for events)\n- user needs Azure serverless -> azure-functions (Azure Functions, Logic Apps)\n- user needs database design -> postgres-wizard (RDS design, or use DynamoDB patterns)\n- user needs authentication -> auth-specialist (Cognito, API Gateway authorizers)\n- user needs complex workflows -> workflow-automation (Step Functions, EventBridge)\n- user needs AI integration -> llm-architect (Lambda calling Bedrock or external LLMs)\n\n## When to Use\nUse this skill when the request clearly matches the capabilities and patterns described above.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["aws","serverless","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-aws-serverless","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/aws-serverless","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 37911 github stars · SKILL.md body (32,071 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:50:32.362Z","embedding":null,"createdAt":"2026-04-18T20:34:24.789Z","updatedAt":"2026-05-18T18:50:32.362Z","lastSeenAt":"2026-05-18T18:50:32.362Z","tsv":"'-09':482,483 '-10':488 '-10240':2224 '-2016':487 '-3':3257 '-31':489 '-50':1723 '-70':687 '/0':2458 '/alexcasalboni/aws-lambda-power-tuning':2323 '/aws-apigateway':1549 '/aws-dynamodb':1558 '/aws-lambda':1540 '/client-dynamodb':138,1170 '/client-s3':1878,2259,2802 '/data'',':2129 '/items':546,572 '/items/123':1439 '/lib-dynamodb':146,1178 '/lib/dynamodb':620 '/prod':614 '/s3-request-presigner':2809 '/src':1462 '/util-dynamodb':1098 '/var/task/src':1464 '0.0.0.0':2457 '0.2.0':1445 '1':1147,1318,1746,1833,3096,3256 '10':766,1722,2347,2752,2757,3066,3068 '100':1014 '1000':3098,3101 '10000':2090 '100ms':2350 '1024':1238,2221,2303,2304,2309,2310 '10ms':683 '1209600':797 '123':1435 '128':2223 '128mb':3223,3234 '14':798 '15':1980 '180':780 '1gb':1239 '2':1193,1324,1846 '20':1611 '200':202,327,657,2654,2696,2838,2892 '2010':481 '2025':1707,1747 '256':497,1623,2766 '3':789,1016,1218,1329,1865,1976 '30':495,1244,1626,2033 '300':2835 '3600':2889 '4':1245,1335 '400':363,632 '404':648 '413':2721 '423.45':1827 '443':2453,2455 '5':1274,1275,1339,2132 '50':686 '500':230,355,382 '5000':2065,2131 '5858':1423,1459 '6':2762 '60':3094 '6x':781,917 '900':2036 'abort':2071 'abrupt':2149 'access':209,334,2338,2527,2532,2544,3121 'access-control-allow-origin':208,333 'accident':2934 'across':130,286,426,2195 'add':3005,3201,3287 'address':1456 'affect':1772 'ai':3408 'alarm':3079,3085 'alert':3099 'alloc':2173,2211 'allow':211,336,2459 'allowhead':526 'allowmethod':522,1646 'alloworigin':521,1643 'alreadi':3032 'alway':429,926,2117,2703 'amazonaws.com':613 'amazonaws.com/prod':612 'api':28,67,70,115,196,432,451,456,459,468,506,609,677,680,696,698,708,715,1142,1366,1389,1401,1477,1480,1631,1634,1663,2705,2744,2751,2756,2793,3393 'api.example.com':2128 'api.example.com/data'',':2127 'api.root.addresource':1651 'api.url':1670 'apigateway':1543 'apigateway.cors.all':1644,1647 'apigateway.lambdaintegration':1660 'apigateway.restapi':1636 'apiid':542,568 'apistack':1565 'apiurl':603,1668 'app':1682,3372 'appear':2154 'applic':22,1138 'application/json':207,235,332,414 'applyon':1212,1901 'approach':2103 'appropri':2021 'architect':3412 'ask':3469 'async':158,243,622,729,803,847,1030,1918,2047,2292,2631,2677,2768,2811,2854,3010,3275,3289 'asynchron':735 'attach':1448,1455,2326,2520 'attribut':1106 'attributedefinit':588,974 'attributenam':589,594,975,980 'attributetyp':591,977 'audit':960 'aug':1706 'august':1745 'auth':3390 'auth-specialist':3389 'authent':3388 'author':3395 'autom':3402 'autopublishalia':1216,1260 'avoid':2469,3164 'aw':2,12,24,136,144,485,514,531,557,584,610,751,775,792,968,996,1024,1088,1096,1154,1168,1176,1184,1187,1202,1233,1254,1264,1376,1492,1505,1529,1537,1546,1555,1678,1697,1748,1867,1876,1881,1884,1894,2028,2174,2216,2257,2381,2422,2439,2466,2473,2478,2485,2498,2505,2540,2800,2807,3061,3083,3108,3112,3120,3130,3149,3293,3302,3311 'await':192,253,641,817,859,1070,1076,1083,2096,2106,2125,2242,2266,2279,2284,2649,2684,2689,2701,2830,2858,2860,2876,3043,3046 'awar':2044 'aws-cdk':1677 'aws-cdk-lib':1528,1536,1545,1554 'aws-sam-c':1375 'aws-sdk':135,143,1095,1167,1175,1186,1875,1883,2256,2799,2806 'aws-serverless':1 'aws/lambda':3090 'awstemplateformatvers':480 'axio':2114,2116 'axios.get':2126 'az':2436 'azur':3364,3367,3369 'azure-funct':3366 'back':469,2940 'bad':1179,2234 'base':176 'bash':1369,1671,1807,2316 'batch':745,770,875,909,924 'batch_item_failures.append':903 'batchitemfailur':806,846,908 'batchitemfailures.push':837 'batchsiz':765,1013 'bedrock':3415 'behavior':2163 'best':419,692,712,912 'better':3239 'beyond':1512 'biggest':1322 'bill':1705,1725,1749,1757,1766,1797,2578 'billingmod':598,984,1592 'blast':3071 'block':2004,2406 'bodi':181,194,213,236,307,310,314,318,324,338,415,633,649,658,814,819,884,887,890,2200,2655,2697,2839,2871,2893 'boto3':277 'boto3.resource':293,1295 'botocore.exceptions':279 'boundari':3477 'break':1073,1080,1086,1742,1970,2168,2371,2584,2743,2931 'breaker':3056 'bucket':2821,2864,2881,2943,2978,2998 'bucket/table':2925 'buckets/prefixes':2966 'buffer':2041,2197 'build':7,17,466,1390,1394,1469,1470 'busi':188,248,319 'cach':701 'call':1943,2122,2475,3267,3414 'callback':2559,2608 'callbackwaitsforemptyeventloop':3204,3211 'capabl':3431 'case':74,511,1068,1074,1081 'catch':216,820 'catchabl':2184 'caught':1967 'caus':1984,2187,2401,2771,3250 'cdk':1498,1506,1526,1530,1538,1547,1556,1672,1679,1680,1685,1689,1693 'cdk.cfnoutput':1666 'cdk.duration.seconds':1625 'cdk.removalpolicy.destroy':1597 'cdk.stack':1567 'cdk.stackprops':1574 'chang':943,955,1692 'charg':1727 'cheaper':688 'check':1808,2081,3007,3106 'chunk':2277,2281,2286 'cidrip':2456 'circuit':3055 'clarif':3471 'class':1564 'clear':169,2551,2641,3428,3444 'cli':1354,1372,1378,1451 'client':148,154,422,3300 'clienterror':281,342 'close':2658,2669,2704 'cloud':3352,3354,3358 'cloudform':1688 'cloudwatch':441,1496,1809,1925,2152,2916,3078,3084 'code':404,409,1416,1503,1615,1782,2645,3135 'cognito':3392 'cold':39,53,1123,1129,1700,1761,1784,1791,1904,1909,1923,2328,2344,2390 'collabor':3343 'com.amazonaws':2484,2504 'com.example.handler':1207 'come':3330 'command':1467,1673,2818,2833 'common':1982,2186 'compar':2364 'comparison':678 'comparisonoper':3103 'compat':198 'complet':2576 'complex':714,1510,3398 'complianc':2537 'concurr':1247,1341,1790,3053 'configur':90,927,1446,2160,2417,2731,3219,3243,3272,3286 'connect':2606,2659,2664,2666,2670,2683 'connection.end':2702 'connection.query':2690 'consid':3213,3236 'console.error':218,822 'console.log':854,1062,1922,2298,3030 'console.warn':2066 'const':132,139,147,151,180,190,251,617,624,639,805,808,813,1033,1037,1050,1056,1092,1164,1171,1183,1581,1603,1633,1649,1653,1872,1880,2053,2084,2113,2123,2240,2246,2252,2260,2264,2271,2280,2295,2647,2672,2682,2687,2795,2803,2813,2817,2828,2856,2874,3013,3017 'construct':1521,1560,1562,1570 'constructor':1568 'consum':2203 'contain':3357 'content':205,233,330,412,2247 'content-typ':204,232,329,411 'context':160,303,874,1307,2049,2294,2633,2679 'context.awsrequestid':226 'context.callbackwaitsforemptyeventloop':171,2642,2680,3215 'context.getremainingtimeinmillis':2055,2089 'continu':3036 'control':210,335 'correl':95 'corsconfigur':520 'cost':685,1721,1736,2910 'cover':25 'cpu':1227,2228 'crash':2138 'create.js':669 'createitem':564 'createitemfunct':555 'credenti':3109,3113 'criteria':3480 'criticalfunct':1252,1270 'cross':957 'cross-region':956 'custom':1912,1926 'dangl':2604 'data':246,389,395,954,2145,2232,2241 'data.body.tostring':2248 'data.id':262 'databas':356,2605,2663,3375 'date.now':2826 'day':799 'dead':3269 'deadletterqueu':790 'deadletterqueue.arn':787 'deadlettertargetarn':785 'debug':1351,1362,1412,1421,1443 'debug-port':1420 'decoupl':734 'def':300,386,400,871,1285,1304 'default':1971,1985,2586,3217,3222,3233 'defaultcorspreflightopt':1642 'delay':1336,2330 'deleg':3344 'delet':525 'delete.js':670 'depend':1776,1842,1850 'deploy':37,83,1425,1427,1472,1489,1490,1694,1695 'describ':3434,3448 'design':75,3376,3381 'destin':1019 'destinationconfig':1017 'detect':3123 'dev':1599,1841 'develop':1346,1359 'diff':1690 'differ':2965,2997,3041 'direct':1794 'dlq':741,929,3279,3285 'dlqs':79 'dns':2408 'docclient':152 'docclient.send':254 'download':2007,2851 'downloadurl':2875,2895 'downstream':1991,2110 'driven':34,720 'due':2729 'durat':1759,1770,1817,1826,1831,2040,2567 'dynamodb':30,292,294,347,580,585,936,941,969,1005,1044,1294,1296,1552,1579,2487,2944,3322,3384 'dynamodb.attributetype.string':1591 'dynamodb.billingmode.pay':1593 'dynamodb.js':672 'dynamodb.table':296,1298,1584 'dynamodbcli':133,150,1165 'dynamodbcrudpolici':576 'dynamodbdocumentcli':140,1172 'dynamodbdocumentclient.from':153 'dynamodbendpoint':2476 'dynamodbreadpolici':551 'e':344,369,375,894,902 'e.response':349 'ec2':2440,2479,2499,2535 'edg':1699 'elast':2377 'els':316 'empti':2596 'enabl':1214 'endpoint':474,2464 'eni':2380,2387 'enterpris':716 'entir':1181,2198,2236 'entiti':2723 'environ':87,498,1618,3128,3145,3332,3339,3460 'environment-specif':3459 'error':106,217,219,221,238,242,348,350,353,357,361,373,380,385,401,417,447,635,651,821,828,1966,2074,2101,2151,2726,2732,2960,3111,3137,3183,3194,3199 'error.message':222,239 'error.stack':224 'error.statuscode':229 'especi':1940 'evaluationperiod':3095 'even':2573,2613 'event':33,117,159,166,178,302,537,563,623,673,676,719,757,804,873,881,1002,1031,1306,1409,1432,1919,2048,2293,2548,2592,2627,2632,2638,2651,2678,2812,2855,2907,2973,2981,3011,3361 'event-driven':32,718 'event.body':183,186,187 'event.get':309,313,317 'event.json':674 'event.pathparameters':626 'event.records':811,1036,3016 'eventbridg':3405 'eventnam':1038,1063,1067 'events/get.json':1410,1430 'exampl':1820 'exc':376 'exceed':2171,2769 'except':341,358,366,367,891,892,2185 'exclud':1840 'execut':608,2727 'execute-api':607 'exit':2094 'expect':1739,1996,2010,2039 'expert':3465 'expiresin':2834,2888 'explicit':2671 'export':1563 'exports.handler':157,621,802,1029,1917,2046,2291,2630,2676,2810,2853,3009 'extend':1566 'extern':1942,3266,3417 'extra':2577 'extrem':2342 'f':346,371,896 'face':1141 'fail':823,833,841,897,2061,2728,2740,3281 'failur':77,771,877,911,925,1963,2772,3252 'fals':172,1930,2643,2681,3216 'faster':1228,1333 'fastfunct':1231 'featur':691,700,717 'fewer':690 'file':2190,2237,2782,2827,3026,3034 'filter':2972,2984 'final':2700 'find':2317 'first':1314,2353,2389 'fix':1802,2019,2208,2414,2620,2779,2963 'forcibl':2175 'format':435,1045 'found':654 'frequenc':1906 'frequent':1783 'fromport':2452 'full':1241,1769,2565,3292,3310 'function':27,64,103,113,156,244,476,491,528,533,559,753,848,998,1146,1204,1235,1256,1364,1404,1487,1602,1713,1729,1731,1773,1854,1896,1939,1945,2030,2143,2147,2218,2335,2358,2373,2424,2557,2563,2957,3063,3276,3359,3368,3370,3404 'functionnam':1268 'functionresponsetyp':767 'g':1676 'gateway':29,197,433,452,1367,1481,1632,2398,2471,2495,2512,2706,2745,2794,3394 'gcp':3348,3351 'gcp-cloud-run':3350 'generat':1687 'generatelargereport':2859 'get':523,549,1240,1286,1309,1437,1658,2050 'get.handler':1614 'get.js':668 'getatt':763,786,1008,1020 'getcommand':141,256,1173 'getheavylib':1855 'getitem':538,618,642 'getitemfn':1604,1630,1661 'getitemfunct':529,1408,1424,1608 'getobjectcommand':2254,2269,2880 'getsignedurl':2804,2831,2877 'github.com':2322 'github.com/alexcasalboni/aws-lambda-power-tuning':2321 'global':490,1288 'good':1158,1280,2249 'grace':2016,2062,2095,3193 'grant':1627 'greaterthanthreshold':3104 'group':2404 'groupdescript':2443 'guid':1428 'handl':107,772,2961,3184,3200 'handleinsert':1071 'handlemodifi':1077 'handler':99,116,124,128,155,268,284,301,424,535,561,667,755,872,1000,1206,1258,1305,1613,3181,3188,3197,3208 'handler.js':125 'handler.py':269 'handleremov':1084 'handlerequest':1208 'happen':2180 'hard':2747 'hardcod':3107,3117,3119,3148,3321,3335 'hash':597,983 'header':203,231,328,410 'heaptot':2306 'heapus':2300 'heavi':1337,1733,1775,1849,1861,2201 'heavy-librari':1860 'heavylib':1852,1857,1858,1864 'high':1144,1709,1935,2140,2902 'high-traff':1143 'higher':1724 'hit':2159 'horizon':1012 'http':66,458,473,505,679,2121,2755 'httpapi':512,516,540,544,566,570,606 'httpmethod':1436 'https':2460 'hyperplan':2386 'iam':3125,3153,3160,3169,3174 'id':96,261,394,396,445,547,590,595,625,627,629,637,643,976,981,1434,1571,1577,1589,1656 'idempot':935,3006 'idl':2356,2580 'imag':993,1108,1112,1118 'impact':1323,1795 'implement':91,114,2042 'import':270,272,274,276,280,865,867,1157,1160,1180,1338,1524,1532,1541,1550,1559,1871,3291,3298,3309,3317 'improv':2382 'includ':443,1726 'inconsist':2162 'increas':1330,1718,2209,3237,3263 'infinit':2001,2896 'info':377,3206,3221 'infrastructur':1501,1511 'init':1229,1277,1334,1383,1681,1702,1751,1805,1812,1816,1823,1825,1830 'initi':126,282,421,1282,1312,1379,1730,1763,1781 'input':175,306,3474 'inputbucket':2980 'insert':1040,1069 'insight':442 'inspector':1466 'instal':1370,1374,1675 'instanc':2536 'instead':2789 'insuffici':2075 'integr':453,460,3409 'interfac':2379 'intern':240,383 'invalid':364 'invoc':131,287,428,1758,2196,2354,2900,2913,2920,3075,3088,3282,3290 'invocationalarm':3081 'invocations/min':3102 'invok':1402,1407,1419,1484,1485 'ipprotocol':2450 'iscoldstart':1915,1921,1929 'isinst':312 'issu':1998,2399 'item':392,399,640,645,652,660,831,842,876,910,973,1640,1650,1652,1654,2085,2087,2108 'item.addmethod':1657 'itemidentifi':838,904 'items.addresource':1655 'itemsapi':1638 'itemst':503,554,579,582,966,1586 'itemstable.streamarn':1009 'java/.net':63,1196,1328,1889 'java21':1210,1899 'javafunct':1200,1892 'javascript':121,615,800,1027,1151,1832,1907,2045,2112,2233,2290,2629,2661,2784,2845,3008 'js':1048 'json':271,365,439,866,1429,1440,2870,2887 'json.dumps':339,416 'json.jsondecodeerror':359 'json.loads':308,885 'json.parse':185,815 'json.stringify':214,220,237,634,650,659,2656,2698,2840,2872,2894 'kb':2767 'keep':82,1276 'key':260,393,709,1102,1105,2824,2867,2884,3018,3035,3045,3049,3122,3132,3139,3151 'key.startswith':3028 'keyschema':593,979 'keytyp':596,982 'lambda':26,98,102,112,123,267,462,471,527,723,782,918,945,1128,1265,1363,1471,1513,1534,1601,1712,1720,1931,1938,1972,2011,2142,2170,2313,2327,2334,2372,2444,2521,2556,2587,2609,2622,2734,2760,2904,2921,2932,3168,3180,3187,3196,3413 'lambda.code.fromasset':1616 'lambda.function':1606 'lambda.runtime.nodejs':1610 'lambdasecuritygroup':2429,2437 'languag':1516,1683 'larg':1778,2189,2231,2714,2718,2725,2781,2843 'largedata':2857,2873 'larger':2008 'last':1342 'latenc':57,682,1131,1136,1800 'latency-sensit':56,1135 'lazi':1281,1847 'leak':2194 'least':3177 'let':1851,1914 'letter':3270 'lib':671,1531,1539,1548,1557 'lib/api-stack.ts':1523 'librari':1862,2202 'light':1278 'limit':2161,2709,2749,3070,3436 'line':1822 'live':1217,1261,1272 'llm':3411 'llm-architect':3410 'llms':3418 'load':1777,1848,2165,2235 'local':1345,1348,1358,1368,1396,1398,1406,1411,1418,1475,1479,1483 'localhost':1457 'localroot':1460 'locat':3042 'log':93,275,436,448,868,961,1494,1497,1810,1821,1956,2153,2917 'logger':288,869 'logger.error':345,370,895 'logger.setlevel':290 'logging.getlogger':289,870 'logging.info':291 'logic':189,249,320,739,853,1735,2575,3371 'long':2079 'longer':1994 'look':1814 'loop':167,2002,2549,2593,2628,2639,2897 'low':1786,2058,2068,3227,3241,3247,3262 'lower':681,684 'make':3265 'malform':2733 'manag':3143,3157 'mani':3229 'match':3429,3445 'math.round':2301,2307 'max':2035,2156,3067 'maximum':1978 'maximumretryattempt':1015 'maxreceivecount':788 'may':2774,3224,3249,3259 'mb':2222,2305,2311,2753,2758,2763 'measur':49,1803 'medium':2332,2553,2711 'memori':46,1222,1225,1331,2136,2157,2172,2192,2193,2206,2210,2226,2239,2288,2299,2319,3218,3235 'memorys':496,1237,1622,2220 'messag':351,405,418,743,826,850,856,861,889,932,934,3118,3147,3171,3195,3212,3231,3253,3283,3308,3334 'messageid':901,906 'messageretentionperiod':796 'method':548,573,1648 'metric':1913,1927 'metricnam':3087 'millisecond':1819 'minim':52,1127,1834 'minut':1981,2915 'misconfig':2405 'misconfigur':1933 'miss':636,3203,3482 'modif':1110,1114 'modifi':1041,1075 'modular':1153,1870,3314 'monitor':1903,2287,3076 'ms':1828 'much':2205 'multipl':2435 'must':3114 'my-api':1387 'myfunct':2026,2214,2420 'mysql':2673 'mysql.createconnection':2685 'mysql2/promise':2675 'name':259,299,501,1301,1386,1447,1588,1620,2823,2866,2883,2987,3324,3328,3337 'namespac':3089 'nat':2397,2470 'necessari':2517 'need':472,737,1163,1249,1519,2376,2526,3347,3363,3374,3387,3397,3407 'network':1997,2378 'never':3115 'new':149,255,990,1107,1115,1380,1583,1605,1635,1659,1665,2073,2100,2262,2268,2815,2819,2862,2879 'newimag':1051,1064,1072,1079 'node':1453 'node.js':122,170,1413,2547,2555,2591,3207 'nodejs20.x':493,1385 'non':2367 'non-vpc':2366 'none':1284,1293 'notif':962 'npm':1674,1843 'null':1055,1061,1853 'object':1049 'objectcr':2983 'obvious':2777 'old':992,1111,1117 'oldimag':1057,1065,1078,1085 'onfailur':1018 'oom':2137 'oper':2005,2080 'optim':41,51,1125,1148,1316,2318 'option':161 'origin':212,337,1645 'os':273 'os.environ':297,1299 'outbound':2461 'output':602,1662,2995,3454 'outputbucket':3001 'outsid':127,283,423 'over':3158,3172 'overhead':2396 'packag':84,1149,1320,1473,1779,1835,3307,3320 'parallel':3069 'param':2244,2270 'paramet':638 'pars':174,305 'partial':769,923,1957 'partitionkey':1587 'pass':2791 'path':545,571,1438 'pathparamet':1433 'pattern':35,97,100,454,722,938,1126,1347,1500,3385,3433 'pay':599,985 'payload':2707,2748 'pend':2607 'per':600,986,1594 'perform':3240 'period':2082,2357,3093 'permiss':1628,3159,3166,3173,3475 'phase':1703,1752,1806 'pip':1373 'plain':1047 'plan':706 'poison':931 'polici':550,575,3161,3175 'pool':2667 'poor':1789 'port':1422,1458 'portabl':3342 'post':524,574 'postgr':3378 'postgres-wizard':3377 'power':2314 'practic':420,913 'prefer':65,1514 'prefix':2971,2988,3000,3004 'presign':2786,2850 'previous':1760 'principl':42,3179 'prioriti':1317 'privat':2339,2534 'privateroutet':2493 'privatesubnet1':2432 'privatesubnet2':2434 'privileg':3178 'process':322,387,730,736,742,825,852,855,888,899,933,1958,2144,2188,2251,2274,3003,3025,3029,3033,3037,3048 'process.env.bucket':2822,2865,2882 'process.env.table':258 'process.memoryusage':2297 'processchunk':2285 'processeditem':2098 'processfil':3044 'processingqueu':773 'processingqueue.arn':764 'processitem':2107 'processmessag':818,849 'processor':118 'processorfunct':749 'processrequest':193,245,2650 'prod':519 'product':9,19,1715,1845 'production-readi':8,18 'program':1515 'progress':2092,2105 'project':662,1381,1392 'promis':2245 'prop':1573,1578 'proper':101,431,2660 'properti':517,534,541,560,567,587,754,761,778,795,971,999,1006,1205,1236,1257,1267,1897,2031,2219,2425,2442,2481,2501,2977,3064,3086 'protocol':1465 'provis':1246,1340 'provisionedconcurr':1262 'provisionedconcurrencyconfig':1266 'provisionedconcurrentexecut':1273 'proxi':2735 'prune':1844 'publish':2950 'publishedvers':1213,1902 'putobjectcommand':2797,2820,2863 'python':265,266,862,863,1279 'qualifi':1271 'queue':762,777,794,1026,3271 'radius':3072 'rais':2182 'rds':3380 'rds/elasticache':2529 'react':939 'reaction':952 'readi':10,20,2618 'real':950 'real-tim':949 'receiv':2717 'recommend':507,1801,2018,2207,2413,2619,2778,2962 'record':809,879,882,886,900,905,1034,3014 'record.body':816 'record.dynamodb.newimage':1052,1054 'record.dynamodb.oldimage':1058,1060 'record.eventname':1039 'record.messageid':827,839 'record.s3.object.key':3019 'recurs':2899 'redrivepolici':784 'reduc':1319,1829 'ref':502,543,553,569,578,1269,2428,2431,2433,2447,2489,2492,2509,2979 'region':611,958,2486,2506 'reliabl':728 'remain':2051,2077 'remainingtim':2054,2064 'remoteroot':1463 'remov':1042,1082 'removalpolici':1596 'repeat':2919 'replic':959 'report':829,1813,1824,2868,2885 'reportbatchitemfailur':768,921 'reportid':2869,2886 'request':323,388,444,601,702,987,1454,1595,2719,2722,3427 'request/response':710,2754,2759 'requestid':225 'requir':134,142,619,1094,1166,1174,1185,1859,1874,1882,2115,2255,2538,2674,2798,2805,3473 'reserv':3052 'reservedconcurrentexecut':3065 'resolut':2409 'resort':1343 'resourc':504,748,965,1199,1230,1251,1891,2025,2213,2340,2419,3058 'respons':199,354,362,381,390,402,434,1961,2124,2199,2265,2616,2715,2736,2737,2765,2844 'response.body':2273 'response.get':398 'rest':69,455,467,695,697,2750 'restapinam':1639 'result':191,215,252,321,340,2648,2657,3050 'result.item':264 'retri':81,738,836,844 'return':195,200,227,263,325,352,360,379,397,406,430,630,646,655,840,845,907,1302,1863,2569,2598,2652,2694,2713,2836,2849,2890 'reus':129,285,425 'reusabl':1520 'review':3466 'right':44,1220 'right-siz':43,1219 'riskyfunct':3059 'role':3126,3154,3170 'routetableid':2491 'row':2688,2699 'rule':2986 'run':1395,1711,1937,2057,2067,3353,3355 'runaway':2909,3074 'runtim':492,1209,1384,1609,1898,2178 's3':2006,2261,2507,2787,2814,2832,2848,2878,2937,2968,2976,2982 's3.getobject':2243 's3.send':2267,2861 's3client':1873,2253,2263,2796,2816 's3endpoint':2496 's3event':2974 's3key':2985 'safeti':3476 'sam':479,664,1344,1353,1371,1377,1382,1393,1397,1405,1417,1426,1450,1468,1474,1482,1488,1493 'sam/cdk':36 'save':2091,2104 'saveprogress':2097 'savetodatabas':860 'schedul':119 'scope':1569,1576,3447 'sdk':137,145,1089,1097,1155,1169,1177,1182,1188,1868,1877,1885,2258,2801,2808,3294,3303,3312,3315 'second':1954,1977,2034,2133,2348,3258 'secret':3131,3138,3142,3150,3156 'secur':2403 'securitygroup':2441 'securitygroupegress':2449 'securitygroupid':2427 'select':2691 'sensit':58,1137 'server':241,384 'serverless':3,11,13,21,486,515,532,558,752,997,1203,1234,1255,1499,1895,2029,2217,2423,3062,3349,3365 'servic':1641,1992,2467,2474,2541 'servicenam':2482,2502 'set':914,2020,2037,2109,2118,2320,3051,3210,3214 'settimeout/setinterval':2603 'sever':1708,1934,2139,2331,2552,2710,2901,3110,3136,3162,3185,3205,3220,3244,3273,3296,3325 'sg':2445 'shake':1839 'sharp':1698 'short':1988 'show':1691,2918 'shutdown':2017 'signific':2384 'silent':1962 'simpl':72,509 'simpler':689 'simul':857 'singl':1403,1486 'situat':1710,1936,2141,2333,2554,2712,2903 'size':45,1150,1221,1321,1836,2708 'skill':5,15,3424,3439 'skill-aws-serverless' 'skip':3020,3031 'slow':1780,2343,2363,2412 'small':85 'smaller':3306,3319 'snapstart':61,1195,1211,1215,1326,1887,1900 'sns':2949 'sourc':179,2924,3134 'source-sickn33' 'special':4,14 'specialist':3391 'specif':3299,3461 'sqs':721,726,760,776,793,1025 'sqs/sns':31 'sqsevent':758 'src':666 'src/handlers':1617 'src/handlers/create.handler':562 'src/handlers/critical.handler':1259 'src/handlers/get.handler':536 'src/handlers/get.js':616 'src/handlers/processor.handler':756 'src/handlers/processor.js':801 'src/handlers/stream.handler':1001 'src/handlers/stream.js':1028 'stack':223 'stagenam':518 'start':40,54,1124,1130,1400,1476,1478,1701,1762,1785,1792,1905,1910,1924,2329,2345,2391 'start-api':1399 'startingposit':1010 'startup':1734 'statist':3091 'status':403,408 'statuscod':201,228,326,407,631,647,656,2653,2695,2837,2891 'step':2956,3403 'still':2394 'stop':2148,3467 'store':2846 'str':315,374 'stream':937,1003,1007,1099,2230,2250,2272,2275,2283 'streamdlq':1022 'streamdlq.arn':1021 'streamprocessorfunct':994 'streamspecif':988 'streamviewtyp':989 'string':184,1572 'structur':92,104,438,661 'sub':605,2483,2503 'subnetid':2430 'substitut':3457 'success':3479 'sum':3092 'super':1575 'switch':1066 'symptom':1716,1944,2146,2341,2562,2720,2908 'sync':2764 'synth':1686 'tabl':295,298,500,581,586,942,970,1283,1287,1289,1291,1297,1300,1303,1308,1310,1580,1582,1619,2948,3323,3327,3336 'table.get':391 'table.grantreaddata':1629 'table.tablename':1621 'tablenam':257,552,577,972 'tail':1495 'take':1993,2564 'task':120,1949,2570,3443 'tcp':2451 'tell':2621 'templat':665 'template.yaml':478,663,747,964,1198,2024 'termin':2012,2176 'test':675,1349,1361,1365,1431,3463 'though':2574 'thousand':2911 'threshold':3097 'throw':2072,2099 'time':951,1946,1950,2052,2060,2070,2076,2571,2581 'timeout':48,494,783,919,1243,1624,1932,1973,1983,1986,2014,2022,2032,2043,2102,2111,2119,2130,2351,2402,2566,2612,3242,3248,3254 'timer':2561 'topic':2952 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'toport':2454 'trace':450 'track':1908 'traffic':1145,1787,2407 'transform':484,711 'treat':3452 'tree':1838 'tri':173,304,812,883,2686 'trigger':724,2905,2927,2935,2938,2945,2954,2969,2992,3345 'trim':1011 'true':378,1916 'truncat':2155,2738 'try/catch':3191,3202 'tune':2315 'type':206,234,331,413,513,530,539,556,565,583,750,759,774,791,967,995,1004,1023,1101,1201,1232,1253,1263,1452,1590,1893,2027,2215,2421,2438,2477,2497,2975,3060,3082 'typeof':182 'typescript':1522,1684 'unexpect':372,1948,3251 'unexplain':1717 'unless':2524 'unmarshal':1043,1053,1059,1091,1093 'unresolv':2602 'updat':2946 'upload':2783,2825,2990,2994 'uploadurl':2829,2841 'url':1664,2788,2852 'usag':705,2289 'use':60,73,86,110,465,510,733,920,948,1087,1134,1152,1194,1315,1325,1357,1509,1837,1866,1886,2158,2296,2312,2462,2514,2665,2785,2964,3124,3141,3152,3176,3232,3313,3338,3383,3421,3422,3437 'used.heaptotal':2308 'used.heapused':2302 'user':1140,2693,3346,3362,3373,3386,3396,3406 'user-fac':1139 'v2':3295 'v3':1090,1156,1869,3304,3316 'valid':703,3105,3462 'valu':604,1669,2989 'variabl':88,499,3129,3146,3333,3340 'vcpu':1242 'verifi':2415 'version':864,1444 'view':1100 'visibilitytimeout':779,915 'vpc':2000,2325,2337,2361,2368,2375,2393,2416,2448,2463,2490,2510,2515,2523,2531,2546 'vpc-attach':2324 'vpcconfig':2426 'vpcendpoint':2480,2500 'vpcendpointtyp':2494,2511 'vpcid':2446,2488,2508 'vs':1415 'vscode/launch.json':1441 'waf':704 'wait':164,2588,2610,2625,2636 'warm':427 'warn':3163,3186,3245,3274,3297,3326 'wasn':1764 'way':1755 'wildcard':3165 'without':2015,2150,2181,2545,3182,3198 'wizard':3379 'work':858,2359 'workflow':3399,3401 'workflow-autom':3400 'workload':59,1990,3230 'workspaceroot':1461 'write':2922,2939,3039 'writetos3':3047 'wrong':2959 'x':1612,1953 'yaml':477,746,963,1197,1223,1250,1518,1890,2023,2212,2418,2468,2967,3057,3080","prices":[{"id":"8b748e98-6870-4a17-ba2b-874a2e6dfcca","listingId":"f96c0a07-bf58-4678-a121-57a21e057956","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:24.789Z"}],"sources":[{"listingId":"f96c0a07-bf58-4678-a121-57a21e057956","source":"github","sourceId":"sickn33/antigravity-awesome-skills/aws-serverless","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/aws-serverless","isPrimary":false,"firstSeenAt":"2026-04-18T21:31:44.966Z","lastSeenAt":"2026-05-18T18:50:32.362Z"},{"listingId":"f96c0a07-bf58-4678-a121-57a21e057956","source":"skills_sh","sourceId":"sickn33/antigravity-awesome-skills/aws-serverless","sourceUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/aws-serverless","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:24.789Z","lastSeenAt":"2026-05-07T22:40:38.390Z"}],"details":{"listingId":"f96c0a07-bf58-4678-a121-57a21e057956","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"aws-serverless","github":{"repo":"sickn33/antigravity-awesome-skills","stars":37911,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-05-18T08:24:49Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"65230f8a5d7b116d64ce2754f21270f9544c2b5f","skill_md_path":"skills/aws-serverless/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/aws-serverless"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"aws-serverless","description":"Specialized skill for building production-ready serverless"},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/aws-serverless"},"updatedAt":"2026-05-18T18:50:32.362Z"}}