DynamoDB Streams & EventBridge — Event-Driven Serverless

Why Event-Driven Serverless Matters

Event-driven architecture is the heart of serverless computing. Instead of polling or synchronous calls, services react to events as they happen. DynamoDB Streams captures every change to your database, and EventBridge routes events between services. Together they enable powerful real-time data pipelines.

Why this matters for your career:

  • Event-driven architecture is essential for modern cloud-native applications
  • DynamoDB Streams enables real-time data replication and processing
  • EventBridge is AWS's serverless event bus — connects all AWS services
  • Understanding event-driven patterns is key for AWS certification exams

DynamoDB Streams

DynamoDB Streams captures a time-ordered sequence of item-level changes in a DynamoDB table. Each stream record represents a single data modification.

Stream Record Structure

{
  "eventID": "1",
  "eventName": "INSERT",  // INSERT | MODIFY | REMOVE
  "eventVersion": "1.0",
  "eventSource": "aws:dynamodb",
  "awsRegion": "us-east-1",
  "dynamodb": {
    "Keys": {
      "id": {"S": "user_123"}
    },
    "NewImage": {
      "id": {"S": "user_123"},
      "name": {"S": "Alice"},
      "email": {"S": "alice@example.com"},
      "createdAt": {"S": "2025-01-15T10:30:00Z"}
    },
    "OldImage": null,
    "SequenceNumber": "111",
    "SizeBytes": 128,
    "StreamViewType": "NEW_AND_OLD_IMAGES"
  },
  "eventSourceARN": "arn:aws:dynamodb:us-east-1:123456789012:table/Users/stream/2025-01-01"
}

Stream View Types

| Type | Description | Use Case | |------|-------------|----------| | KEYS_ONLY | Only the key attributes of the modified item | Track which items changed | | NEW_IMAGE | The entire item after modification | Replicate data to another system | | OLD_IMAGE | The entire item before modification | Audit trail, undo operations | | NEW_AND_OLD_IMAGES | Both before and after images | Full change data capture |

Lambda + DynamoDB Streams Example

import json
import boto3

def lambda_handler(event, context):
    """Process DynamoDB Stream events."""
    for record in event['Records']:
        event_name = record['eventName']  # INSERT, MODIFY, REMOVE

        if event_name == 'INSERT':
            new_item = record['dynamodb']['NewImage']
            user_id = new_item['id']['S']
            email = new_item['email']['S']
            print(f"New user created: {user_id} ({email})")

            # Trigger welcome email via SES
            send_welcome_email(email)

        elif event_name == 'MODIFY':
            new_image = record['dynamodb']['NewImage']
            old_image = record['dynamodb'].get('OldImage', {})
            print(f"User updated: {new_image['id']['S']}")

            # Check for specific field changes
            if new_image.get('email') != old_image.get('email'):
                print("Email changed — send verification")

        elif event_name == 'REMOVE':
            old_item = record['dynamodb']['OldImage']
            print(f"User deleted: {old_item['id']['S']}")

            # Clean up related resources
            cleanup_user_data(old_item['id']['S'])

    return {'statusCode': 200}


def send_welcome_email(email):
    ses = boto3.client('ses')
    ses.send_email(
        Source='welcome@example.com',
        Destination={'ToAddresses': [email]},
        Message={
            'Subject': {'Data': 'Welcome to our platform!'},
            'Body': {'Text': {'Data': 'Thank you for signing up...'}}
        }
    )


def cleanup_user_data(user_id):
    # Delete related records in other tables
    dynamodb = boto3.resource('dynamodb')
    orders_table = dynamodb.Table('Orders')
    response = orders_table.query(
        IndexName='UserIdIndex',
        KeyConditionExpression=boto3.dynamodb.conditions.Key('userId').eq(user_id)
    )
    with orders_table.batch_writer() as batch:
        for item in response['Items']:
            batch.delete_item(Key={'id': item['id']})

Amazon EventBridge

EventBridge is a serverless event bus that connects application data from your own apps, AWS services, and third-party SaaS applications.

EventBridge vs. SNS

| Feature | EventBridge | SNS | |---------|-------------|-----| | Schema | Structured event with detail-type | Generic message | | Filtering | Content-based filtering (rules) | Topic-based only | | Targets | Multiple targets per rule | Subscribers to topic | | Third-party integration | Built-in (Zendesk, Shopify, etc.) | Custom integration needed | | Schema registry | ✅ Yes | ❌ No | | Replay events | ✅ Yes | ❌ No | | Archive events | ✅ Yes | ❌ No |

EventBridge Rules Example

{
  "source": ["myapp.users"],
  "detail-type": ["UserCreated", "UserUpdated"],
  "detail": {
    "plan": ["premium", "enterprise"]
  }
}

This rule matches events where:

  • source = "myapp.users"
  • detail-type is "UserCreated" or "UserUpdated"
  • The user's plan is "premium" or "enterprise"

Lambda + EventBridge Example

import json
import boto3

def create_user(event, context):
    """Create a user and emit an event."""
    body = json.loads(event['body'])

    # Save to DynamoDB
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Users')
    table.put_item(Item={
        'id': body['id'],
        'name': body['name'],
        'email': body['email'],
        'plan': body.get('plan', 'free')
    })

    # Emit EventBridge event
    eventbridge = boto3.client('events')
    eventbridge.put_events(Entries=[{
        'Source': 'myapp.users',
        'DetailType': 'UserCreated',
        'Detail': json.dumps({
            'userId': body['id'],
            'email': body['email'],
            'plan': body.get('plan', 'free')
        }),
        'EventBusName': 'default'
    }))

    return {
        'statusCode': 201,
        'body': json.dumps({'message': 'User created', 'id': body['id']})
    }

Scheduled Events (Cron)

{
  "schedule": "rate(24 hours)",
  "targets": [{
    "arn": "arn:aws:lambda:us-east-1:123456789012:function:cleanup-expired-sessions",
    "input": "{\"type\": \"cleanup\"}"
  }]
}

Or use cron syntax:

schedule: "cron(0 2 * * ? *)"  # Run at 2 AM every day

Common Event-Driven Patterns

| Pattern | Services | Use Case | |---------|----------|----------| | Change Data Capture (CDC) | DynamoDB Streams → Lambda → Elasticsearch | Real-time search indexing | | Fan-out | EventBridge → Multiple Lambdas + SQS + SNS | Notify multiple downstream systems | | Scheduled tasks | EventBridge (cron) → Lambda | Daily reports, cleanup jobs | | Choreography | SQS → Lambda → DynamoDB → SQS → Lambda | Distributed sagas, workflows | | Log aggregation | CloudWatch → Lambda → Elasticsearch | Centralized logging | | Throttle buffer | API Gateway → SQS → Lambda | Handle traffic spikes gracefully | | Dead letter queue | Lambda → DLQ (SQS) | Capture failed invocations |

Best Practices

| Practice | Reason | |----------|--------| | Enable streams on DynamoDB tables | Required for CDC and event-driven processing | | Use NEW_AND_OLD_IMAGES | Full audit trail of all changes | | Filter events in EventBridge rules | Lambda only runs for relevant events | | Set appropriate batch sizes | Optimize Lambda invocation frequency | | Handle duplicate events | Streams guarantee at-least-once delivery | | Use DLQ for failed events | Never lose data from processing failures | | Monitor iterator age | Detect slow stream processing | | Archive important events | EventBridge can replay archived events |

Summary

DynamoDB Streams and EventBridge enable powerful event-driven serverless architectures. DynamoDB Streams captures every data change in real-time. EventBridge routes events between services with content-based filtering and scheduled triggers. Together they form the backbone of modern event-driven applications on AWS.

Key takeaways:

  • DynamoDB Streams captures INSERT, MODIFY, REMOVE events
  • Stream view types: KEYS_ONLY, NEW_IMAGE, OLD_IMAGE, NEW_AND_OLD_IMAGES
  • EventBridge is a serverless event bus with content-based filtering
  • EventBridge supports scheduled events (cron/rate expressions)
  • EventBridge has built-in integration with 200+ AWS services and SaaS apps
  • Use DynamoDB Streams for real-time data replication and CDC
  • Use EventBridge for decoupled, event-driven microservices
  • Always implement idempotent processing for at-least-once delivery

What's Next: Step Functions

The next chapter covers AWS Step Functions — orchestrating multi-step serverless workflows with state machines, error handling, and parallel execution.

Unlock Full Tutorial

This chapter is paid content. Join the project to unlock over 5000 words of deep analysis, including 10+ god-tier Prompts and real Source Code examples!