
EE 547 - Unit 7
Fall 2026

Tightly coupled: one service needs another to be running, fast, and unchanged to do its own work

Asynchronous: the sender hands the message to an intermediary and does not wait for the receiver

Managed service: infrastructure the provider operates and the application uses through API calls
Three services act on every check-in
Commands: check-in asks each service to act
send in check-inEvent: check-in records what occurred
Event-driven: services publish events and react to the events they subscribe to

Point-to-point: a queue
Publish-subscribe: a topic

Produce: S3 when an object is written, API Gateway when a request arrives, EventBridge Scheduler at a set time
Carry: SQS queues, SNS topics, Kinesis Data Streams logs
Process: Lambda runs a function for each delivered event or batch, with nothing running or billed between events
Run by the provider: machines, failures, and capacity, so each service is configured and called, not operated

After the reply: each service shows the check-in only once it has processed the event
One database
Two services, one event
gate-list service passenger 42 added done
notification service "checked in" message failed
check-in replied "checked in" done

Check-in, one request
After the reply

Disk: numbered blocks of a fixed size, read and written by number
File system: the software in the operating system that gives blocks names
Opening a file: a lookup in the tree, then the record, then the blocks
Cache: the tree, records, and free list are kept in memory, so most lookups never reach the disk
Block volume: a disk reached over the network (EBS)
File system on the instance
Files belong to the instance that mounts the volume
/srv/passes/42-7.pdf

Two instances, one volume
Ordinary file systems (ext4, XFS) assume one machine manages the volume

Network file system: the file system runs on a server, and the instances send it their file operations
Mounted like a disk
open("/srv/shared/passes/42-7.pdf") is unchanged
AWS runs
The application sets
Capacity
Billing
Throughput
Created and mounted

Round trip per operation: open, close, list, and every read or write not served from the client’s cache
Large files
Workloads it serves poorly
Close-to-open consistency: the NFS guarantee
Locks
In practice: write, close, then open on another instance, and locks where two instances write the same file


/var/data on EBS
/srv/shared on EFS
Both: paths, rename, append, in-place writes, and locks, reached by a mount from inside one network

Object: bytes and metadata stored under a key in a bucket
What the trade gives

Two writers, one key

Sorted keys, listed by prefix
The key is the only index
Second key: write each pass under both layouts
flights/7/2026-10-27/42.pdf
passengers/42/2026-10-27/7.pdf
Index: one object, one record per pass in a database
DynamoDB item
PK PASSENGER#42
SK 2026-10-27#FLIGHT#7
key flights/7/2026-10-27/42.pdf

Multipart upload: start, send numbered parts, complete
Also from independence
Cost: parts of an unfinished upload are billed until it is aborted

Presigned URL: a request signed in advance, locally, with the application’s credentials
The signature binds
Upload and download

Event notification: S3 publishes an event when an object is created, overwritten, copied, deleted, or restored
scans/, .jpgDelivery

Work the passenger does not need before the reply
Run inside the request
Thread on the instance: the handler starts the work in a thread and replies
Job table: the handler inserts a row and replies
A worker claims one job
running job with an old claimed_at belonged to a worker that died, and is claimed againstate = 'done' and stores the resultProperties the work needs: kept until finished, taken by one worker, returned if that worker dies, processed by as many workers as are running

Message queue: a service that stores messages from producers until consumers finish them
The job table’s properties, without the table
Amazon Simple Queue Service (SQS): message queues that applications call over HTTPS
AWS runs
Billing: about $0.40 per million requests, nothing for an idle queue
The application sets
Already in use: S3 sends each passport-scan event to an SQS queue, and the passport-check workers receive from it

Message: up to 1 MiB of text, kept for 4 days by default and up to 14
Three calls

Visibility timeout: how long a received message stays hidden, 30 s by default
Shorter than the work

At-least-once delivery: every message is delivered, some more than once
Idempotent consumer: the second delivery has no further effect

Poison message: one that fails on every attempt, such as a scan that is not an image
Redrive policy: a receive count after which SQS moves the message to a second queue

Backlog: grows at arrivals minus the processing rate, drains at the processing rate minus arrivals
Competing consumers: workers on one queue take different messages
Standard queue
Booking 9001, two messages
1 seat changed to 14C
2 seat changed to 21A
FIFO queue
MessageGroupId="booking-9001"Deduplication: a second send with the same deduplication ID within 5 minutes is dropped

Short poll: a receive returns at once, empty if nothing is visible, and every request is billed
Long poll: a receive waits up to 20 s for a message
The worker loop: receive, process, delete, repeat
Functions: code that runs only when a message arrives, with the platform doing the polling

One fact, several services: “passenger 42 checked in” matters to the gate list, the notification service, and baggage
A queue per service

Publish-subscribe
Compared with a queue
Amazon Simple Notification Service (SNS): topics that applications publish to over HTTPS
AWS runs
Billing: about $0.50 per million publishes, plus deliveries to HTTPS, email, and SMS

Topic to queues: each subscriber’s subscription is its own SQS queue
What each queue adds
Filter policy: a condition on the event body, set on one subscription with FilterPolicyScope: MessageBody
Without a filter
Routing by rules: EventBridge applies filters like these across events from many sources, AWS services included

A topic keeps nothing once delivered
When a delivery to a subscriber fails
Uses that need past events

Log: events appended in order and kept for a set period
Compared with a queue and a topic

Amazon Kinesis Data Streams: a managed log, split into shards

A server sized for the peak
Also the application’s

Function service: runs a handler once per event, on environments it starts and stops
One way to run the same patterns
AWS Lambda: the function service that receives events and runs handlers for them
AWS runs
Billing: $0.20 per million invocations, plus run time times memory, about $0.0000167 per GB-second
The application sets
From S3: one record per object changed
From SQS: a batch of messages
From an HTTP request: through a gateway or function URL
The handler’s two arguments
event: the source’s document, as a Python dictcontext: the request ID and the time left before the timeoutprint output and errors go to CloudWatch Logs, tagged with the request ID
Package: the handler and its libraries
Attached permissions
GetObject a missing role permission
The 250 MB limit: zip and layers together, unpacked
Beyond it
/tmp outside the handler
Cold start: the first event in a new environment waits for it to be set up
When it happens

Shorter
Avoided, for a price
Kept between events in one environment
/tmp (512 MB to 10 GB)Not kept, not shared
Configuration outside the code
A deploy
Versions and aliases
live names one version, and the triggers point at the aliaslive from 8 back to 7 rolls back without a new deploy
One setting: memory, from 128 MB to 10,240 MB
Cost per run: memory times run time

At the timeout
finally, no cleanup
Synchronous: the caller waits for the run to finish
Invoke callFailure is the caller’s

Asynchronous: the source hands over the event and continues
Invoke with InvocationType="Event"Lambda’s retries
Event source mapping: Lambda’s poller for a queue
Partial batch failure: report the messages that failed
ReportBatchItemFailures set on the mapping, the rest are deleted, and the failed ones return and count toward the dead-letter limit
Polled from a stream: one batch per shard at a time, in order
Limits on the wait

Concurrency: environments running at once
Over a limit: throttling

Default: an isolated VPC that Lambda owns, not connected to the account’s VPCs
Attached: an interface in a private subnet

Connections follow environments
Bounds

Cost
Limits that decide it before cost

Invoking a function: an AWS API call, signed with credentials the function’s resource policy allows
Three such endpoints

Gateway: a server in front of the backends that receives every request first
Backends
AWS runs
Billing: about $1.00 per million requests for HTTP APIs
The application sets
api.airline.exampleSimpler: a function URL gives one function its own HTTPS address, with no routes and no authorizer beyond IAM
Routes
POST /checkins check-in function
GET /airports/{code}/flights board function
GET /passengers/{id}/trips trips function
{code} captures one path segment and passes it in the event404 from the gateway, no function runsThe event the function receives
The reply the function returns
routeKey
JWT authorizer: the gateway verifies a signed token on every request
401, before any function runsWhat the function receives
requestContext.authorizer.jwt.claims
Throttling: a rate limit per route, per client, and per account
429 Too Many Requests from the gatewayWhat it protects

The gateway’s limit: 30 s at most for the whole request
Accepted, then continued
202 with a job address/jobs/318, a short request, until the result is there
Round-trip floor: distance over the speed of light in fiber, there and back
A page is many requests

Content delivery network: caches in many cities, in front of one origin
Who benefits
AWS runs
Billing: per GB sent to clients and per request, cheaper per GB than sending from the origin directly
The application sets
www.airline.example/api/*
Static site: files the browser runs as they are, with no server code per request
Private bucket
/api/* on the same domain goes to API Gateway
Lifetime: set by the origin’s Cache-Control: max-age, or by the distribution’s default
The trade

Content in the name: the build names each file by a hash of its bytes
Cache-Control: max-age=31536000 on hashed files, max-age=60 on index.htmlAfter a deploy
index.html is refreshed within a minute and names the new script
Cached at the edge
GET /api/airports/LAX/flights: the same reply for every client, 30 s lifetimePassed through to the origin
POST /api/checkins: a change, never cachedGET /api/passengers/42/trips: one passenger’s data, Cache-Control: privateThe document check in one program
Provided by the language and the database
None of it written by the application: it comes with running every step in one process against one database

Each step in its own service
What the application now places

Order as dependencies: which step needs which other step’s result
Join: a step that waits for several others
One record per document check, created when the check starts
check 5120
status waiting
passport pass
watchlist (missing)
visa pass
deadline 14:20:00
A check finishing

Write, then look: two separate requests for each check
The same shape as a double booking
Claiming the finish: change waiting to deciding, only if all three results are present and no one has claimed it
try:
table.update_item(
Key={"check": "5120"},
UpdateExpression="SET #s = :deciding",
ConditionExpression=(
"#s = :waiting AND "
"attribute_exists(passport) AND "
"attribute_exists(watchlist) AND "
"attribute_exists(visa)"),
ExpressionAttributeNames={"#s": "status"},
ExpressionAttributeValues={
":waiting": "waiting",
":deciding": "deciding"})
act_on(read_results("5120"))
except ConditionalCheckFailedException:
pass # claimed already, or a result missingOne write, one winner
Every check tries

A counter: each step adds one
A field per step: each step sets its own

A step that never reports
A deadline, written when the check starts
waiting to timed_out, then refer to an agentA step that acts before the check finishes
Compensating action: a later step that undoes an earlier one’s effect
confirmed, notify the passengerSaga: the standard name for a sequence of steps, each with its compensating action

Choreography: services react to events, and the job record holds the state
Orchestration: one workflow calls each step
The document check as a state machine (abridged)
{"StartAt": "Checks",
"States": {
"Checks": {
"Type": "Parallel",
"Branches": [
{"StartAt": "Passport",
"States": {"Passport": {
"Type": "Task",
"Resource": "...passport-fn",
"TimeoutSeconds": 600,
"Retry": [{"ErrorEquals":
["States.ALL"],
"MaxAttempts": 3}],
"End": true}}},
"... watch list, visa ..."],
"Catch": [{"ErrorEquals":
["States.ALL"], "Next": "Refer"}],
"Next": "Decide"},
"Decide": {"Type": "Task", "End": true},
"Refer": {"Type": "Task", "End": true}}}The same four, in one definition
Parallel for the three checks, Next for what followsRetry and TimeoutSeconds per step, Catch for the path that compensates or refersWhat Step Functions runs: each run’s steps, and a history of every step, billed per state transition
In a job record, with choreography
In an orchestrator
Either way