Back to All Concepts
CloudServerlessAWSArchitectureIntermediate

Serverless Architecture (FaaS)

Functions as a Service (AWS Lambda). The Event-Driven paradigm shift. Benefits (Scaling to Zero) vs Drawbacks (Cold Starts, Vendor Lock-in).

Last updated: By the ScaleWiki Editorial Team

No Servers? No, Just Other People's Servers.

Serverless: You write code (Function). Cloud Provider manages infrastructure (OS, patching, scaling).

Key Traits:

  1. Event-Driven: Code sleeps until triggered (HTTP, S3 upload, Queue message).
  2. Stateless: Functions are ephemeral. No local disk persistence.
  3. Scale to Zero: If no traffic, you pay $0.

Architecture Patterns

1. Web API (API Gateway + Lambda)

Replaces EC2 + Nginx.

2. Async Processing (S3 + Lambda)

Image resizing pipeline.

  1. User uploads photo.jpg to S3 Bucket raw-images.
  2. S3 sends event ObjectCreated to Lambda.
  3. Lambda resizes image and saves to processed-images.

3. Fan-Out (SNS + multiple Lambdas)

  1. User registers.
  2. Publish "UserCreated" to SNS Topic.
  3. Lambda A (Email Service): Sends Welcome Email.
  4. Lambda B (Analytics): Updates Dashboard.

The Cold Start Problem ❄️

The biggest drawback.

  1. Request arrives: AWS finds no running container.
  2. Download Code: Pulls your zip file (50MB) from S3.
  3. Start Container: Spins up Firecracker MicroVM.
  4. Init Runtime: Starts Python/Node/Java process.
  5. Execute Handler: Runs your code.

Total Latency: 200ms (Node.js) to 10s (Java Spring Boot).

Mitigation:

  • Keep Warming: Ping function every 5 mins.
  • Provisioned Concurrency: Pay to keep NN instances warm.
  • Micro-Frameworks: Don't use heavy frameworks (Spring/Django). Use lightweight ones (Flask/Express/Go).

Limitations

FeatureServerless (Lambda)Containers (Fargate/K8s)Virtual Machines (EC2)
Max Runtime15 minutes (Hard limit)UnlimitedUnlimited
Disk Space512MB - 10GB (Ephemeral)Persistent VolumesInfinite (EBS)
Connection LimitsMassive concurrency kills DBs (Connection Pooling needed)Controlled scalingControlled scaling
CostExpensive at high sustained loadCheaper at scaleCheapest (Reserved Instances)

Code Example: AWS Lambda (Python)

python
import json
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')

def lambda_handler(event, context):
    """
    Triggered by API Gateway.
    event: { "body": "{\"name\": \"Alice\"}" }
    """
    print(f"Received event: {event}")
    
    try:
        # Parse Input
        body = json.loads(event.get('body', '{}'))
        name = body.get('name')
        
        if not name:
            return {"statusCode": 400, "body": "Missing name"}

        # Business Logic
        user_id = save_user(name)
        
        return {
            "statusCode": 200,
            "body": json.dumps({"message": "Success", "id": user_id})
        }
        
    except Exception as e:
        print(f"Error: {e}")
        return {"statusCode": 500, "body": "Internal Error"}

def save_user(name):
    item = {"pk": name, "status": "active"}
    table.put_item(Item=item)
    return name
Click to expand code...

The Economics: When Does Serverless Actually Save Money?

The billing model is the real architectural decision. Lambda charges per request plus GB-seconds of execution; a VM charges for wall-clock existence. Run the numbers on a 512MB function taking 100ms per request:

1 million requests/month:
  Lambda: ~$1.05  (compute + requests)
  Smallest useful VM: ~$15-30/month, mostly idle

500 million requests/month (steady ~190 req/s):
  Lambda: ~$500+
  Two modest VMs behind a load balancer: ~$60-120

The crossover is dramatic. The rule that falls out:

  • Spiky, low-average traffic (webhooks, cron jobs, internal tools, early-stage products): serverless wins by an order of magnitude, and scaling to zero means your staging environment is nearly free.
  • Sustained high throughput: containers or VMs win, often by 5–10x. At constant load you are paying Lambda's premium for elasticity you never use.
  • The hybrid reality: mature teams run the steady base load on containers and use functions for the bursty edges (event processing, glue code, infrequent jobs) — matching each workload to the billing model it exploits best.

Watch for the hidden line items: API Gateway per-request pricing can exceed Lambda's own cost, chatty functions pay for time spent waiting on downstream calls, and cross-AZ data transfer between functions and databases quietly accumulates.

The Database Connection Problem

The sharpest operational edge in serverless is impedance mismatch with relational databases. Every concurrent Lambda instance opens its own database connection — and Lambda will happily scale to 1,000 concurrent instances during a spike. PostgreSQL with max_connections = 100 collapses immediately, not from query load but from connection exhaustion.

Solutions, in rough order of adoption:

  1. Connection proxies (RDS Proxy, PgBouncer): functions connect to the proxy, which multiplexes thousands of function connections onto a small pool of real ones.
  2. HTTP-native databases (DynamoDB, Aurora Data API, serverless Postgres providers): no persistent connections at all — every query is a stateless HTTP call, which matches the function model perfectly.
  3. Concurrency caps: set a maximum concurrency on database-touching functions, converting a database outage risk into managed queueing upstream.

This is why serverless architectures gravitate to DynamoDB in practice — not because NoSQL is inherently better, but because its access model matches ephemeral compute. See SQL vs NoSQL for the broader trade-offs.

Orchestration: Beyond Single Functions

Real workflows are rarely one function. "Process an order" means: validate → charge card → reserve inventory → send confirmation — with retries, timeouts, and compensation when a middle step fails. Two patterns dominate:

  • Choreography: functions communicate through events (SNS/EventBridge/SQS). Loosely coupled and scales organically, but the workflow logic exists nowhere explicitly — debugging "why did order 981 stall?" means archaeology across five functions' logs.
  • Orchestration (Step Functions, Durable Functions): a state machine explicitly defines the flow, handles retries with backoff, and keeps an inspectable execution history. Costs more per transition, but failed multi-step workflows become visible instead of mysterious.

A useful heuristic: choreography between domains (order service tells the world "order placed"), orchestration within a domain (the payment workflow's five steps run under one state machine). This mirrors the same tension found in Event Sourcing & CQRS.

Interview Tips 💡

  • "When NOT to use Serverless?" — Long-running tasks (>15m), WebSocket servers (need stateful connections), Heavy GPU tasks (Training), High-frequency trading (latency variance).
  • "Idempotency" — Lambda guarantees "At Least Once" delivery. Your function might run twice for the same event. Make it idempotent! (Check DB before writing).
  • "Vendor Lock-in" — Moving Lambda logic to Google Cloud Functions requires rewriting infrastructure code (Terraform helps, but logic is tied to SDKs).
  • "Cost crossover" — Show you know serverless is cheap at low/spiky volume and expensive at sustained scale; name the hybrid pattern (containers for base load, functions for bursts).
  • "Connection pooling" — Bringing up RDS Proxy or an HTTP-native database unprompted signals real production experience.

Related Concepts

About ScaleWiki

ScaleWiki is an interactive educational platform dedicated to demystifying distributed systems, software architecture, and system design. Our mission is to provide high-quality, technically accurate resources for software engineers preparing for interviews or solving complex scaling challenges in production.

Read more about our Editorial Guidelines & Authorship.

Educational Disclaimer: The architectural patterns and system designs discussed in this article are based on common industry practices, technical whitepapers, and public engineering blogs. Actual implementations in enterprise environments may vary significantly based on specific product requirements, legacy constraints, and evolving technologies.

Related Articles