Serverless patterns: cold start optimization (Provisioned Concurrency, SnapStart, keep-warm), event source mapping (S3/SQS/DynamoDB Streams/EventBridge), AWS Step Functions, Lambda Powertools (logging/metrics/tracing), idempotency, cost model, and observability with X-Ray.
From clarcnpx claudepluginhub marvinrichter/clarc --plugin clarcThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Production patterns for AWS Lambda and serverless architectures — cold starts, event routing, orchestration, and observability.
Cold Start = Container Boot + Runtime Init + Function Init
~100-500ms + ~50-200ms + your code
Warm Start = (container already running)
~1-10ms (just your function code)
Cold Start by Runtime (approximate):
| Runtime | Cold Start |
|---|---|
| Rust (custom runtime) | ~1ms |
| Go | ~5ms |
| Node.js 20 | ~80–150ms |
| Python 3.12 | ~100–300ms |
| Java 21 (without SnapStart) | ~1000–3000ms |
| Java 21 (with SnapStart) | ~100–200ms |
1. Provisioned Concurrency (eliminates cold starts)
# serverless.yml / SAM template
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 5 # Always warm instances
# Schedule scaling (cost optimization)
# Scale up before peak, down after
aws application-autoscaling register-scalable-target \
--service-namespace lambda \
--resource-id function:my-function:prod \
--scalable-dimension lambda:function:ProvisionedConcurrency
aws application-autoscaling put-scheduled-action \
--service-namespace lambda \
--resource-id function:my-function:prod \
--scalable-dimension lambda:function:ProvisionedConcurrency \
--scheduled-action-name scale-up-morning \
--schedule "cron(0 7 * * ? *)" \
--scalable-target-action MinCapacity=10,MaxCapacity=10
2. SnapStart (Java only — Firecracker MicroVM snapshot)
# SAM template
MyFunction:
Type: AWS::Serverless::Function
Properties:
SnapStart:
ApplyOn: PublishedVersions
AutoPublishAlias: prod
3. Keep-Warm Pings (free mitigation)
// handler — detect and discard warm pings
export const handler = async (event: any) => {
if (event.source === 'keep-warm') {
return { statusCode: 200 };
}
return handleRealRequest(event);
};
# EventBridge rule — ping every 5 minutes
KeepWarmRule:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: rate(5 minutes)
Targets:
- Id: MyLambdaTarget
Arn: !GetAtt MyFunction.Arn
Input: '{"source": "keep-warm"}'
4. Minimize Package Size
# Check your Lambda deployment size
aws lambda get-function --function-name my-function \
--query 'Configuration.CodeSize'
# Reduce: only bundle what you need
# Node.js: esbuild with tree-shaking
esbuild src/handler.ts --bundle --minify --target=node20 \
--platform=node --outfile=dist/handler.js
# Python: pip install --no-deps, use Lambda Layers for shared deps
5. Move Initialization Outside Handler
// WRONG: DB connection created on every invocation
export const handler = async (event) => {
const db = new Database(process.env.DB_URL); // ❌ Cold start every time
return db.query('SELECT ...');
};
// CORRECT: Initialize once, reuse across warm invocations
const db = new Database(process.env.DB_URL); // ✅ Runs once per container
export const handler = async (event) => {
return db.query('SELECT ...');
};
// S3 event structure
interface S3Event {
Records: Array<{
s3: {
bucket: { name: string };
object: { key: string; size: number; eTag: string };
};
eventName: string; // 'ObjectCreated:Put', 'ObjectRemoved:Delete'
}>;
}
export const handler = async (event: S3Event) => {
for (const record of event.Records) {
const { bucket, object } = record.s3;
const key = decodeURIComponent(object.key.replace(/\+/g, ' '));
const file = await s3.getObject({
Bucket: bucket.name,
Key: key,
}).promise();
await processFile(file.Body as Buffer, key);
}
};
import { SQSEvent, SQSBatchResponse } from 'aws-lambda';
export const handler = async (event: SQSEvent): Promise<SQSBatchResponse> => {
const failures: SQSBatchResponse['batchItemFailures'] = [];
await Promise.all(
event.Records.map(async (record) => {
try {
const message = JSON.parse(record.body);
await processMessage(message);
} catch (error) {
// Partial batch failure — only failed items go back to queue
failures.push({ itemIdentifier: record.messageId });
}
})
);
return { batchItemFailures: failures };
};
# SAM/CDK — SQS trigger configuration
MyFunction:
Events:
SQSQueue:
Type: SQS
Properties:
Queue: !GetAtt MyQueue.Arn
BatchSize: 10
FunctionResponseTypes:
- ReportBatchItemFailures # Required for partial failure handling
MaximumBatchingWindowInSeconds: 5
import { DynamoDBStreamEvent, DynamoDBRecord } from 'aws-lambda';
import { unmarshall } from '@aws-sdk/util-dynamodb';
export const handler = async (event: DynamoDBStreamEvent) => {
for (const record of event.Records) {
const eventType = record.eventName; // 'INSERT' | 'MODIFY' | 'REMOVE'
if (eventType === 'INSERT' || eventType === 'MODIFY') {
const newItem = unmarshall(record.dynamodb?.NewImage ?? {});
await syncToSearchIndex(newItem);
}
if (eventType === 'REMOVE') {
const oldItem = unmarshall(record.dynamodb?.OldImage ?? {});
await removeFromSearchIndex(oldItem.id);
}
}
};
// EventBridge event
interface OrderPlacedEvent {
source: string; // 'myapp.orders'
'detail-type': string; // 'Order Placed'
detail: {
orderId: string;
customerId: string;
amount: number;
};
}
export const handler = async (event: EventBridge.EventBridgeEvent<'Order Placed', OrderDetail>) => {
const { orderId, customerId, amount } = event.detail;
await processOrder({ orderId, customerId, amount });
};
# EventBridge rule — content-based filtering
OrderRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source: ['myapp.orders']
detail-type: ['Order Placed']
detail:
amount: [{ numeric: ['>', 100] }] # Only large orders
Targets:
- Id: ProcessLargeOrder
Arn: !GetAtt ProcessOrderFunction.Arn
| Type | Duration | Pricing | Use Case |
|---|---|---|---|
| Standard | Up to 1 year | Per state transition | Long-running workflows, auditing |
| Express (Async) | Up to 5 minutes | Per invocation + duration | High-volume events |
| Express (Sync) | Up to 5 minutes | Per invocation + duration | Request-response |
{
"Comment": "Order processing workflow",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "arn:aws:lambda:...:function:ValidateOrder",
"Next": "ChargePayment",
"Catch": [{
"ErrorEquals": ["ValidationError"],
"Next": "HandleValidationError"
}],
"Retry": [{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2.0
}]
},
"ChargePayment": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "ChargePayment",
"Payload": {
"orderId.$": "$.orderId",
"taskToken.$": "$$.Task.Token"
}
},
"HeartbeatSeconds": 300,
"Next": "FulfillOrder"
},
"FulfillOrder": {
"Type": "Parallel",
"Branches": [
{
"StartAt": "ShipItems",
"States": {
"ShipItems": { "Type": "Task", "Resource": "...", "End": true }
}
},
{
"StartAt": "SendConfirmation",
"States": {
"SendConfirmation": { "Type": "Task", "Resource": "...", "End": true }
}
}
],
"Next": "UpdateInventory"
},
"WaitForRestock": {
"Type": "Wait",
"Seconds": 86400,
"Next": "CheckInventory"
},
"OrderComplete": {
"Type": "Succeed"
},
"HandleValidationError": {
"Type": "Fail",
"Error": "ValidationFailed",
"Cause": "Order validation failed"
}
}
}
{
"ProcessItems": {
"Type": "Map",
"ItemsPath": "$.items",
"MaxConcurrency": 10,
"Iterator": {
"StartAt": "ProcessItem",
"States": {
"ProcessItem": {
"Type": "Task",
"Resource": "arn:aws:lambda:...:function:ProcessItem",
"End": true
}
}
},
"Next": "Aggregate"
}
}
Unified library for structured logging, metrics, and tracing:
npm install @aws-lambda-powertools/logger @aws-lambda-powertools/metrics @aws-lambda-powertools/tracer
import { Logger } from '@aws-lambda-powertools/logger';
const logger = new Logger({
serviceName: 'order-service',
logLevel: 'INFO',
});
export const handler = async (event: any) => {
// Automatically adds requestId, function name, cold start flag
logger.info('Processing order', { orderId: event.orderId });
try {
const result = await processOrder(event.orderId);
logger.info('Order processed', { orderId: event.orderId, result });
return result;
} catch (error) {
logger.error('Order processing failed', { error, orderId: event.orderId });
throw error;
}
};
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
const metrics = new Metrics({ namespace: 'OrderService', serviceName: 'order-processor' });
export const handler = async (event: any) => {
metrics.addMetric('OrdersReceived', MetricUnit.Count, 1);
const start = Date.now();
await processOrder(event);
metrics.addMetric('ProcessingTime', MetricUnit.Milliseconds, Date.now() - start);
metrics.addMetric('OrdersSucceeded', MetricUnit.Count, 1);
metrics.publishStoredMetrics(); // Flush to CloudWatch
};
import { Tracer } from '@aws-lambda-powertools/tracer';
const tracer = new Tracer({ serviceName: 'order-service' });
export const handler = async (event: any) => {
const segment = tracer.getSegment();
const subsegment = segment?.addNewSubsegment('processOrder');
try {
const result = await processOrder(event);
tracer.putAnnotation('orderId', event.orderId);
tracer.putMetadata('result', result);
return result;
} catch (error) {
subsegment?.addError(error as Error);
throw error;
} finally {
subsegment?.close();
}
};
For idempotency (Lambda Powertools idempotency, DynamoDB persistence), cost model (Lambda vs. Container break-even), and observability (CloudWatch Insights queries), see skill serverless-patterns-advanced.
edge-patterns — Cloudflare Workers, Vercel Edge Middleware (CPU-constrained, no cold starts)observability — General observability patterns (OpenTelemetry, Grafana)chaos-engineering — Testing Lambda failure modes (throttling, DLQ exhaustion)