Serverless and Managed Services

intermediate serverless lambda api-gateway event-driven

Serverless doesn’t mean “no servers.” The servers are still there — we just don’t think about them. We write a function, upload it, and the cloud runs it whenever something triggers it. No provisioning, no patching, no scaling decisions. We pay per invocation, not per hour.

How It Works

We write a function that handles one event — an HTTP request, a file upload, a message from a queue. The cloud provider:

  1. Receives the event
  2. Spins up our function in a container (or reuses a warm one)
  3. Runs our code
  4. Shuts down when done
  5. Charges us for the milliseconds of execution
# AWS Lambda example — a simple Node.js function
# handler.js
exports.handler = async (event) => {
  const name = event.queryStringParameters?.name || "World";
  return {
    statusCode: 200,
    body: JSON.stringify({ message: `Hello, ${name}!` }),
  };
};

That’s it. No Express server, no port configuration, no process manager. Just a function.

The Event-Driven Pattern

Serverless shines when events drive the workflow. Instead of a monolith doing everything, we chain small functions together.

Event-Driven Architecture
Example: Image Processing Pipeline
  User uploads image → S3 Bucket
    ↓ triggers
  Lambda: resize → saves thumbnail to S3
    ↓ triggers
  Lambda: metadata → writes record to DynamoDB
    ↓ triggers
  SNS notification → emails the user "upload complete"

No server running 24/7 waiting for uploads. Each piece runs only when triggered, scales independently, and costs nothing when idle.

Key Serverless Services

Compute:

  • AWS Lambda / Google Cloud Functions / Azure Functions — run code on events
  • Cloudflare Workers — runs at the edge (CDN nodes), ultra-low latency

API Layer:

  • API Gateway (AWS, GCP) — routes HTTP requests to Lambda functions, handles auth, rate limiting, CORS

Messaging:

  • SQS (Simple Queue Service) — message queue, guarantees delivery, decouples services
  • SNS (Simple Notification Service) — pub/sub, fan out one event to many subscribers
  • EventBridge — event bus for routing events between AWS services
# AWS SAM template — Lambda behind API Gateway
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  HelloFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: handler.handler
      Runtime: nodejs20.x
      Timeout: 10
      MemorySize: 128
      Events:
        Api:
          Type: Api
          Properties:
            Path: /hello
            Method: get

When Serverless Makes Sense

  • Sporadic workloads — a function that runs 100 times a day costs almost nothing
  • Event processing — file uploads, webhooks, queue consumers
  • APIs with variable traffic — scales to zero when nobody’s calling
  • Cron jobs — scheduled Lambda beats keeping a server running 24/7 for a 5-minute task

When It Doesn’t

Cold starts — if a function hasn’t been invoked recently, the first invocation takes 100ms-2s to spin up. For latency-sensitive APIs, this can hurt.

Execution limits — Lambda maxes out at 15 minutes. Long-running tasks (video processing, ML training) need a different approach.

Vendor lock-in — Lambda code is easy to port, but once we’re deep into SQS + SNS + Step Functions + DynamoDB, switching providers is a massive effort.

Complex local development — replicating the Lambda + API Gateway + DynamoDB stack locally requires tools like SAM or Serverless Framework. It’s doable but more friction than running a local Express server.

High-throughput, steady traffic — if we’re running 10 million invocations per hour consistently, a container on ECS or a Kubernetes pod would be cheaper.

Cost Model

# Lambda pricing (approximate):
# $0.20 per 1 million requests
# $0.0000166667 per GB-second of compute
#
# Example: 1 million requests, each using 128MB for 200ms
# Compute: 1M × 0.128GB × 0.2s × $0.0000166667 = $0.43
# Requests: 1M × $0.0000002 = $0.20
# Total: ~$0.63 for 1 million invocations

In simple language, serverless is about writing code and letting the cloud handle everything else. It’s perfect for bursty, event-driven workloads. But for always-on, high-throughput services, running our own containers is usually cheaper and gives us more control.