This is awesome news. I would expect that we would probably see normal Lambda functions eventually follow suit to the 1ms pricing model, or at the very least, something like 10ms incremenets.
For those who aren't super familiar with AWS, this announcement only covers "Lamda@Edge", this isn't the "normal" Lamda serverless function service. These are Lamda functions running at AWS Edge Locations, which are hundreds of CDN endpoints around the world. Lamda@Edge have various restrictions on what they can do, compared to the main Lambda service. They can only be triggered by CloudFront (AWS' CDN service). You could think of them as a "lite" version of Lambda. They are generally used for basic tasks like renaming/manipulating HTTP headers coming into the CDN. So they tend to run in just a few milliseconds.
Normal Lambda are currently billed in 100ms increments. But it would be great to see this come down. I run a few Lambda functions that take < 10ms to run and it would be nice to be able to get 10x the invocations than I am getting on them now because I have to pay the 100ms rate for a 10ms invocation. Granted its all so cheap, even at scale, that its hard to complain too much.
For instance, Cloudflare throws in fair-use bandwidth and its cache for free, while there's also no need to setup an API Gateway to serve http reqs (if forwarding http is all you're doing with apigw).
It's funny our team literally just last week did something like this at ___ BigCorp. We need to verify a JWT signature from a new 3rd party provider and then append a secure auth token that is accepted by the backend service. Couldn't this just be done in the backend service? Why yes it definitely could. But apparently there are rigid security policies in place, and this stuff appears to have been carved in stone and approved by SOC2 auditors and lawyers and regulators or whatever and they have agreed that the backend gateway would use X specific formats for authentication and nobody can make any exceptions. So instead our team is spinning up an ad-hoc lambda function attached to cloudfront which will use none of our usual tooling & frameworks and have zero visibility for our security teams and be full of whatever soon to be out of date 3rd party js dependencies we need, all in the name of security so that we can pretend that the API we're communicating with is using our approved auth token format when they aren't. Just another day at a big company, really.
I mean a less cynical reading is that this is like nginx handling https->wsgi for your Python application. You can deal with a unification of your auth stack and not have application development be disrupted
We use Lambda@Edge to build our own CDN on top of S3 with authentication, so our customers have reliable, fast and secure data access. We use a bunch of edge lambdas which serve thousands of requests each minute, so I suspect we'll see a nice cost reduction with this.
Some of the stuff we do:
- rewrite urls
- auth and permissions check
- serve index.html on directory indexes
- inject dynamic content in served html files
- add CORS headers
Can I ask how you're injecting dynamic content in served html files? My understanding was that lambda@edge functions could not modify the origin response body.
> When you’re working with the HTTP response, Lambda@Edge does not expose the body that is returned by the origin server to the origin-response trigger. You can generate a static content body by setting it to the desired value, or remove the body inside the function by setting the value to be empty. If you don’t update the body field in your function, the original body returned by the origin server is returned back to viewer.
It sounds to me like they might be creating the response from scratch rather than modifying an existing one. And since they’re talking about serving data from s3, maybe it’s just a nicely formatted version of aws s3 ls?
I'm not sure what you're specifically referring to by egress, but data transfer from S3/EC2/ELB etc to CloudFront is free:
> If you are using an AWS origin, effective December 1, 2014, data transferred from origin to edge locations (Amazon CloudFront "origin fetches") will be free of charge.
And in general data out from CloudFront ($0.085 to $0.02 in NA & EU) is cheaper than data out from S3 ($0.09 to $0.05 in us-east-2). For the lambda@Edge portion it's $0.60 per 1 million requests while the CloudFront requests are $0.75 to $1.00 per 1 million requests.
Those are public on demand rates and any customers with significant or consistent usage should definitely contact AWS for lower committed/custom prices.
Edit: Disclaimer I'm a principal at AWS, and in the past spent significant time working on CloudFront & Lambda@Edge, but all of the above is public information.
In AWS on the whole if there is any type of extension mechanism it's done via a lambda. Anything that needs an eval(), that is more than a regexp, is done via lambda.
This makes lambda's the glue of AWS. The input events are small json values, and the outputs are json values, and you can (mostly) use any language you want.
Essentially this is a way to lets you push all of the weird feature requests your customers might have off into one place.
From a customer point of view, maybe you need to rewrite the path based on the contents of a cookie, or maybe you want to shed certain types of requests in high load scenarios, or maybe there's a buggy upstream application that sends bad cache-control headers, or ...
If the goal is to let the customer specify infinitely complex logic at the edge, a programming language is a good way to do that. Function As A Service is a good billing model for lots of invocations of short, small functions across the customers choice of language.
The unfortunate side effect is that Lambda@Edge at least adds quite a bit of latency that a simpler but less powerful rules based system for header manipulation probably wouldn't.
We experimented with using Lambda@Edge for manipulating a header, but the added latency just wasn't worth it, and we had to come up with a different solution. That was years ago though, so maybe it is better now.
It's especially useful for doing things during the Origin Request phase, which happens prior to the request from the CDN to the Origin.
In that phase you can change anything about the request itself, or the origin it will connect to. But the function only needs to run when there's a cache miss.
I have an application that needs to select an origin based on the request path (too many to use CloudFront cache behaviours), with a cache miss rate of less than 1%. It's a tiny amount of additional latency for cache misses, and a very small proportion of our CDN costs per month.
I think so, as an alternative to all this AWS magic you could totally deploy <insert open source software name> on 200+ newly deployed instances, colo servers, or whatever you like!
I caught it too. I get downvoted a lot for not following rules and I don’t really care this was hilarious
cloud magic has shown us that “one day” we will need to scale up to an extreme count of “instances” and that suboptimal solutions can be negated with horizontal scaling.
CloudFront should let you configure header injection for responses. Just a simple list of key-value pairs. I've seen it requested before, it's a feature a lot of people want.
I don't understand what nginx has to do with this. nginx's language is just that: a language. If Lambda@Edge would support nginx language, you would still be invoking a lambda. But I'd must rather write some header rewriting code in, say, JavaScript than nginx's language.
Then why a (Turing-complete) programming language and not a config language? Simple: because a programming language gives you infinite more power than what any config system could ever provide. E.g. I could compare the origin IP, determine the country, and change the response based on that. And there are plenty of use cases like this which you cannot express in a config language.
> E.g. I could compare the origin IP, determine the country, and change the response based on that. And there are plenty of use cases like this which you cannot express in a config language.
Well, you can do that in plenty of "config languages", including nginx[1]. The reason Lambda exists is that it's good for Amazon, because they can push all the costs of the logic back onto the customer. (It could also be good for the customer, in that whatever configuration Amazon might otherwise support could be limited.)
Has anyone replicated a sqllite db to Cloudfront cache and used that as an input to their Lambda@Edge ?
I have been thinking about this for a while as it would avoid having cloudfront making a origin call to the backend server for db reads on data that does not change frequently. I am trying to figure out why this is a bad idea .
We replicate sharded, versioned, csv-files on-demand from S3 to Cloudflare edge for code run by workers.dev.
Cache invalidation is tricky. Avoid it by ttl-expiring caches as frequently as budget allows. We, instead, employ a (probably over-engineered) hand-rolled set-reconciliation algorithm to match our read/write patterns.
do it! Years ago my team messed around with using lambdas to pull/push data from sqlite into s3 and it worked pretty well for certain regime sizes and workloads! Then we partitioned the data to filter out the slow zones into more robust/long running things like a job queue and postgres
You only have five seconds to process the entire request. If your lambda has to make a request to download a sqlite database every time, and the process it, it probably needs to be small enough to fit into 1MB anyway.
Lambda functions running @Edge have different limits compared to vanilla AWS Lambda. You get 30 seconds to respond if it's on a cache miss (Origin Request/Response), or 5 seconds if it's on a cache hit (Viewer Request/Response): https://docs.aws.amazon.com/AmazonCloudFront/latest/Develope...
Lambda (at least the non-@edge version) comes with 512MiB of
/tmp directory storage
And "The same Lambda execution environment may be reused by multiple Lambda invocations to optimize performance. The /tmp area is preserved for the lifetime of the execution environment and provides a transient cache for data between invocations. Each time a new execution environment is created, this area is deleted."
Regular Lambda (not edge) are just container images up to 10 GB in size.
There's also the layers thing. A function can use up to five layers at a time. The total unzipped size of the function and all layers can't exceed the unzipped deployment package size limit of 250 MB. Can update separately from the container, almost as fast as a regular fs.
And finally it has access to EFS which is faster than S3.
Interesting, we’re just about to put cloudflare workers in prod and find their approach much more flexible vs lambda@edge being possibly triggered four times at edge part of a request life cycle. But this could significantly reduce cost if your execution time is low.
How likely are you to see 1ms execution times for this stuff tho? Super simple logic should be that low I guess..
They must have a very mature execution environment to be able to offer this (if 1ms execution is achievable), cf workers have a whole set to logic to average out cpu spikes so you don’t randomly hit the 50ms limit, bc their execution of your code isn’t that deterministic I suppose.
I don't think it's about getting 1ms execution time: It's more like having 300ms vs 301ms execution time be very similar in cost (or however the rounding worked).
The firecracker microvm says startup time is under 125ms, but I have not personally done any benchmarking, though my employer does use firecracker for hosting our CI builders.
Ah yeah makes sense. Really interesting that cf workers limit you to 50ms cpu time rather than wallclock time, makes lots of send-then-wait scenarios possible/way cheaper.
actually there appears to be a limit to this. i’ve never been able to perform more than ~50 http requests per invocation, leading me to believe that they are “billed” with 1ms cpu time.
So if I want to hook into each 4 parts of the lifecycle, I configure that and it gets executed once?
Can I maintain state between inbound request->origin request->origin response->inbound response?
My understanding was you can’t and it got called 4 times with different events, workers solves this by you being responsible for making the origin request (there is a simple mode where it does it for you to) with promises to manage origin response and inbound response logic.. I thought lambda@edge didn’t work like that?
For each lambda function you specify which one of the 4 places it is called. So effectively be 4 different lambda functions, triggered independently (they could ofcourse share code).
If you wanted to maintain state then I'd guess the easiest (only?) way is for the function to add headers to the HTTP request/response as it passed through.
This is great news! I'm using lambda@edge to server-side render an ember.js app using Fastboot (http://ember-fastboot.com/), and lowering the cost is a real big win!
I'm not using the fastboot-app-server, which currently uses express and requires you to have that set up for your app, but it's the most common path. Using lambda@edge is slightly different in that I'm relying on the cdn to render the page once and then cache it for subsequent requests w/o requiring a node server.
Yep Sqwok is rendered with fastboot (mostly used for the post page seo/rich preview) Feel free to ping me @guac or ask a question and I'll respond, and also there is a fastboot meeting next week that I'll be at and it should be interesting! The fastboot team has been working on some really cool stuff.
There's some set up required and you have to essentially handle how to route the request, handle static files, compression, etc, but it's not _too_ bad.
I've been meaning to do a write up on it and probably should, but feel free to check it out in action at the site I'm developing https://sqwok.im
ah darn! well I'm sure they'll have a recap video! or let me know if you have any questions you'd like to ask, or ask in the fastboot chan on discord, or sqwok :D
That assumes the runtime is evenly distributed, which is probably not the case. But still yeah, there will be some functions that end exactly in multiples of 50ms.
AWS has admitted under-pricing S3. A new bill item, # of requests served, was added after launch.
> ... When we launched S3, we were charging only for data transfer and data storage. It turned out that we had quite a few customers who were storing millions and millions of thumbnails of products they were selling on eBay. There was not much storage because these thumbnails were really small, and there wasn't much data transfer either, but there were enormous numbers of requests. It made us learn, for example, when you design interfaces, and definitely those you charge for, you want to charge for what is driving your own cost. One of the costs that we didn't anticipate was the number of requests, and request handling. We added this later to the payment model in S3, but it was clearly something we didn't anticipate. Services that came after S3 have been able to learn the lessons from S3 itself.
Yeah; citation needed. I've never seen an instance of a price increase. I can find multiple forums of people claiming Amazon has never increased prices.
The only instance I can find of any cloud provider increasing prices was once in 2015 when Microsoft did in Europe...and while that led to a flurry of "cloud providers are going to increase prices" blog posts and things, calmer heads noted the exchange rates as the likely reason (and, certainly, the claims that prices would increase across the board never came to pass).
That's fair, though I'd consider APIs to be a different beast than a cloud IaaS sort of thing. Maybe that's the distinction worth making, IaaS vs SaaS or similar. But fair point either way.
i wish someone would make a financial derivative of cloud provider pricing. i'd like to make money off of all of these folks who are convinced AWS is going to raise prices, any day now.
AWS is quite expensive, but I don't think they actually raise prices much if ever. At worst, they just don't lower prices as quickly as Moore's law decreases their costs.
Dotnet is not a language. C# and the others that run in dotnet environment can be JITed with multiple tiering for fast startup or use various AOT toolchains from Mono, Xamarin, Core RT to new built-in output in dotnet 6.
For those who aren't super familiar with AWS, this announcement only covers "Lamda@Edge", this isn't the "normal" Lamda serverless function service. These are Lamda functions running at AWS Edge Locations, which are hundreds of CDN endpoints around the world. Lamda@Edge have various restrictions on what they can do, compared to the main Lambda service. They can only be triggered by CloudFront (AWS' CDN service). You could think of them as a "lite" version of Lambda. They are generally used for basic tasks like renaming/manipulating HTTP headers coming into the CDN. So they tend to run in just a few milliseconds.
Normal Lambda are currently billed in 100ms increments. But it would be great to see this come down. I run a few Lambda functions that take < 10ms to run and it would be nice to be able to get 10x the invocations than I am getting on them now because I have to pay the 100ms rate for a 10ms invocation. Granted its all so cheap, even at scale, that its hard to complain too much.