In serverless, the config is the design
A box diagram of API Gateway, Lambda, SQS, and DynamoDB hides your real serverless configuration — the per-service knobs and defaults that decide whether it works.
Here’s a diagram you’d wave through in a review.
A user hits API Gateway. API Gateway calls a Lambda. That Lambda drops a message on an SQS queue. A second Lambda pulls from the queue and writes to DynamoDB. Five boxes, four arrows, a clean left-to-right flow.
Looks done. It isn’t.
It’s a picture of what you meant to build. None of the decisions that decide whether this thing actually holds up are on the diagram — they’re one level down, in the configuration on each box.
The boxes are the easy part
Take that same flow and open each box up.
Start with Lambda, where it gets loud. Memory runs from 128 MB to 10,240 MB, and CPU is allocated in proportion to it — so the memory slider is really your CPU slider too. Timeout runs from 1 second to 15 minutes. Architecture is arm64 or x86_64.
Here’s the contrast that should bother you. A Lambda at 128 MB with a 3-second timeout, and the same code at 1 GB with a 30-second timeout, are the identical box on the diagram. In production they’re two different systems — different latency, a different cost per invocation, a different failure mode when a downstream call gets slow. One trips its timeout and sheds the request; the other holds the line and grinds through. The arrow pointing into each one looks exactly the same.
Every other box hides the same way. API Gateway is a REST or an HTTP API — different feature sets, different per-request prices — with auth and a request quota you either set or leave open. SQS is short-polling or long-polling. The dead-letter queue is a retry count before a message gets set aside instead of retried forever. DynamoDB is on-demand or provisioned, TTL on or off, reads strong or eventual.
Four boxes. Dozens of decisions. Not one of them shows up as a line or a label.
Serverless configuration is the flexibility — and the surface area
That’s the real strength of serverless, and it’s easy to miss. The flexibility lives in configuration you set, not code you write. You don’t fork the Lambda runtime to make it faster; you move a memory slider. You don’t build a retry system; you set a redrive policy. Learn each knob once and you reuse it on every function, every queue, and every table you ever deploy.
But flexibility and surface area are the same thing measured from two sides. Every knob is one more decision you own. And one more you can quietly get wrong — a timeout that’s too short, a batch size that’s too big, a polling mode that’s burning money on empty receives.
The boxes don’t multiply when your system gets more complex. The config does.
Every default is a decision you didn’t know you made
Here’s the part that took me too long to internalize.
Every value you don’t set is still set. By the default. And the default isn’t “no decision” — it’s a decision AWS made for your system, one you inherited without reading.
SQS defaults to short polling. If you never touched ReceiveMessageWaitTimeSeconds, it’s 0, and your consumers are doing short-poll receives — more empty responses, more requests, more cost — because you didn’t choose long polling, not because short polling was right for your queue.
A Lambda you deployed without setting a timeout has a 3-second timeout. You didn’t decide 3 seconds was enough for that function. AWS decided it, once, for every function anyone ever creates.
Create a DynamoDB table through the API or CloudFormation without naming a billing mode, and you get provisioned throughput at 5 read and 5 write capacity units — even though AWS’s own guidance now points most workloads at on-demand. The default predates the recommendation, and it’s still the default.
None of these are bugs. They’re just decisions with nobody’s name on them. And the diagram is no help here either — a default knob and a deliberately-set knob look exactly the same on the canvas, which is to say they’re both invisible.
Where a diagram that understands the services comes in
So a normal architecture diagram has a blind spot precisely where serverless systems live or die. It shows the boxes and hides the knobs.
That’s the gap Design Beaver is built around. It’s a diagramming canvas that actually knows what the AWS services on it are — so a config decision and its consequence can surface on the diagram, while you’re drawing, instead of living invisibly in the console or buried three files deep in your IaC. It validates as you draw.
Here’s the honest version: it doesn’t read your account, and it doesn’t catch everything — it isn’t trying to. One thing it does know is the public example you’ll see all over these docs: draw a Lambda writing to an SQS queue with no dead-letter queue attached, and it’ll flag that failed messages have nowhere to land. That’s the gist — a decision made visible on the canvas, so you make it on purpose instead of by omission. It’s not a linter for your whole system, and I’d rather say that plainly than oversell it.
The thing I keep coming back to
A diagram of an architecture should be able to be wrong.
That sounds backwards, but it’s the whole point. If a diagram is only boxes and arrows, it can’t be wrong — it’s a drawing, and a drawing agrees with whatever you deploy. The moment a diagram carries enough about the services to be checkable, it can disagree with you. It can be wrong on purpose, so a tool can tell you it’s wrong.
I’m still figuring out how far that goes. Not every knob belongs on a canvas, and a picture that tried to show all of them would be worse than the plain box diagram. But the boxes were never the hard part. The config was. That’s the part worth being able to see.
Defaults worth setting on purpose
A few serverless defaults you inherit unless you say otherwise:
- Lambda timeout: 3 seconds. Fine for a router, short for anything that calls a database or an external API.
- Lambda memory: 128 MB. The floor — and since CPU scales with it, sometimes the slowest choice, not the cheapest, once you count the extra duration.
- SQS polling: short.
ReceiveMessageWaitTimeSecondsof 0. Long polling (up to 20 seconds) usually means fewer empty receives and a smaller bill. - SQS → Lambda batch: 10 messages, 0-second window. Raise the batch size above 10 and you’re required to set a batching window of at least 1 second.
- DynamoDB (via API/IaC): provisioned, 5 RCU / 5 WCU. On-demand is the safer default for anything with unproven or spiky traffic.
You can draw one of these architectures in Design Beaver right now — free, in the browser, with a Google or GitHub sign-in that keeps your diagrams. And if this way of thinking about defaults is your thing, I write more of it over at milinpaul.com.
Try Design Beaver on your own architecture
It’s live in beta — free, in your browser. Sign in with Google or GitHub to save your work.
Sign up for free! →Prefer email? Get new features in your inbox: