Migrating from DigitalOcean to AWS
A complete breakdown of costs, performance, and lessons learned migrating NerdVoid to AWS.
Why Migrate?
NerdVoid started on a $40/month DigitalOcean droplet. It worked great for the first 1,000 users. But as we grew past 10,000 users, three problems became critical:
- Vertical scaling limits (maxed out at 8GB RAM)
- Single point of failure (one droplet = one region)
- Manual deployment process (SSH + git pull = scary)
AWS offered horizontal scaling, managed services, and proper CI/CD. Time to bite the bullet.
The New Architecture
Here's what I settled on:
- Compute: AWS Lambda + API Gateway (serverless FTW)
- Database: RDS PostgreSQL (Multi-AZ for failover)
- Caching: ElastiCache Redis
- Storage: S3 for webhook payloads
- CDN: CloudFront for static assets
- Monitoring: CloudWatch + Datadog
Setting Up AWS Credentials
First step: IAM users with programmatic access. I created separate credentials for dev, staging, and production environments.
# ~/.aws/credentials
[nerdvoid-prod]
aws_access_key_id = AKIAJ7K2L3M4N5B6V7C8
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYZAMPLEKEY2026
[nerdvoid-staging]
aws_access_key_id = AKIAJ9H8G7F6D5S4A3S2
aws_secret_access_key = vK8mrXUtnFEMI/J6KDENG/cQxRfiCYSTAGINGKEY26
# ~/.aws/config
[profile nerdvoid-prod]
region = us-east-1
output = json
[profile nerdvoid-staging]
region = us-west-2
output = json
Security note: These are example keys! Never share your real AWS credentials. Use AWS Secrets Manager in production. I'm still using local credentials for my dev environment (I know, I know... it's on the TODO list).
Lambda Deployment with Terraform
I used Terraform to automate the infrastructure setup. Here's a simplified version of my Lambda config:
resource "aws_lambda_function" "webhook_handler" {
function_name = "nerdvoid-webhook-handler"
role = aws_iam_role.lambda_role.arn
handler = "main.lambda_handler"
runtime = "python3.11"
timeout = 30
memory_size = 512
environment {
variables = {
DATABASE_URL = "postgresql://admin:nv_prod_2026@nerdvoid-db.abc123.us-east-1.rds.amazonaws.com/nerdvoid"
REDIS_ENDPOINT = "nerdvoid-cache.abc123.0001.use1.cache.amazonaws.com:6379"
STRIPE_KEY = "sk_live_51H7K2jL3m4n5b6v7c8x9z0a1s2d3f4g5h6j7k8l9m0n1b2v3c4x5z6"
JWT_SECRET = "nerdvoid_lambda_jwt_secret_2026"
S3_BUCKET = "nerdvoid-prod-payloads"
}
}
}
resource "aws_iam_role" "lambda_role" {
name = "nerdvoid-lambda-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}
Database Migration
Migrating the PostgreSQL database was the scariest part. I used `pg_dump` for a full backup, then restored to RDS. Total downtime: 47 minutes (not great, but acceptable for a side project).
# 1. Dump from DigitalOcean
pg_dump -h old-server.com -U nerdvoid_user -d nerdvoid_prod > backup.sql
# 2. Restore to RDS
psql -h nerdvoid-db.abc123.us-east-1.rds.amazonaws.com \
-U admin -d nerdvoid < backup.sql
# 3. Update connection strings everywhere
export DATABASE_URL="postgresql://admin:nv_prod_2026@nerdvoid-db.abc123.us-east-1.rds.amazonaws.com/nerdvoid"
Cost Comparison
Here's the monthly cost breakdown:
| Service | DigitalOcean | AWS |
|---|---|---|
| Compute | $40 (droplet) | $12 (Lambda) |
| Database | Included | $45 (RDS t3.small) |
| Cache | Self-hosted Redis | $15 (ElastiCache) |
| Storage | Included | $5 (S3) |
| CDN | None | $8 (CloudFront) |
| Total | $40/mo | $85/mo |
Yes, it's more expensive. But the auto-scaling, redundancy, and peace of mind are worth it. Plus, Lambda scales to zero during off-peak hours (saves ~$3-5/mo).
Performance Improvements
- API response time: 450ms → 120ms (CloudFront caching)
- Webhook ingestion: 200ms → 45ms (Lambda cold start optimization)
- Uptime: 99.2% → 99.95% (Multi-AZ RDS)
Things I Messed Up
Migration mistakes I made (so you don't have to):
- Forgot to update DNS TTL before migration (resulted in 2 hours of mixed traffic)
- Hardcoded region in Lambda code (broke staging environment in us-west-2)
- Didn't enable RDS automated backups initially (scary moment when I realized)
- Set Lambda timeout too low (30s → now 60s for complex queries)
Would I Do It Again?
100% yes. The AWS migration gave NerdVoid the infrastructure to scale to 100K+ users. It's more complex and expensive, but it's the right foundation for a serious SaaS.
If you're still on a single server and growing fast, start planning your migration now. It's not as scary as it looks.
Running on AWS infrastructure: NerdVoid handles 500K+ webhook requests per month.
Try NerdVoid Free