Most stream and queue consumers waste money invoking Lambda for events the handler ignores in the first five lines. Event source mapping filters push that predicate to AWS so you never pay the invoke — the unfair advantage when DynamoDB streams fan out every attribute change or SQS carries mixed message types.
⚡ TL;DR: Attach FilterCriteria on ESMs for DynamoDB Streams, Kinesis, SQS, and MSK. Prefer allowlists on event names / type fields. Keep filters small and testable; dual-write metrics for “matched vs dropped” via stream lag dashboards. Combine with idempotency patterns from Bedrock Agents Idempotent Tool Calls when filtered traffic still retries.
Filter at the mapping, not in the handler prologue
// GOOD: only MODIFY with status=PAID
await lambda.createEventSourceMapping({
FunctionName: "fulfill-order",
EventSourceArn: streamArn,
StartingPosition: "LATEST",
FilterCriteria: {
Filters: [
{
Pattern: JSON.stringify({
eventName: ["MODIFY"],
dynamodb: {
NewImage: {
status: { S: ["PAID"] },
},
},
}),
},
],
},
});
// BAD: invoke on everything, return early
export const handler = async (event: { Records: Array<{ eventName: string }> }) => {
for (const r of event.Records) {
if (r.eventName !== "MODIFY") continue; // you already paid for this invoke
}
};
✅ Pattern matches DynamoDB typed images ({ "S": ["PAID"] }).
❌ Filtering only in code after a full batch invoke.
SQS multi-type topics (really: one queue, many producers)
{
"body": {
"type": ["OrderPaid", "OrderRefunded"]
}
}
FilterCriteria: {
Filters: [
{ Pattern: '{"body":{"type":["OrderPaid","OrderRefunded"]}}' },
],
},
If body is a JSON string, use the SQS filter semantics carefully — AWS matches on the message body structure when content-type is JSON. Validate with aws lambda create-event-source-mapping dry-runs in staging.
Operational pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
| Wrong typed image path | Silent drop of all events | Integration test with real stream record |
| Over-narrow filter after schema change | Lag grows, business stalls | Schema contract tests |
| Multiple filters OR semantics misunderstood | Unexpected invokes | Document OR across Filters array |
| Relying on filters for authz | Security bug | Filters ≠ authorization |
// Canary: emit a synthetic PAID modify and expect invoke metric +1 within 60s
Dropped events do not invoke — they also do not hit your DLQ. That is desired for noise, catastrophic for misconfigured filters. Alarm on business KPIs (orders fulfilled/min), not only Lambda errors.
Closing checklist
- [ ] ESM FilterCriteria deployed as code (CDK/Terraform), not console clicks
- [ ] Patterns use correct DynamoDB type wrappers
- [ ] Staging test proves match and non-match cases
- [ ] KPI alarms detect accidental total-drop
- [ ] Handlers remain defensive (filters can lag schema)
- [ ] Cost dashboard shows invoke drop after filter rollout
Related reading
- Bedrock Agents: Idempotent Tool Calls Against DynamoDB Writes
- Lambda Warm Pools: Low-Latency Backends for Coding Agent Tools
- OpenTelemetry for LLMs: Trace Prompt Latency Across Microservices
- CI Failure Triage Bots: Separate Flaky Noise From Real Regressions
Last updated on September 11, 2026
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
