14 ms·
PSA: porting an existing application one-to-one to serverless almost never goes as expected. Couple of points that stand out from the article: 1. Don’t use .NE
by abiro 7y ago
PSA: porting an existing application one-to-one to serverless almost never goes as expected. Couple of points that stand out from the article:
1. Don’t use .NET, it has terrible startup time. Lambda is all about zero-cost horizontal scaling, but that doesn’t work if your runtime takes 100 ms+ to initialize. The only valid options for performance sensitive functions are JS, Python and Go.
2. Use managed services whenever possible. You should never handle a login event in Lambda, there is Cognito for that.
3. Think in events instead of REST actions. Think about which events have to hit your API, what can be directly processed by managed services or handled by you at the edge. Eg. never upload an image through a Lamdba function, instead upload it directly to S3 via a signed URL and then have S3 emit a change event to trigger downstream processing.
4. Use GraphQL to pool API requests from the front end.
5. Websockets are cheaper for high throughput APIs.
6. Make extensive use of caching. A request that can be served from cache should never hit Lambda.
7. Always factor in labor savings, especially devops.
- cameroncf 7y ago> PSA: porting an existing application one-to-one to serverless almost never goes as expected. Came here to post this and agree 100%. Moving to Serverless requires evaluating the entire stack, including the server side language choice, and how the client handles API calls. Often a move to serverless is better accomplished gradually in stages than the quick "lift and shift" that AWS like to talk about so much. Sometimes you can simply plop your existing app down in Lambdas and it runs just fine, but this is the exception not the rule.
- k__ 7y agoThe community is to blame for this. If "serverless heros" are running around promoting Lambda, newcomers will use it without thinking twice...
- xwdv 7y agoIn tech you either die a hero or live long enough to become the villain.
- atroche 7y agoThe Rust runtime has a fast start time as well, FWIW.
- zeawee 7y agoBecause Rust doesn't have a runtime initialization.
- thramp 7y agoRust AWS Lambda Runtime author here: while the Rust runtime tends to beat all other runtimes, Go is _very_ close in terms of startup times.
- Scuds 7y agothis? https://aws.amazon.com/blogs/opensource/rust-runtime-for-aws-lambda/ https://aws.amazon.com/blogs/opensource/rust-runtime-for-aws... https://github.com/awslabs/aws-lambda-rust-runtime https://github.com/awslabs/aws-lambda-rust-runtime https://crates.io/crates/lambda_runtime https://crates.io/crates/lambda_runtime you rock! That docker based build system makes building those MUSL based rust binaries a snap!
- thramp 7y agoYep! Thank you so much! I really need to update the documentation, but I think `cross` (https://github.com/rust-embedded/cross https://github.com/rust-embedded/cross), a drop-in cargo replacement, is the probably the best available solution for building musl-based binaries.
- ufmace 7y agoI've struggled with this before, will have to take a look at it.
- missosoup 7y agoThat's more steps than 'just use containers and ignore the serverless meme'.
- abiro 7y agoI don’t think anybody advocates for rewriting all existing projects as serverless. But if you’re starting a startup, going all in on serverless will let you deliver better products faster. If Paul Graham’s Beating the Averages would be written today, the secret weapon would be serverless, not Lisp.
- missosoup 7y ago> going all in on serverless will let you deliver better products faster Can you show some empirical evidence that supports this? In my experience this is another nebulous serverless hype claim that doesn't withstand scrutiny.
- abiro 7y agoI don’t think it’s possible to produce empirical evidence to prove or disprove this claim, but it’s just common sense: Using managed services leads to writing less code and minimizing devops work, both resulting in more time for feature development that takes less time overall and produces higher quality service (latency, availability, etc). Then there is the added benefit of clear financial insight into the inner workings of the application (one can trace capital flows through functions) which will result in better resource allocation decisions.
- missosoup 7y ago> but it’s just common sense No. There's nothing common sense about it. It only seems plausible if you read the sales brochure from a cloud vendor and have no experience with all the weird and whacky failure modes of these systems and the fact that none of the major selling points of serverless actually work as advertised unless you dedicate significant engineering time to make them work - as the GP comment has demonstrated. The amount of engineering time required to make serverless work quickly catches up to or even exceeds just doing the damn thing the normal way. And that engineering time is not transferable to any other cloud vendor, and neither is your solution now. So congratulations you just locked your business in. Serverless only makes sense if you have a fairly trivial problem and operate on really narrow margins where you need your infra and associated costs to scale up/down infinitely.
- joelthelion 7y ago> Don’t use .NET, it has terrible startup time. Lambda is all about zero-cost horizontal scaling, but that doesn’t work if your runtime takes 100 ms+ to initialize. The only valid options for performance sensitive functions are JS, Python and Go. Shouldn't this not be a problem if you're doing 10 million requests a day? If you have enough requests, your lambdas should stay hot most if not all the time.
- CosmicShadow 7y agoI built an azure function that runs for free that just pings my .NET MVC pages periodically so they are always hot on my cheap hosting.
- Avalaxy 7y agoYou can just use application insights for this. It can also show you the results of the ping over time in a scatter chart.
- mycall 7y agoI need to include this into my builds.
- CosmicShadow 7y agoOh interesting, maybe I should look into this more, I feel like it would be useful, but one day it just showed up in my projects and spammed out and drowned all my debugs in the log so now I rip it out as soon as I can because it drives me nuts and I couldn't find an easy way to turn down the messaging.
- Avalaxy 7y agoIf you're still reading this, you can disable Application Insights during debugging (why would you need it anyway during debugging). To do this you make an application variable like 'EnableApplicationInsights' in your web.config so you can set per environment whether or not it should be on. Then if this is false, in your Application_Start() you can set this: TelemetryConfiguration.Active.DisableTelemetry = true;
- mnutt 7y agoHaving used serverless a bit, I’ve run into many of the same issues and generally agree with the advice but depending on your use case it may not be worth contorting your architecture to fit serverless. Instead, I’d look at it as a set of criteria for if serverless would fit your use case. At this point in time the only places I’d use lambda are for low-volume services with few dependencies where I don’t particularly care about p99 latency, or DevOps-related internal triggered jobs.
- frenchman99 7y agoI can't support point 7. enough. People often forget about the cost of labor. We migrated our company webapp to Heroku last year. We pay about 8 times what a dedicated server would cost, even though a dedicated server would do the job just fine. And often times, people tell me "Heroku is so expensive, why don't you do it yourself? Why pay twice the price of AWS for a VM?" But the Heroku servers are auto-patched, I get HA without any extra work, the firewall is setup automatically, I can scale up or down as needed for load testing, I get some metrics out of the box, easy access to addons with a single bill, I can upgrade my app language version as needed, I can combine multiple buildpacks to take care of all the components in our stack, build artifacts are cached the right way, it integrates with our CI tool, etc, etc. If I had to do all of this by hand, I would spend hours, which would cost my company way more. In fact, I'd probably need to setup a Kubernetes cluster if I wanted similar flexibility. By that point, I'd probably be working full-time on devops.
- rogem002 7y agoOnce you factor in the learning time for AWS per a developer the cost is even higher. At my previous company we had project with an AWS deploy process that only two developers could confidently use. Teaching a new developer & keeping them up to date was a big time sink. For comparison we had a Rails app setup on heroku that on day one junior devs were happily deploying to (plus we had Review apps for each PR!)
- mycall 7y agohttps://docs.microsoft.com/en-us/azure/app-service/containers/quickstart-ruby https://docs.microsoft.com/en-us/azure/app-service/container...
- abnerg 7y agoThis is a good point. Expecting developers to understand how to configure service to service IAM permissions and all the other nuances of AWS infrastructure is a fool's errand. Also one of the reasons we started Stackery.
- zaro 7y ago
- fogetti 7y agoI haven't thought about step 3 before, but makes sense. Maybe I should show this to the guy who used Google Cloud Functions to upload images in our previous project :) I guess the reasoning would be that this way the actual time spent in serverless code is shorter and by proxy the service becomes cheaper?
- abiro 7y agoSaves time and money by writing and executing less code + S3 is optimized for this task, so it will always perform better than an ad hoc serverless function.
- chrshawkes 7y agoGraphQL makes caching a real bitch.
- ClumsyPilot 7y agoIt might do, bu let for some APIs caching doesn't even make sense.
- deleted 7y ago[deleted]
- microcolonel 7y ago> 1. Don’t use .NET, it has terrible startup time. Lambda is all about zero-cost horizontal scaling, but that doesn’t work if your runtime takes 100 ms+ to initialize. The only valid options for performance sensitive functions are JS, Python and Go. I always sorta assumed that Amazon pre-initialized runtimes and processes and started the lambdas from essentially a core dump. Is there some reason they don't do this, aside from laziness and a desire to bill you for the time spent starting a JVM or CLR? Does anyone else do this?
- staticassertion 7y ago> The only valid options for performance sensitive functions are JS, Python and Go. With custom runtimes that's not the case anymore. I write my lambdas in Rust. Can't stress (7) enough, would also add 'morale' savings. It can be really stressful for developers to deal with gratuitous ops work.
- matchagaucho 7y agoRE: #3. This still requires a Lambda to pre-sign the URL. No? Granted, this approach is much lighter than uploading an image directly.
- abiro 7y agoIf you use Cognito for identity management, then there isn’t even need for that. You can just assign users the appropriate IAM role and you can upload directly from the front end.
- foxtr0t 7y agoSo, to summarize, you should: 1. not use the programming language that works best for your problem, but the programming language that works best with your orchestration system 2. lock yourself into managed services wherever possible 3. choose your api design style based on your orchestration system instead of your application. 4. Use a specific frontend rpc library because why not. ... I've hacked a few lambdas together but never dug deep, so I have very little experience, but these points seem somewhat ridiculous. Maybe I'm behind the times but I always thought these sort of decisions should be made based on your use case. EDIT: line breaks.
- hallman76 7y ago> I've hacked a few lambdas together but never dug deep Then why comment? You clearly don't understand the use-case that AWS fits. I've had jobs that took 18 hours to run on single machine finish in 12 minutes on Lambda. I could run that process 4 times a month and still stay within AWS's free tier limits. For the right workloads it is 100% worth realigning your code to fit the stack.
- foxtr0t 7y ago>Then why comment? Because the instruction list from above isn't backed with any solid reasoning and because commenting is what people do on HN. >You clearly don't understand the use-case that AWS fits. Pray tell, what is this enviable use case that I so clearly do not grasp?
- ses1984 7y ago>I've had jobs that took 18 hours to run on single machine finish in 12 minutes on Lambda. I could run that process 4 times a month and still stay within AWS's free tier limits. Ok I'll bite. What takes 18 hours to run on a single machine but finishes in 12 minutes on Lambda.
- mycall 7y agoAn unoptimized query?
- xchaotic 7y agoAs general rules these sound great at first sight, but don’t really address the main culprit from TFA - like for like API Gateway costs a lot more to process n number of requests.
- abiro 7y agoWell, given the feature set of API Gateway compared to a Load Balancer I think it should be expected that it costs more. But that’s also beside the point which is to use managed services to do the heavy lifting. Eg. if you need a PubSub service for IoT, that shouldn’t go through API Gateway and Lambda, there is a specific AWS service for that.
- dalanmiller 7y ago> 4. Use GraphQL to pool API requests from the front end. What does this look like in practice? Doesn't this increase response time for the initial requester?
- abiro 7y agoThese are usually the read N items from a database type of queries that GraphQL makes trivial to batch together. Will barely increase response time, but will provide a better experience for users on bad connections.
- oliora 7y agoYou forget C++. It’s a great choice for Lambda due to startup times. Python startup time is actually terrible and should be avoided if the call rate is really high. Actually, Lambda instance is reusable and after spinning up it will be used to handle multiple requests (if ones are coming often enough).
- peterwwillis 7y agoOn "7) Always factor in labor savings, especially devops": DevOps is not a synonym for "ops" or "sysadmin". It's not a position. DevOps is like Agile or Lean: it's a general method with lots of different pieces you use to improve the process of developing and supporting products among the different members of multiple teams. DevOps helps you save money, not the reverse. You don't even need an "ops person" to do DevOps.
- sreque 7y agoI measured startup of the runtimes a long time ago, and back in the days of node.js 010.x at least, Python 2's startup time was twice as fast as Node.js's, and Java's wasn't much worse than Node.js. I don't know how .NET fares compared to Java, but I imagine it's about the same. Furthermore, eople like to compare runtime startup times, but this tells a very small portion of the story. For most applications, the dominant startup cost isn't the startup of the runtime itself, but the cost of loading code the app code into the runtime. Your node.js runtime has to load, parse, compile, and execute every single line of code used in your app, for instance, including all third-party dependencies. Compare, for instance, the startup cost of a "hello world" node.js function with one that includes the AWS SDK. At least, six years ago, the Node.js AWS SDK wasn't optimized at all for startup and it caused a huge (10x?) spike in startup time because it loaded the entire library. I would argue that the only languages that are a really good fit for Lambda are ones that compile to native code, like GoLang, Rust, and C/C++. The cost to load code for these applications is a single mmap() call by the OS per binary and shared library, followed by the time to actually load the bytes from disk. It doesn't get much faster than that. Once you've switched to native code, your next problem is that Lambda has to download your code zip file as part of startup. I don't know how good Lambda has gotten at speeding that part up.
- jroper 7y agoNumber 3 - thinking in events instead of REST actions, can't be stressed enough. Of course, some things must be actions (or another for that is commands), and in those situations, you need something that will turn a command into an event, this is one of the features of CloudState (https://cloudstate.io https://cloudstate.io), which offers serverless event sourcing - you handle commands, and output events that can be further processed downstream by other functions.
- wodenokoto 7y ago> Below is a report for one request, you can see we're using 3.50ms of compute time and being billed for 100ms, which seems like a big waste. Doesn't sound like your point number 1 is valid at all, quite the opposite.
- abacate 7y ago> The only valid options for performance sensitive functions are JS, Python and Go. I can think of a number of other languages that would probably easily surpass these, especially on latency.