Skip to content
Technical Guide Cost Optimization

S3 to Lambda Through EventBridge: Cost, Audit, and Routing Trade-offs

Choose direct S3 events or CloudTrail data events for EventBridge without paying for an audit path your Lambda trigger does not require.

Level

Intermediate

Evidence

Evidence boundaries stated

Learning format

Explanation, practice, knowledge check

S3 to Lambda Through EventBridge: Cost, Audit, and Routing Trade-offs

Learning contract

What you will be able to do

Evidence stated in lesson
Level Intermediate
Reading 7 min read
Practice Optional exercise
Review record See lesson sources

Reviewer, review date, sources, evidence limits, and correction status are recorded in the lesson itself.

S3 to Lambda Through EventBridge: Cost, Audit, and Routing Trade-offs

Use S3's direct EventBridge integration when you need to filter and route object events to one or more targets. Add CloudTrail data events only when you also need an API-level audit record containing details such as the caller and request operation.

CloudTrail is not required merely to route an S3 object-created event through EventBridge. That distinction removes an unnecessary service from many designs and changes the cost model completely.

Before you start

Level Intermediate
You should already know S3 notifications, EventBridge rules, and Lambda invocation basics
Reading time 12 minutes
Practice time 20 minutes
Evidence AWS service behavior and prices are sourced; architecture and CDK are illustrative
Pricing checked 25 July 2026
Technical review Pending human technical review

By the end, you will be able to:

  • Choose the correct S3-to-EventBridge event source for a stated requirement.
  • Calculate CloudTrail data-event charges from request volume.
  • Add filtering, retry, and dead-letter handling to an EventBridge target.
  • Define the metrics and test events that prove delivery is working.

Why this matters

Two event paths can look similar on an architecture diagram:

S3 service event -> EventBridge -> Lambda

S3 API call -> CloudTrail data event -> EventBridge -> Lambda

They are not interchangeable.

The first path reports that something happened to an S3 object. It is the normal choice for application routing. The second records an API call through CloudTrail and can answer audit questions about the request. It also adds CloudTrail data-event charges and a separate event shape.

If a design adds CloudTrail only because an older example says EventBridge needs it, the workload pays for audit collection without establishing an audit requirement.

Architecture at a glance

Path A: direct S3 service events

S3 bucket
  -> default EventBridge bus
      -> rule matching bucket, event type, prefix, or suffix
          -> Lambda target
          -> SQS dead-letter queue for failed target delivery

After EventBridge delivery is enabled on a bucket, S3 sends supported bucket events to the default event bus. EventBridge rules perform the filtering. This is useful for routing one event to multiple consumers or applying richer event-pattern matching than a basic bucket notification.

Path B: CloudTrail data events

S3 API request
  -> CloudTrail trail configured for selected S3 data events
      -> default EventBridge bus
          -> rule matching "AWS API Call via CloudTrail"
              -> Lambda target

Use this path when the identity and API-call record are part of the requirement. The trail must be configured to capture the relevant S3 data events. A management-event trail alone does not capture high-volume object operations such as PutObject.

The event schemas differ, so a Lambda handler written for the direct S3 event cannot safely assume that a CloudTrail event has the same fields.

Choose the event source from the question you need to answer

Requirement Better default Reason
Start processing when an object is created Direct S3 event to EventBridge Fewer components and no CloudTrail data-event dependency
Route object events to several consumers Direct S3 event to EventBridge EventBridge rules provide fan-out and filtering
Record who called PutObject and from where CloudTrail data event The API audit record is the requirement
Investigate denied or unusual S3 API calls CloudTrail data event Identity and request metadata matter
Buffer a slow, single consumer S3 to SQS to Lambda A queue solves backpressure; EventBridge alone does not

Do not use the CloudTrail path as a substitute for a queue. EventBridge retries target delivery, but it is not a workload backlog that operators can throttle and drain like SQS.

Implement the direct EventBridge path

The following CDK TypeScript is illustrative. It shows the relationship between the bucket, rule, Lambda target, and dead-letter queue; it has not been deployed as part of this lesson.

// Illustrative
const bucket = new s3.Bucket(this, "Uploads", {
  eventBridgeEnabled: true,
  enforceSSL: true,
});

const failedDeliveries = new sqs.Queue(this, "EventDeliveryDlq", {
  encryption: sqs.QueueEncryption.SQS_MANAGED,
  retentionPeriod: Duration.days(14),
});

const rule = new events.Rule(this, "UploadedDocuments", {
  eventPattern: {
    source: ["aws.s3"],
    detailType: ["Object Created"],
    detail: {
      bucket: { name: [bucket.bucketName] },
      object: { key: [{ prefix: "incoming/" }] },
    },
  },
});

rule.addTarget(new targets.LambdaFunction(processor, {
  deadLetterQueue: failedDeliveries,
  retryAttempts: 8,
}));

The rule filters before invoking Lambda, which avoids paying for and operating invocations that the application will discard. The dead-letter queue shown here captures EventBridge target-delivery failures. It does not capture every application-level failure after Lambda accepts the event; the Lambda function still needs its own error handling and idempotency strategy.

Add CloudTrail only when audit evidence is required

For the CloudTrail path, scope advanced event selectors to the bucket and operations that matter. Capturing every S3 object read and write across every bucket creates cost and noise.

The selection boundary should be written as a reviewable requirement:

Capture write-only S3 data events for the production uploads bucket.
Retain the trail according to the audit policy.
Do not capture read events unless the audit requirement includes object access.

CloudTrail data events reach EventBridge with a CloudTrail-oriented detail type. Match the API event explicitly, and test the real event envelope before writing the production handler.

{
  "source": ["aws.s3"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["s3.amazonaws.com"],
    "eventName": ["PutObject", "CompleteMultipartUpload"]
  }
}

This event pattern is illustrative. Your trail selector, bucket boundary, multipart behavior, and EventBridge event must be tested together.

Cost model

The old version of this article multiplied CloudTrail data-event cost by three in one section and used the correct formula in another. Use one explicit calculation instead.

AWS listed CloudTrail trail data events at $0.10 per 100,000 events delivered when pricing was checked on 25 July 2026. S3 storage, CloudWatch Logs delivery, Lambda, EventBridge, cross-Region transfer, archives, and downstream services are separate.

For ten million captured S3 data events in one month:

10,000,000 events / 100,000 = 100 billing units
100 billing units × $0.10 = $10 CloudTrail data-event delivery

For ten million events per day over a 30-day month:

300,000,000 events / 100,000 = 3,000 billing units
3,000 billing units × $0.10 = $300 CloudTrail data-event delivery

These calculations cover CloudTrail data-event delivery only. They do not include S3 storage for trail files, Lambda requests and duration, log ingestion, EventBridge opt-in data events, archives, replay, or data transfer.

EventBridge pricing distinguishes management events, custom events, partner events, cross-account delivery, and opt-in AWS data events. Use the current EventBridge pricing table for the Region and event class rather than copying a custom-event price onto an S3 service event.

What breaks and how you detect it

Symptom or signal Likely cause What to inspect Safe response
No Lambda invocation after an upload EventBridge delivery not enabled, rule does not match, or target permission is missing Bucket notification configuration, rule matched-events metric, target failed-invocations metric Send a controlled test object and compare its real event with the rule
Direct events work but CloudTrail events do not Trail is not capturing S3 data events Trail advanced event selectors and logging status Add the narrow data-event selector and wait for delivery
Duplicate processing At-least-once delivery or target retry Object identity and application logs Make the handler idempotent using bucket, key, and version or sequencer data
Dead-letter queue grows EventBridge cannot deliver to the target DLQ payload, Lambda resource policy, throttles, target availability Correct the delivery failure, then replay deliberately
Audit cost grows unexpectedly Read and write events or too many buckets are captured CloudTrail usage and event selectors Narrow selectors to the required operations and resources

Security and cost

Security baseline

  • Restrict the Lambda resource policy to the intended EventBridge rule.
  • Encrypt sensitive buckets, trail destinations, queues, and logs according to data classification.
  • Keep the CloudTrail log bucket private and separate audit-log administration from workload administration.
  • Scope trail selectors to named resources and required event categories.
  • Treat event payloads as untrusted input; object keys and metadata can contain unexpected values.
  • Do not place secrets or personal data in event-detail fields or application logs.

Cost assumptions

Region: Confirm for the workload; example arithmetic uses the public USD trail rate
Currency: USD
Usage assumption: 10 million captured data events in one month
CloudTrail unit price: $0.10 per 100,000 data events delivered
Calculation: 10,000,000 / 100,000 × $0.10
CloudTrail subtotal: $10
Excludes: EventBridge, Lambda, S3 trail storage, CloudWatch, archives, replay and transfer
Sensitivity: Cost scales with captured events and duplicate trail copies
Pricing checked: 25 July 2026

Practice: choose and price the event path

Safety: This exercise creates no AWS resources, needs no credentials, and has no cleanup step.

Goal

Choose an event source and calculate the CloudTrail portion of the cost for one workload.

Steps

  1. Write the trigger requirement in one sentence: application routing, API audit, or both.
  2. Estimate monthly object creates, reads, deletes, and multipart completions separately.
  3. Choose direct S3 events, CloudTrail data events, or both.
  4. If using CloudTrail, identify the exact operations and buckets its selector will capture.
  5. Calculate the trail data-event charge using the current official rate.
  6. Define one test event, one failure destination, and one alarm owner.

Verify the result

The exercise is complete only when another engineer can reproduce the event-count calculation and explain why CloudTrail is present or absent.

Clean up

No resources are created.

Verify cleanup

Confirm that the exercise did not enable EventBridge delivery, create a trail, or deploy a rule in any AWS account.

Check your learning

  1. Does S3 require CloudTrail to send object-created service events to EventBridge?
  2. When is the CloudTrail event path justified?
  3. What is the CloudTrail data-event delivery charge for 50 million captured events at $0.10 per 100,000?
  4. Why does an EventBridge target DLQ not replace application-level idempotency?

Review the answers

  1. No. EventBridge delivery can be enabled directly on the S3 bucket.
  2. When the requirement needs an API audit record or CloudTrail-specific request and identity details.
  3. 50,000,000 / 100,000 × $0.10 = $50, excluding all other services.
  4. The DLQ handles failed target delivery; duplicate or repeated accepted events can still reach application code.

Before you ship

  • [ ] The design says whether the requirement is routing, audit, buffering, or a combination.
  • [ ] Direct S3 and CloudTrail event schemas have separate tested fixtures.
  • [ ] EventBridge rules filter by the intended bucket and event type.
  • [ ] Lambda processing is idempotent.
  • [ ] Target retries and a dead-letter queue are configured and owned.
  • [ ] CloudTrail selectors capture only the required resources and operations.
  • [ ] Cost calculations include event volume, unit price, date, and exclusions.
  • [ ] A controlled upload proves the full delivery path before production traffic is enabled.

Sources and verification

Continue learning

Correction history

  • 2026-07-25: Replaced the CloudTrail-required routing model with separate direct-event and audit-event paths; corrected CloudTrail cost arithmetic and removed unsupported incident claims.

Next step

Get production-grade notes and the AWS Architecture Review Checklist.

Subscribe for deep dives, architecture teardowns, and cost analyses. Plus download checklists and audit templates to turn reading into structured decisions.

Browse checklists
Rahul Ladumor

About the author

Rahul Ladumor

Independent AWS and platform architect. Writes evidence-led lessons about architecture decisions, cost, security, failure modes, and operations.

Continue learning

Build on this lesson.

These lessons share the same primary topic. Follow the explicit “Next lesson” link in the article when one is provided.