|$ curl https://forge-ai.dev/api/markdown?path=docs/architecture/serverless
$cat docs/serverless-/-faas-architecture.md
updated Today·18-26 min read·published

Serverless / FaaS Architecture

ArchitectureServerlessFaaSIntermediate🎯Free Tools
Introduction

Serverless architecture runs application logic on managed compute that autoscales with demand — commonly Functions-as-a-Service (FaaS) plus managed backends (databases, queues, object storage). You write handlers; the cloud provider handles servers, patching, and elastic scale. You still design architecture: boundaries, state, idempotency, and cost.

"Serverless" does not mean "ops-free." It shifts ops toward observability, cost control, configuration, and distributed design discipline.

When Requirements Fit
RequirementServerless fit
Spiky / unpredictable trafficStrong — scale to zero / out
Pay-per-use cost model desiredStrong for bursty workloads
Small event handlers / APIsStrong
Long CPU-bound jobs (hours)Weak — use containers/batch
Hard ultra-low latency every requestWeak — cold starts risk
Specialized hardware / GPUs always onOften weak / specialized offerings
  • Why choose it: reduce idle cost, accelerate delivery of event-driven glue, let platform teams focus elsewhere.
  • How: design small handlers, push state to managed stores, use queues for async, watch cold start and concurrency limits.
Cold Starts

A cold start happens when a new execution environment initializes — loading runtime, code, and dependencies — before handling a request. Impact varies by language, package size, VPC networking, and provisioned concurrency settings.

MitigationTradeoff
Keep packages smallDiscipline on deps
Provisioned concurrencyPays for warm capacity
Prefer lighter runtimesLanguage constraints
Avoid VPC unless neededNetworking security tradeoffs
Async where latency allowsUX eventual
📝

note

If NFR says p99 < 50ms including auth for all traffic 24/7, validate cold-start behavior early with production-like load — or choose always-on compute for that path.
Cost Model

Cost typically tracks invocations, duration, memory, and downstream managed services. Bursty apps often save vs always-on clusters; high, steady, long-running workloads can cost more on FaaS than on containers.

  • Model cost with expected RPS × duration × memory price + storage/queue costs.
  • Watch chatty designs that multiply invocations.
  • Set budgets and alerts — runaway recursion or retries can surprise.
Limits & Architectural Constraints
  • Max execution duration per invocation.
  • Payload size limits on events/responses.
  • Concurrency quotas and downstream DB connection storms.
  • Local disk ephemeral and limited.
  • Vendor-specific packaging and IAM models — portability costs.

Connection management

Use pooling proxies or serverless-friendly DB offerings; do not open a new DB connection naively per invoke at scale.

Idempotency

At-least-once invocation is common — design handlers safe to retry.

Observability

Structured logs, tracing, cold-start metrics, and DLQs for async paths.

Common Patterns
PatternUse
HTTP API + functionCRUD/BFF endpoints
Queue/stream consumerAsync processing
Scheduled functionCron-style jobs
Fan-out via pub/subEvent-driven integration
Orchestrator (step functions)Multi-step workflows
handler.sketch.mjs
JavaScript
1export async function handler(event) {{
2 const cmd = parse(event);
3 // idempotency key from event id
4 if (await alreadyProcessed(cmd.id)) return {{ ok: true }};
5 await placeOrder(cmd);
6 await markProcessed(cmd.id);
7 return {{ ok: true }};
8}}
Serverless vs Containers vs Modular Monolith
ChooseWhen
FaaSEvent glue, spiky APIs, minimal ops
Containers on orchestratorLong processes, complex networking, steady load
Modular monolith on simple hostEarly product, strong consistency, small team
Common Mistakes
  • Death by a thousand functions without module boundaries.
  • Ignoring cold starts until launch day.
  • Sync fan-out causing cascading latency and cost.
  • Storing critical state only in local /tmp.
  • No cost alerts on retries/DLQ storms.
Serverless Checklist
serverless-checklist.txt
TEXT
1[ ] Workload shape fits (spiky/event/short)
2[ ] Latency NFRs validated vs cold starts
3[ ] Cost model spreadsheet signed off
4[ ] Idempotency & retry policy defined
5[ ] Concurrency vs DB capacity planned
6[ ] Observability + alarms in place
7[ ] Escape hatch to containers documented
Hexagonal Meets Serverless

Keep domain/use cases pure; treat the function entrypoint as a driving adapter. This preserves testability and an escape hatch to containers later without rewriting business rules.

composition.mjs
JavaScript
1import {{ placeOrder }} from "./application/place-order.js";
2import {{ pgOrders }} from "./adapters/pg-orders.js";
3import {{ stripePayments }} from "./adapters/stripe.js";
4
5const uc = placeOrder({{ orders: pgOrders, payments: stripePayments }});
6export const handler = async (event) => uc(parse(event));
SDLC Implications

Serverless thrives with strong CI (packaging, integration tests against emulators/sandboxes), staged deploys, and infrastructure as code. Local fidelity is never perfect — invest in contract tests and ephemeral cloud environments for critical paths.

Portability Reality

FaaS APIs differ across clouds. If portability is a Must NFR, isolate domain logic (hexagonal) and accept rewriting adapters — or prefer containers. If portability is only a Could, optimize for one platform's strengths and document lock-in in an ADR.

Mini Case

A media company moved image thumbnail generation to queue-triggered functions. API latency NFRs stayed on an always-on service; burst work scaled independently; cost dropped 60% vs a fleet of always-on workers. They kept domain code portable and later ran the same workers on containers for a on-prem customer — because hexagonal adapters made the swap possible.

Security Considerations
ConcernPractice
IAM least privilegePer-function roles; no wildcards
SecretsManaged secrets; never env in images/logs
Event injectionValidate envelopes; auth on HTTP triggers
Dependency riskScan packages; pin versions
Data exfilEgress controls where required

Serverless widens the attack surface via many entrypoints. Inventory triggers and apply the same threat modeling you would for microservices.

Go/No-Go Questions
  • Is the critical path tolerant of cold starts — measured, not hoped?
  • Do we have idempotency keys on all mutating handlers?
  • Can the database survive concurrency × connection behavior?
  • Are costs alerted and modeled at 10× traffic?
  • Is there an escape hatch ADR if FaaS limits bind us?

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.