Ask HN: Have you shipped anything serious with a “serverless” architecture?
I've been watching the rise and maturing of AWS lambda and similar offerings with excitement. I've also shipped several microservices in both node and Java that are entirely serverless, making use of API gateway, lambda, dynamo db, sqs, kinesis, and others.
For the simple case, I found the experience to be great. Deployment was simple and made use of shell scripts and the excellent AWS CLI.
I've been hesitant to build anything serious with it tho. The primary concern has been visibility into the app. The app's operation can be quite opaque when deployed that way. Further exacerbating the issue, we've a few times lost Cloudwatch logs and other reporting due to both configuration issues and improper error handling, but these are things that would have been much easier to identify and diagnose on a real server.
Have you shipped anything serious with a serverless architecture? Has scaling and cost been favorable? Did you run into any challenges? Would you do it again?
206 comments
[ 3.3 ms ] story [ 250 ms ] threadIt has been pretty much set-and-forget. Last anyone had to even look at it was almost 3 years ago, and afaik it's still working (our ad sales team would be complaining loudly if it weren't).
For something peripheral like that, it's nice not to have to run servers for it or devote any energy to keeping it running.
In terms of both server costs and upkeep costs, the economics have been highly favorable.
I'm not sure I'd use it yet for something mission-critical or that shipped changes frequently. My recollection is that when we did have to adjust it, debugging was a bear. Tho tooling for that may have improved in the last 30 months.
In this way, serverless can actually be WAY better than traditional methods for dealing with frequent changes. You can have many valid endpoints, but only one “production” endpoint that changes based on business rules (or even split for A/B testing)
I eventually got upset enough that I made a tool to stream the cloudwatch logs to the terminal and colorize, indent + nicely format json output:
https://github.com/TylerBrock/saw
Have you tried anything like iopipe for helping debug lambdas?
[0]: https://github.com/iopipe/iopipe-js/ [1]: https://github.com/iopipe/iopipe-python/ [2]: https://github.com/iopipe/iopipe-java/ [3]: https://github.com/iopipe/iopipe-go/
Disclosure: Work on the Python and Go agents.
Cloudwatch feels like it was not made for humans. Searching and filtering for specific log events is a huge pain.
I think one of the best things one could do is to pipe your Cloudwatch logs to an ElasticSearch cluster.
Saw installs as a single binary, is performant, and has better looking output than all of them.
I'll soon see if the back of the envelop calculations were correct. :)
I think serverless is the future... but not today.. in 5-10 years. That sounds like a long way off, but it's not.. it'll pass in no time. And maybe they'll improve it enough by then to make it viable.
I wouldn't build anything serious with it, unless you're ok rewriting it a few years from now.
> some serious shortcoming and a lot more work needs to be put into these serverless platforms
Not actionable at all
> The approach they're taking I don't think will last
No reason given
> It really needs a redesign/restructure
Nothing here too
> And maybe they'll improve it enough by then to make it viable
What makes it (un)viable?
As a company that has built our most recent site completely on serverless, we've become familiar with some of the issues. Though I definitely would not consider it a no-go.
If you intend to compete with them - you might wanna reconsider.
[0]: https://iopipe.com
Disclosure: Work on the Python and Go agents.
I’m sure AWS would recommend you use Kinesis Firehose or something to put in ElasticSearch and use Kibana or something. But I would be great to have an equally scalable log parser/searcher.
All of https://ayvri.com is built using serverless.
(we'll be migrating from doarama to ayvri in the coming weeks)
For our processing we handled 200k uploads in one hour on ayvri when we where building scenes for the Wings for Life event (the World's largest organized run).
When just relying on serverless triggering an event from s3, the cost was high due to the volume of scaling, time in spinning up new services, etc. etc. We built a queuing system which manages load and then spins-up new instances based on the load in the queue. This resulted in a much faster response, and SIGNIFICANT reduction in cost.
For the ayvri website, some pages are slow due to the lambda's not being warm, and I'm surprised users haven't complained. The important stuff is kept warm, and we're working on scaling that out for more responsiveness across the site.
As far as visibility into the app, I'm not going to pretend this is a solved problem. At the moment, we have most of the visibility we need via cloudwatch, and we have built some of our own analytics.
We had one instance where there was an issue between db connectivity which we were not able to resolve. We have put it down to a short networking issue between services. It lasted for 5 minutes one Sunday morning and then went away. So we had enough visibility into the service not being available, but failed in deeper understanding of where the problem was.
If you have further questions I can help with, feel free to reach out.
I will say, that I bought into serverless and went whole hog. I probably don't recommend that. We jump through some hoops we probably wouldn't need to if we had run our website via an ec2 instance and cloud-formation managing the scaling.
However, we have a few of our services which can come under high load quickly, and we don't need to scale up the entire site to serve those, such as our track processing. We believe Serverless was the correct decision for those processes.
That time includes the amount of time to spin-up the lambda.
Ours is a long-running lambda, and we benefit from some local cache when they are running as well.
In order to handle the load, we had to extend the number of lambda's available on our account as well, so we are talking about 1000s of seconds being eaten up every second.
We listen to the cloud pubsub from a worker.
1) we don't manage it. We receive quite a lot of webhooks and it's nice to offload that 2) all of our webhooks are async. We just have 1 worker that handles it all, instead of provisioning a bunch of pods. 3) managing cloud functions is dope, since you can make it autodeploy from git.
10/10 would use again. Not sure about building a whole app around it tho
My biggest complaints are probably DynamoDB eventual consistency (unavoidable when using GSIs), occasional CloudFormation funkiness (though no urgent prod issues yet, thankfully), CodeDeploy CW alarm rollback jankiness (which doesn't tell you which alarm triggered a rollback!!), and lambda coldstarts. But none of these are too terribly concerning and I have faith they'll get incrementally better over time, hopefully.
The biggest cautionary tip I have is we run all our Lambdas with the max 3GB memory both for peace-of-mind and because the underlying EC2 instances have significantly faster CPU. We were seeing weird timeouts and latency initially with <1GB memory, so I'd be hesitant to run the service if the extra cost of using the biggest possible instances is a concern, which for us it is not.
Another cost concern I should also mention is that we mitigate cold starts by running multiple canaries using scheduled lambdas (in addition to the standard canary role of generating a baseline of metrics and immediately detecting/alarming on end-to-end issues). We are effectively maintaining a constant warm pool which, in theory anyway, greatly decreases the chances customer traffic will hit cold starts. I'm not intimately involved with the financial aspects but I suspect achieving the same effect with EC2 would be significantly cheaper, at least with respect to infrastructure costs. I would guess, though, that the developer time savings achieved by massively reduced ops burden and overall system simplicity are probably comparable to the increased infrastructure cost, and very possibly hugely outweighing it.
I assume DynamoDB part isn't serverless.
DynamoDB is still persistent storage.
It seems that every every "hosted" solution is now being dubbed "serverless". :\
Oh and of course 5+ if-statements is now "AI".
While the definition of what constitutes 'serverless' is pretty ambiguous, no one includes ephemeral state as a systems requirement, else you have something useless.
DynamoDB is generally viewed as serverless because there's no management of an underlying VM, and for some definitions because it can scale out horizontally automatically, without downtime, to meet demand (as compared with RDS, or another managed database solution that can only scale vertically).
When you create a DB with DynamoDB, you're just telling AWS "I need a database" and it gives you one. No need to worry about deciding how much CPU power, RAM, or storage you'll need for it.
> It seems that every every "hosted" solution is now being dubbed "serverless". :\
Got a good example of something being called "serverless" that you don't think should be? I mean, yes, DynamoDB, Lambda, etc. are all running on servers. But the idea is that you don't manage them. No packages to keep up to date. No worrying about whether or not the instance size you chose is big enough. No dealing with autoscaling to meet demand when a million reddit users hit your app.
Meanwhile Kinesis requires you to specify the number of shards you have to use, so there is management even if they're not called "servers".
> No need to worry about deciding how much CPU power, RAM, or storage you'll need for it.
You realize you specify the RAM for lambda functions, which correlates to CPU.
And with Dynamo you specify RCUs and WCUs and you enable autoscaling which adds more...
I'm not trying to be pedantic about "The cloud being just someone else's servers". I mean that "serverless" to mean is a very explicit thing about Lambda and writing stateless code. And every existing hosted multi-tenant service shouldn't just be dubbed that.
DynamoDB is great, especially when it's used wisely.
[1]: https://docs.aws.amazon.com/amazondynamodb/latest/developerg...
It's also possible to use API Gateway canary deployments and dedicated "preprod" stages as well - the benefit being you can, in theory, use traffic shifting lifecycle hooks to deploy a new version completely isolated from customer traffic and test it before incrementally rolling out your main A/B deployment. I created an experimental proof-of-concept for this but haven't had the time to flesh it out for production usage, but would very much like to at some point.
tl;dr The answer to your question is yes, there is a good story around CI with Lambda using the AWS ecosystem. However Lambda alone is not something that should be relied on for long-term or definitive versioning on its own.
Edit: thinking about your question more, it seems you are assuming that individual developers will directly edit Lambda function code in the console and you want to track versions or trigger deployments based on that activity. You absolutely should not ever be editing Lambda code manually directly in the console outside of one-off experiments/prototypes that are completely unrelated to dev/test/production. Always keep your Lambda function code under source control and deploy using zips uploaded to S3 and CloudFormation (the serverless framework[1] provides good tooling for this, though we don't use it - instead we use SAM and our own internal tools).
[1] https://serverless.com/
At some point I believe when we're big enough we might switch to using servers in all the regions where we currently run APIG+Lambda.
The stacks are super proprietary. Porting away from AWS to another serverless cloud vendor (e.g. Azure) would be a major project.
Porting to a server-ful architecture would be a full rewrite.
Edit: We also broke the stack into a number of independent microservices, each with their own API, DB, and dedicated CI pipeline. This would allow us to incrementally migrate chunks in parallel without disrupting the entire service.
I still think platform neutrality is a good goal, but I'm starting to view it like I do database neutrality. It's great in theory to be able to swap out postgres with mysql and vice versa, but you miss out on a lot of features of postgres that aren't portable. And in practice, I've never swapped out postgres for something else. Just some thoughts.
well a moan bit loudly...
So without digging in to who the client is etc, are you saying that serverless architecture is today, validated enough that the AWS bill can be cut by ... what 25%? more?
That sounds like great savings (plus nice fat contractor bills for rewriting as lambda) - but is it a hit for amazon
(I suspect amazon views it as "kill your own babies" survival but am interested in the margin effect on the data centre business - it's twenty years since i touched a business model of a DC)
PS I get the prolongment issue - it sounds sensible in the 20 seconds it was covered in the approval meeting, but not when the details are looked at.
This does come with additional cost. Serverless pricing doesn't scale, your costs increase linearly with your usage, and there're no discounts for bulk usage or reserved pricing.
We were recently on the receiving end of a massive HTTP GET Flood DDoS and although we did not experience any downtime as a result of it, I ended up finding out about it a few days later when billing alarms started going off.
Basic Shield is supposed to be on for all users but I don't think APIG is covered in the range of services covered by their Advanced Protection plan.
I'm not blaming you -- far from it! Just wondering how applicable your experience is to the world I normally work in.
We are all in with AWS so the code build, cloudformation and code pipeline all work really well with lambdas.
I was super impressed with how they had set this all up and they were extremely well aware of all the limitations and do's and dont's of that particular cloud implementation.
Obviously there is the lock-in problem, if you ever decide to move you have a bit of work ahead, so build some abstraction layers in right from day 1 to avoid hitting all your code if that time should ever roll around.
And cultivate contacts with your cloud vendor.
That leaves the company to use the various APIs.
So you use Google Cloud Functions to ingest data and do all preliminary processing, store the data in one of the various persistent storage options (Spanner, Bigtable, whatever is best suitable for the job) processing optionally using background functions or containers for further processing or presentation.
Given that a reasonably short while ago I did not yet see Google as a serious contender in this space I'm actually surprised how far they have come.
You can basically create an enterprise class application dealing with vast amounts of data and never even know on what silicon (or where...) your processes are running.
Of course you still have to give some parameters, such as in which DC you want to run your stuff but on the whole it is about as painless as it can be.
For more info this would be a good starting point:
https://cloud.google.com/functions/
Important notes about the execution environment limits:
https://cloud.google.com/functions/quotas
If you decide you're never going to boot a machine and manage it yourself, you're locked into the exact set of choices your cloud had made available for you. When your project has a need that's not covered, you're stuck.
I'm not talking about vendor lock in here, purely about the reduced flexibility within a given vendor if you choose to never manage a server yourself.
So far, we love it. It handles roughly 20k images a day.
You are right that Cloudwatch logs are a hassle. So we pipe all of the log events into Scalyr (and log JSON objects, which Scalyr parses into searchable objects).
In terms of error handling, Lambda retries once on exception. So we raise exceptions in truly exceptional cases (e.g. - some weather in the cloud prevents a file from being downloaded or uploaded). We have Cloudwatch alerts that notify the team for every true exception. Happens less than once a day.
In pseudo-exceptional cases (e.g. a user emails an invalid image), we simply log to Scalyr with an attribute that identifies that the event was pseudo-exceptional, and then set up Scalyr alerts to email us if the volume of those events goes above x per hour.
tl;dr - Cloudwatch + Scalyr with good alerts and thoughtful separation of exceptions from pseudo-exceptions is my recommendation!
I have 14 or so regions so doing the same thing with EC2 would have considerable overhead, though I can still imagine many cases where Lambda would not be cost effective, but its integration with Kinesis is fantastic as well, stream processing almost cannot be easier, and while people say Kafka is more cost-effective, with a bit of batching you can get a long way with Kinesis as well.
https://apex.sh/ping/#pricing
But the business idea is simple so I am sure it would be easy to calculate a rough idea.
The best part is no devops needed. We use Serverless Framework. The biggest downside are cold starts for frontend response time. But this hasn't been a terrible issue as of yet. We have considered moving these 20 API endpoints to a nodeJS server which will resolve the issue but didn't have the time to do it yet.
We'll never go back. Serverless is the future.
The Bustle stack looks like Redis/Elasticsearch => NodeJS Lambda GraphQL API layer => (sometimes api gateway) => NodeJS lambda render layer => api gateway => CDN. We're working towards removing all the api gateway usage if possible with smarter CDNs like cloudflare workers and Lambda at edge, but it's not currently possible.
This setup gets us an average of 70ms api response time and less than 200ms worst case rendering time. Higher than 90% of cache misses never gets the worst case as we can serve stale content in those cases. Lots of room for improvement too. =)