Course outline

AWS / Intermediate: application service contracts / Lesson 10

Queues, events, and idempotency

Choose asynchronous boundaries by delivery, acknowledgment, ordering, failure recovery, and business identity requirements.

About 5 min readContent reviewed
On this page

Lesson goals

  • Explain the assumptions, responsibilities, and trade-offs of queues, events, and idempotency.
  • Interpret both examples and distinguish declared intent from verified evidence.
  • Diagnose the listed failures and justify the worked decisions without using a real AWS account, credential, or service.

Distinguish a command, an event, and a delivery

A command asks for work; an event reports something that happened; a delivery is one attempt to transport a message. Their identities need not be identical. SQS provides queues, SNS provides supported fan-out patterns, and EventBridge routes events through its documented buses or other integration features. Select the service mode and target contract rather than treating all messaging products as interchangeable. The first synthetic envelope separates stable business operation identity from a delivery attempt. It contains no real customer data or resource ARN and is not sent to a broker or AWS endpoint.

json Synthetic business-message envelope
{"schema":"booking-request.v1","operation_id":"lab-booking-17","delivery_attempt":"lab-attempt-b","payload":{"seats":2},"classification":"public-synthetic-teaching-data"}

The operation ID remains stable across delivery attempts. The envelope is not a real customer request or an AWS publish operation and carries no credentials.

Read acknowledgment and retry semantics

A consumer receiving a message has not necessarily completed or acknowledged the business operation. In SQS, visibility and deletion have distinct roles; work can be delivered again if it is not removed under the chosen contract. Standard queues can deliver duplicates and do not guarantee the applicationโ€™s global order. FIFO features add documented ordering and deduplication scope but do not make every external side effect exactly once. SNS, EventBridge, Lambda, and targets can each add their own retries or failure handling. Read the exact integration documentation and define who owns redelivery and terminal recovery.

Make operation identity durable

Use a stable operation key tied to the intended business action, not a new random value for every retry. A durable idempotency record should bind accepted input, state transition, and result with an appropriate atomicity and retention policy. The second simulation suppresses repeated synthetic IDs in a sequential in-memory list. It is useful arithmetic but loses state on restart and does not coordinate concurrent consumers. A database transaction, conditional write, outbox, or another application protocol may be required to connect message handling to external effects. Deleting a message before durable success can lose work; deleting afterward can leave a duplicate window.

python Harmless duplicate-delivery model
deliveries = ["lab-a", "lab-b", "lab-a", "lab-b"]
completed = set()
for operation_id in deliveries:
    if operation_id not in completed:
        completed.add(operation_id)
print(len(deliveries), len(completed))
print("sequential in-memory model only")
Expected output
4 2
sequential in-memory model only

Four deliveries represent two synthetic operations. The set is not durable or atomic across consumers and proves no AWS delivery guarantee.

Bound backlog and poison-message behavior

A queue buffers mismatch but does not create downstream capacity. Measure age, depth, processing time, retry volume, and useful completion, not only message count. Visibility, retention, batch size, and concurrency must fit the work and recovery objectives. A dead-letter queue is a recovery workflow boundary, not an automatic fix or permission to discard customer work. Preserve safe diagnostic context and decide whether to correct, replay, reconcile, or expire a message. Replaying an entire backlog without rate control can recreate the incident or duplicate side effects. Test schema evolution and malformed messages with synthetic data.

Verify boundaries without publishing real events

Review producer permission, broker or bus policy, encryption keys, target identity, network path, and consumer authorization separately. A successful publish response does not prove final processing or user correctness. Define monitoring, retention, ownership, and reconciliation before production adoption. No queue, topic, bus, event rule, subscription, message, redrive, or service invocation is created or executed here. The examples are offline records and a pure Python simulation. Actual delivery, ordering, throughput, and price depend on service mode, Region, current documentation, and the selected integration; no universal exactly-once or free-processing promise is made.

Common errors and fixes

Publish success is called business completion

Why it happens
Transport acknowledgment replaced consumer outcome.
How to fix it
Track durable processing and reconciliation separately.
Prevent it next time
Define end-to-end event status and ownership.

FIFO is assumed to make payments exactly once

Why it happens
Service deduplication was confused with external transaction semantics.
How to fix it
Use operation-level idempotency and uncertain-outcome recovery.
Prevent it next time
Test interruption after effect before acknowledgment.

Backlog replay recreates an outage

Why it happens
Recovery ignored downstream capacity and duplicate risk.
How to fix it
Rate-limit reviewed recovery and reconcile outcomes.
Prevent it next time
Rehearse poison-message and DLQ handling safely.

Check your understanding

1. A charge succeeds but message deletion fails. What can the next delivery cause?

Show worked solution

Without durable idempotency or reconciliation it can charge again. Preserve the same operation key and verify the existing outcome before repeating the external effect. Broker acknowledgment and a payment transaction are separate state transitions.

2. Why is message age often more useful than depth alone?

Show worked solution

Age can reveal that work is not completing within its deadline even when the count is small. Interpret it with arrival rate, processing time, retries, and priority. A large healthy burst and a small stuck poison-message flow need different recovery decisions.

Key takeaways

  • A command asks for work; an event reports something that happened; a delivery is one attempt to transport a message.
  • Use a stable operation key tied to the intended business action, not a new random value for every retry.
  • Review producer permission, broker or bus policy, encryption keys, target identity, network path, and consumer authorization separately.

Official references