DVA-C02Chapter 23 of 101Objective 1.1

Lambda Destinations and Async Invocations

This chapter covers Lambda Destinations and async invocations, a critical topic for the DVA-C02 exam. Understanding this allows you to design event-driven architectures that handle failures gracefully and route results without polling. Approximately 5-10% of exam questions touch on Lambda invocation modes, error handling, and Destinations. Mastering this topic will help you answer questions about decoupling, retry behavior, and event-driven patterns.

25 min read
Intermediate
Updated May 31, 2026

Package Delivery with Notifications

Imagine you run a busy warehouse where workers process packages. Normally, you hand a package to a worker, and they process it. But sometimes the worker is busy or the package is complex. Instead of waiting, you toss the package onto a conveyor belt (async invocation). A supervisor monitors the belt and assigns it to the next available worker. Now, you want to know what happened to each package after processing. You install two chutes at the end: one for successful packages (to shipping) and one for failed packages (to rework). Each chute has a sensor that sends a notification to your phone. This is exactly how Lambda Destinations work: after an async invocation completes (success or failure), Lambda sends the result to a configured destination (like SQS, SNS, or another Lambda). The key is that you don't poll or check logs; the notification is automatic. If the worker fails, the package goes to the failure chute, and you get alerted. You can also set up a separate chute for events that expire (DLQ). This decouples the processing from the notification, just like Lambda Destinations decouple result handling from the function code.

How It Actually Works

What are Lambda Async Invocations?

Lambda functions can be invoked synchronously (InvocationType='RequestResponse') or asynchronously (InvocationType='Event'). For async invocations, Lambda queues the event and returns a 202 response immediately. The function processes the event later. This is ideal for non-latency-sensitive workloads like processing S3 events, SNS notifications, or scheduled tasks.

Why Async Invocations Exist

Async invocations decouple the producer from the consumer. The producer (e.g., S3) doesn't wait for the function to complete. This improves scalability and fault tolerance. If the function fails, Lambda automatically retries twice (total 3 attempts) with a 1-minute wait between retries. After all retries fail, the event can be sent to a Dead Letter Queue (DLQ) or a Lambda Destination (on failure).

Internal Mechanism

When you invoke a Lambda function asynchronously, the event is placed in an internal SQS queue managed by Lambda. Lambda's internal poller reads from this queue and invokes your function. If the function returns an error (including throttling or invocation errors), Lambda retries based on the configured retry policy. The default retry count is 2 (so 3 total attempts). The maximum event age is 6 hours (default) but can be set from 60 seconds to 6 hours. After the event expires or all retries fail, the event is discarded unless a DLQ or Destination is configured.

Lambda Destinations

Lambda Destinations allow you to route the result of an async invocation to another AWS service without writing code. You can configure destinations for two states:

On success: Invocation succeeds (no error thrown).

On failure: Invocation fails after all retries or expires.

Each destination can be one of:

Another Lambda function

Amazon SQS (Standard or FIFO)

Amazon SNS (Standard or FIFO)

Amazon EventBridge (Event bus)

You can configure up to two destinations per function (one for success, one for failure). Destinations receive a JSON payload containing the result, request context, and response context.

Configuration

Destinations are configured on a function's asynchronous invocation configuration. You can do this via AWS Console, CLI, or SDK. CLI example:

aws lambda put-function-event-invoke-config \
  --function-name my-function \
  --destination-config '{"OnSuccess":{"Destination":"arn:aws:sqs:us-east-1:123456789012:my-queue"},"OnFailure":{"Destination":"arn:aws:sns:us-east-1:123456789012:my-topic"}}'

You can also configure event invoke config for a specific qualifier (version or alias) using the --qualifier parameter.

Retry Behavior and DLQ vs Destinations

Before Destinations, the only way to capture failed events was a Dead Letter Queue (DLQ). DLQ can be an SQS queue or SNS topic. DLQ receives events only after all retries are exhausted. Destinations are more flexible because they can handle both success and failure, and they provide richer context. However, DLQ and Destinations are not mutually exclusive; you can have both, but if both are configured, the Destination takes precedence for failure events (the event is sent to the Destination, not the DLQ).

Interaction with Other Services

Many AWS services invoke Lambda asynchronously: S3, SNS, CloudWatch Events, EventBridge, etc. When these services invoke Lambda, they use async invocation by default. The function's async configuration (including Destinations) applies. For example, if S3 sends an event to Lambda and the function fails, after retries, the event can be sent to an SNS topic via Destination.

Event Payload

The destination receives a JSON payload with the following structure:

{
  "version": "1.0",
  "timestamp": "2019-11-24T23:08:25.651Z",
  "requestContext": {
    "requestId": "c2a6f2ae-...",
    "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
    "condition": "Success",
    "approximateInvokeCount": 1
  },
  "requestPayload": {
    ... // original event
  },
  "responseContext": {
    "statusCode": 200,
    "executedVersion": "$LATEST",
    "functionError": "" // only on failure
  },
  "responsePayload": {
    ... // function's return value or error object
  }
}

Maximum Event Age and Retry Attempts

Default maximum event age: 6 hours.

Configurable range: 60 seconds to 6 hours.

Default retry attempts: 2 (total 3).

Configurable range: 0 to 2.

If you set retry attempts to 0, the function is invoked once; if it fails, it goes to Destination/DLQ immediately.

Error Handling

When a function fails asynchronously, Lambda captures the error and retries. If the function is throttled (concurrency limit), Lambda retries with backoff. If the function code throws an unhandled exception, it counts as a failure. If the function times out (max 15 min), it also counts as a failure.

Best Practices

Always configure a Destination or DLQ for async invocations to avoid losing events.

Use Destinations over DLQ because they provide more context and can handle success cases.

Set appropriate max event age and retry attempts based on your use case.

For FIFO ordering, use SQS FIFO as destination; SNS FIFO also supported.

Destinations can be chained: a destination Lambda can invoke another function with Destinations.

Common Exam Scenarios

You need to process S3 events and send success notifications to an SNS topic. Answer: Configure a Destination on success.

You want to capture all failed invocations after retries. Answer: Configure a Destination on failure or a DLQ.

You need to handle throttling errors specifically. Answer: Throttling is treated as a failure; after retries, it goes to Destination.

Limitations

Destinations are only available for async invocations. Synchronous and event source mappings (like DynamoDB Streams) do not support Destinations.

Maximum of two destinations per function (one success, one failure).

Destination payload size is limited to 256KB (same as Lambda invocation payload).

Destinations cannot be configured for functions invoked via AWS SDK with InvocationType='Event' if the function is not configured for async? Actually, any async invocation uses the function's async config.

Monitoring and Logging

You can monitor async invocations via CloudWatch metrics: AsyncEventsReceived, AsyncEventAge, AsyncEventsDropped. For Destinations, you can log the destination invocation via CloudWatch Logs if the destination is a Lambda function.

Walk-Through

1

Invoke Lambda Asynchronously

A producer (e.g., S3) sends an event to Lambda with InvocationType='Event'. Lambda places the event in an internal queue and returns a 202 status code immediately. The event is not processed yet. The producer continues without waiting.

2

Event Queued and Retried

Lambda's internal poller reads the event and invokes the function. If the function succeeds, the result is sent to the OnSuccess destination (if configured). If the function fails (error, timeout, throttle), Lambda waits 1 minute and retries. This happens up to 2 more times (3 total). The maximum event age timer starts; if the event ages out, it is discarded or sent to OnFailure destination.

3

Retries Exhausted or Success

After all retries (if any), if the function still fails, the event is considered failed. If a Destination on failure is configured, Lambda sends the event payload to that destination. If no Destination, and a DLQ is configured, the event is sent to the DLQ. If neither, the event is discarded.

4

Destination Receives Payload

The destination service (SQS, SNS, Lambda, EventBridge) receives a JSON payload with version, timestamp, requestContext, requestPayload, responseContext, and responsePayload. The destination can then process this payload. For example, SNS can send an email, or another Lambda can perform cleanup.

5

Destination Processing

The destination processes the payload. If it's a Lambda function, it is invoked synchronously (by default) with the payload. If it's SQS, the message is enqueued and can be consumed later. If it's SNS, the message is published to subscribers. If it's EventBridge, the event is put onto the event bus.

What This Looks Like on the Job

Enterprise Scenario 1: Image Processing Pipeline

A media company uploads images to S3. Each upload triggers a Lambda function that resizes the image and stores it in another S3 bucket. This is an async invocation (S3 -> Lambda). They need to know if processing succeeded or failed. They configure a Destination on success to an SNS topic that sends an email to the operations team. On failure, they send the event to an SQS queue for manual reprocessing. They set max event age to 2 hours and retry attempts to 1 (total 2). This ensures that transient failures are retried once, but if it fails again, it goes to the queue. In production, they handle thousands of uploads per minute. They monitor AsyncEventsDropped metric to catch any events that expired. They also set a concurrency limit to avoid overwhelming downstream services.

Enterprise Scenario 2: Order Processing System

An e-commerce platform uses EventBridge to trigger a Lambda function for order validation. The function validates the order and updates a database. They use async invocation because the validation is not time-critical. They configure a Destination on failure to another Lambda that sends a notification to the customer service team via Slack (using webhook). They also configure a DLQ (SQS) as a backup. However, they realize that if both Destination and DLQ are configured, the Destination takes precedence, so the DLQ is never used. They remove the DLQ to avoid confusion. They set retry attempts to 2 (total 3) and max event age to 5 minutes because orders should be processed quickly. They also use SQS FIFO as the Destination for failure to maintain order of failed events.

Common Pitfalls

Forgetting to configure a Destination or DLQ: Events are silently dropped after retries. This is a common exam trap.

Configuring both DLQ and Destination on failure: Destination wins, but candidates think DLQ is used.

Assuming Destinations work for synchronous invocations: They don't. Only async.

Not setting appropriate max event age: If set too low, events may expire before retries complete.

Using FIFO SQS as destination without proper message group ID: The payload includes requestId, which can be used as message group ID for ordering.

How DVA-C02 Actually Tests This

DVA-C02 Objective 1.1: Design event-driven architectures

This topic falls under Domain 1: Development with AWS Services. The exam specifically tests your ability to:

Configure Lambda async invocation settings (retry attempts, max event age).

Choose between DLQ and Destinations for error handling.

Understand the payload format of Destinations.

Identify which services invoke Lambda asynchronously.

Common Wrong Answers

1.

'Destinations can be used for synchronous invocations.' This is false. Destinations only work with async invocations. Candidates confuse Destinations with Lambda's response from synchronous invocations.

2.

'A Dead Letter Queue is always better than a Destination.' DLQ only handles failures, not successes. Destinations are more flexible. The exam expects you to choose Destinations when you need to handle success or need richer context.

3.

'You can configure multiple destinations for the same state.' You can only have one destination per state (success and failure). Some candidates think you can have multiple SQS queues.

4.

'Retry attempts default to 3.' The default is 2 retries (total 3 attempts). The exam may ask 'how many retries by default?' Answer: 2.

Specific Numbers and Terms

Default retry attempts: 2 (total 3)

Default maximum event age: 6 hours (360 minutes)

Configurable max event age: 60 seconds to 6 hours

Configurable retry attempts: 0 to 2

Destination types: Lambda, SQS, SNS, EventBridge

Payload fields: version, timestamp, requestContext, requestPayload, responseContext, responsePayload

Destination only for async invocations

DLQ and Destination: if both configured for failure, Destination takes precedence

Edge Cases

Throttling: When a function is throttled, Lambda retries automatically. The event is not sent to Destination until all retries are exhausted.

Function timeout: Treated as an error; retries apply.

Event source mappings (e.g., DynamoDB Streams): These use synchronous invocation (the poller invokes the function synchronously). Destinations do not apply.

If you set retry attempts to 0, the function is invoked once. If it fails, the event goes directly to Destination/DLQ.

FIFO queues as destinations: Supported for SQS and SNS. For SQS FIFO, you must ensure the message group ID is set. Lambda uses the requestId as the message group ID.

Eliminating Wrong Answers

If the question mentions 'after the function completes successfully', look for 'OnSuccess' destination.

If the question mentions 'all retries are exhausted', the answer is 'Destination on failure' or 'DLQ'.

If the question asks for 'automatic notification without custom code', the answer is 'Lambda Destinations'.

If the question involves 'synchronous invocation', eliminate any option mentioning Destinations.

Key Takeaways

Lambda async invocations return a 202 immediately and process later.

Default retry attempts: 2 (total 3); can be set 0-2.

Default maximum event age: 6 hours; can be set 60 seconds to 6 hours.

Destinations can be configured for OnSuccess and OnFailure states.

Destination types: Lambda, SQS, SNS, EventBridge (FIFO supported for SQS/SNS).

If both DLQ and Destination on failure are set, Destination takes precedence.

Destinations only work for async invocations, not synchronous or poll-based.

The destination payload includes version, timestamp, requestContext, requestPayload, responseContext, responsePayload.

Always configure a Destination or DLQ to avoid silent data loss.

Monitoring: AsyncEventsReceived, AsyncEventAge, AsyncEventsDropped CloudWatch metrics.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Dead Letter Queue (DLQ)

Only handles failures (after retries).

Supports SQS and SNS only.

Receives original event payload only.

No additional context about the invocation.

Cannot handle success cases.

Lambda Destinations

Handles both success and failure.

Supports Lambda, SQS, SNS, EventBridge.

Receives enriched payload with request and response context.

Provides version, timestamp, and function ARN.

More flexible and recommended for new designs.

Watch Out for These

Mistake

Lambda Destinations work for all invocation types.

Correct

Destinations only work for asynchronous invocations (InvocationType='Event'). Synchronous invocations and event source mappings do not support Destinations.

Mistake

The default number of retries is 3.

Correct

The default number of retry attempts is 2, meaning a total of 3 invocation attempts (initial + 2 retries). The exam tests this exact number.

Mistake

A Dead Letter Queue and a Destination on failure can both receive the same failed event.

Correct

If both are configured, the Destination on failure takes precedence. The event is sent only to the Destination, not the DLQ.

Mistake

You can configure multiple destinations for success or failure.

Correct

You can configure at most one destination for success and one for failure. You cannot have multiple destinations for the same state.

Mistake

Destinations can be used to capture events that are dropped due to concurrency limits.

Correct

Throttled events are retried automatically. Only after all retries are exhausted does the event go to the Destination. The Destination does not receive events immediately upon throttling.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Can I use Lambda Destinations with synchronous invocations?

No. Lambda Destinations are only available for asynchronous invocations (InvocationType='Event'). For synchronous invocations, the caller receives the response directly. If you need to handle results from synchronous invocations, you must implement that logic in the caller.

What happens if I configure both a DLQ and a Destination on failure?

The Destination on failure takes precedence. The failed event will be sent to the Destination, not the DLQ. The DLQ will not receive any events. It is best to use only one mechanism to avoid confusion.

How many times does Lambda retry an async invocation by default?

By default, Lambda retries twice (so three total attempts: initial + 2 retries). You can configure retry attempts from 0 to 2. The wait time between retries is 1 minute.

Can I send the result of a successful async invocation to an SQS FIFO queue?

Yes. SQS FIFO queues are supported as destinations. Lambda uses the requestId as the message group ID to maintain order. Ensure your queue is configured correctly to accept messages.

What is the maximum event age for an async invocation?

The default maximum event age is 6 hours. You can configure it between 60 seconds and 6 hours. After this time, if the event hasn't been processed successfully, it is discarded or sent to a Destination/DLQ.

Does Lambda Destinations work with event source mappings like DynamoDB Streams?

No. Event source mappings invoke the function synchronously (the poller waits for the function to complete). Destinations only apply to asynchronous invocations triggered directly via InvocationType='Event'.

What information is included in the destination payload?

The payload includes version, timestamp, requestContext (requestId, functionArn, condition, approximateInvokeCount), requestPayload (original event), responseContext (statusCode, executedVersion, functionError), and responsePayload (return value or error).

Terms Worth Knowing

Ready to put this to the test?

You've just covered Lambda Destinations and Async Invocations — now see how well it sticks with free DVA-C02 practice questions. Full explanations included, no account needed.

Done with this chapter?