Why profile the job before picking a service
In Level 1 you saw every AWS integration service on one page. That page does not tell you which one to use. Most bad integration choices start with the product: someone likes EventBridge, so every problem gets an event bus. The fix is to describe the job first, the same way every time, and let that description rule services out.
Think of it as a pre-flight checklist. A pilot does not choose a runway by feel. They check weight, wind and runway length, and the numbers make the choice. The standard integration profile is that checklist. It has twelve attributes, and each one should get a number or a plain answer.
The twelve attributes
| # | Attribute | The question to ask |
|---|---|---|
| 1 | Sync or async | Does the caller wait for the answer? |
| 2 | Commands or events | "Do this" sent to one owner, or "this happened" sent to anyone who cares? |
| 3 | Ordering | Must messages be processed in order? Globally, or only per key such as per order? |
| 4 | Delivery and duplicates | Can you lose a message? Can you handle the same one twice? |
| 5 | Size and volume | Largest payload in KB, average and peak messages per second |
| 6 | Latency | Acceptable end-to-end delay at p99 |
| 7 | Fan-out | How many consumers get each message, now and in a year? |
| 8 | Long-running work | Seconds, minutes, days? Does a human step in? |
| 9 | Partners and SaaS | Do outside systems send or receive data? |
| 10 | API consumers and security | Who calls you, and how do they authenticate? |
| 11 | Team skills | What does the team already run well? |
| 12 | Cost model | What do you pay for: requests, messages, state transitions, hours or a broker running all the time? |
The two answers that narrow the list first
Synchronous or asynchronous. In a synchronous call the caller blocks: a mobile app calls POST /orders and waits for a 201. That points you at API management (API Gateway, AppSync), and its timeouts become hard limits. In an asynchronous call the caller hands the work off and moves on. That points you at queues, topics and buses.
Command or event. A command has one intended handler and expects the work to get done: ChargeCard, ShipOrder. An event states a fact about the past and does not care who listens: OrderPlaced. Commands usually go to a queue or a workflow step. Events go to a topic or an event bus so that new consumers can subscribe later without the producer changing.
Naming check: if the message name is an imperative verb (
SendInvoice), it is a command. If it is past tense (InvoiceSent), it is an event. Mixing the two, for example an "event" that only one service may handle, is a common reason designs break when a second team joins.
Worked example: order placement
Keep the profile as a file in the repo next to the code, so you can review it like code:
# integration-profile.yaml (reviewed 2026-10-29)
job: order-placement
sync_or_async:
checkout_api: sync # shopper waits for an order number
downstream: async # payment, stock, email happen afterwards
message_kind:
checkout_api: command # PlaceOrder
downstream: event # OrderPlaced
ordering: per-key # per order_id only; global order not needed
delivery: at-least-once # never lose an order; duplicates OK if consumers are idempotent
size:
avg_kb: 4
max_kb: 40 # big baskets with line items
volume:
avg_per_sec: 15
peak_per_sec: 600 # Black Friday, about 40x average
latency_p99:
checkout_api_ms: 800
downstream_s: 30
fan_out: 4 # payment, inventory, email, analytics; expect 6 to 8 later
long_running: "payment retries up to 24h"
partners_saas: ["Stripe webhooks in", "3PL warehouse API out"]
api_consumers: ["own web/mobile app (Cognito JWT)"]
team_skills: ["Lambda", "Terraform", "no broker admins"]
cost_model: pay-per-use preferred; spiky traffic
Four things in this file already shape the design. The checkout API is sync, so it needs an API front door with an 800 ms target. Fan-out of 4 or more events points to publish-subscribe or a bus, not a single queue. A 24-hour retry window is longer than a short-lived workflow can run. "No broker admins" is a real argument against running a broker.
Check the profile against dated limits
The numbers matter because each service has limits. A few to check against, as of October 2026:
- Payload size: SQS and EventBridge accept up to 1 MB. Both were raised from 256 KB, SQS in August 2025. SNS can now take up to 1 MiB, but only if you set the
MaximumMessageSizetopic attribute. The default is still 256 KiB, and larger publishes are billed in 64 KB chunks. - Synchronous timeouts: API Gateway's default integration timeout is 29 seconds. Regional and private REST APIs can request up to 300 seconds through Service Quotas, sometimes in exchange for a lower throttle quota. HTTP APIs cannot.
- Long-running work: Step Functions Standard workflows run for up to one year with exactly-once execution. Express workflows run for at most five minutes. Asynchronous Express runs are at-least-once.
- Duplicates: SQS standard queues are at-least-once, and the docs tell you to make consumers idempotent.
So the 40 KB basket fits anywhere, and the 24-hour retry rules out Express workflows.
Hard constraints versus preferences
Mark every attribute as one of two kinds. A hard constraint removes a service from the list. A preference only changes its score later. Weighting comes later in the course, so for now just tag each one:
constraints:
hard:
- delivery: at-least-once # losing an order is a business failure
- long_running: 24h # rules out anything capped at minutes
- max_kb: 40 # every option must accept it
preference:
- cost_model: pay-per-use # a broker could still win on other points
- team_skills: Lambda # skills can be learned; it's a cost, not a wall
- fan_out_growth: 6-8 # nice to absorb without code changes
Trade-off: teams often mark too much as hard. "Must be ordered" is often only true per customer or per order, and global ordering costs a lot more throughput. Ask "what breaks, and who complains?" before you call something hard.
A second profile in brief: partner data sync
Nightly, a SaaS CRM pushes about 200,000 contact changes. The work is async. The messages are events (ContactUpdated). Ordering matters per contact. Payloads are about 2 KB. Latency of up to 1 hour is fine. Fan-out is 2. The partner side is the SaaS vendor's API. Here the partner and SaaS attribute and the volume per batch drive the choice, not latency. The profile is the same and the answers are very different.
Key takeaways
- Fill in all twelve attributes with numbers: KB, messages per second, p99 latency and consumer count, not words like "large" or "fast".
- Sync or async, then command or event, is the first cut. Sync brings timeouts. Events bring fan-out.
- Check the numbers against dated limits, such as payload size, the 29-second API timeout and workflow duration, before you like any one service.
- Tag each attribute as a hard constraint (rules a service out) or a preference (scored later).
- Store the profile as a reviewed file and update it when the business changes.