One Year with Serverless: The Honest Pros and Cons
An honest review after running AWS Lambda-based serverless architecture for a full year.
I Was Sick of SSH-ing into Servers to Dig Through Logs
Applying patches, managing disk space, SSH-ing into a box and running tail -f when something breaks. I wanted out of all of that. That's the entire reason I chose serverless.
I started a side project with AWS Lambda + API Gateway + DynamoDB, and later built a company project with the same stack. It's been a year.
The Cost Is Absurdly Cheap
We had an internal tool running on an EC2 t3.small. About 500 requests per day. Monthly cost: around $15.
After migrating to Lambda, the monthly cost dropped to about $0.25. Twenty-five cents. If there are no requests, the cost is literally zero. For services with unpredictable traffic like side projects, this advantage is the dealbreaker.
No 3 AM Phone Calls
In an entire year, I had zero infrastructure-related outages. There were errors from code bugs, sure, but zero outages caused by a server dying. No OS update worries, and deploying is a single serverless deploy command.
But that's where the good news ends.
Cold Starts Are More Noticeable Than You'd Think
"It can't be that bad, right?" I thought. In practice, it's different. With the Node.js runtime, cold starts average 200-400ms. When the first request comes in during low-traffic hours, the delay is noticeable.
Provisioned Concurrency fixes this, but then you lose the cost advantage. This dilemma was pretty frustrating.
(The joy of a $0.25 monthly bill gets shaken by a single cold start.)
Local Development Is Painful
This is honestly the biggest inconvenience of serverless architecture. The serverless-offline plugin simulates things to some degree, but once you set up DynamoDB Local and an S3 emulator, you start wondering, "is this really the simplicity serverless promised?"
"It works locally but breaks when deployed" happened frequently. Running integration tests against actual AWS was more reliable, but that slows down the feedback loop.
The 15-Minute Wall
Lambda's maximum execution time is 15 minutes. Most API requests are fine, but parsing 100K rows of CSV and inserting into the DB hit the timeout. I had to split it with Step Functions, and suddenly a simple task became a complex workflow.
Debugging with CloudWatch Logs
Is somehow worse than SSH-ing into a server to read logs. Logs are scattered, search is slow, and real-time inspection is difficult. I eventually brought in Datadog, and only then could I debug comfortably. But Datadog costs money too, which diluted the whole cost advantage of serverless.
The most important investment in serverless is logging and monitoring. Skip that, and when something blows up, you won't even know where it happened.
Honest Conclusion
Low or variable traffic services, event-driven processing, rapid prototyping -- I'd strongly recommend serverless for these. For services with steady traffic, tasks needing long execution times, or cases requiring complex state management, a traditional server is better.
After a year, I've learned that serverless isn't magic -- it's a tool. One that shines when used in the right place.