Home

Awesome

re:Web

re:Web enables classic web applications to run on AWS Lambda.

It translates serverlessly between any web application and the AWS API Gateway or AWS Application Load Balancer.

But Why?

Traditional web applications need to be deployed on VMs or in containers. These run continuously around the clock, which means you have to reserve (pay) CPU and RAM capacity continuously. Every millisecond that your service is not busy handling a web request, it is wasting resources. Typical web applications spend more than 90% of their CPU time idle. That's a lot of waste! Finely tuned and well-operated high-traffic applications may see much better utilization, but even then there is a lot of headroom (waste).

With re:Web and AWS Lambda, you can practically eliminate this waste: Resources are billed only as they are actually used for each individual web request, down to the millisecond.

This can mean significant savings for any usage pattern, but of course it's especially awesome for applications that are not used around the clock, like Grafana, or applications that are used in a very unpredictable and peak-prone way, like PostgREST.

This architecture has some key benefits:

Status

This is experimental / a proof of concept. Maybe don't use it in a high-profile production site just yet. :-)

But it works surprisingly well. I'd like to evolve this idea and push the envelope a little, to see what's possible. The most imporant next step is to test and document more applications that work this way.

Applications

Because re:Web behaves like a HTTP proxy, it can potentially work with many, many applications!

It requires zero code changes.

All you need to do is to add the re:Web binary and use it as the ENTRYPOINT. In some cases, some trivial changes to the application's Dockerfile are necessary, to make the application suitable for the AWS Lambda execution environment.

The following applications have been tested and are known to work:

Click on the links for setup details.

The following applications are known NOT to work:

More Data

There's some high-traffic load test data for Wordpress; it includes some napkin math for potential AWS costs.

How it Works

High level overview:

re:Web arch

API Gateway

We abuse the API Gateway because it's simply the better Load Balancer -- it has less administrative overhead, we don't need to embed it in any VPC, and most importantly, it charges per actual request instead of per hour.

It is used simply as a dumb HTTP proxy and forwards all requests to Lambda. Note that it terminates TLS; it allows custom domain names and ACM certificates.

Application Load Balancer

There's several scenarios where ALB might be preferable to API Gateway -- most importantly, it becomes cheaper than API Gateway at some traffic levels.

When using ALB, make sure to select Multi Value Headers in the ALB Target Group attributes.

re:Web

The re:Web binary is a small piece of Go code that is added to the original web application's container image. It is the Lambda's entrypoint. On startup, it starts the actual web application, and waits until it becomes available. It handles communication with the Lambda Runtime API, and for each incoming request (Lambda invocation), it will make a corresponding HTTP request to the web application.

Application Server

This is simply the web application, as it would have been deployed per usual. Most software images come with some web server built-in, e.g. Apache or nginx, and/or they provide their own HTTP server which would serve traffic directly to the public in a VM or container deployment. re:Web acts as a proxy to this HTTP server.

Future Ideas

Many! In no particular order:

Contributions welcome, of course! See below for "Contact".

Limitations

Session management

Due to the potentially high and fluctuating concurrency of Lambda, re:Web can only work with applications that behave properly in such settings. Any application that needs to keep local state, like session information, will not work. While some such applications can be coerced by using a load balancer's "sticky session" feature, this workaround will not help on Lambda.

Lambda Limitations

Lambda itself has several very important limitations.

See also: Lambda quotas.

API Gateway vs. Application Load Balancer

LimitAPI GatewayApplication Load Balancer
ProtocolsHTTPS onlyHTTP and/or HTTPS
Request size (uploads)10 MB1 MB
Response size6 MB (from Lambda)1 MB
Timeoutmax. 30 seconds900 seconds (from Lambda)

Startup Time

One more thing to keep in mind is the web application's startup time. Every time when Lambda needs to spawn an additional instance to handle a request, this request will have to wait until that instance is ready.

This is next to nothing for many languages like PHP and Go (1-3 seconds at most -- not very noticable), but can be annoying (Kibana/Node takes ~10 seconds to start) or it can flat out stop the show (e.g. Confluence/Java takes about half a day to start). All subsequent requests handled by a "warm" instance can complete in mere milliseconds, of course.

This can be worked around with using Lambda Provisioned Concurrency, but that voids the Lambda cost advantage. It might still be preferable to a container deployment for availability reasons though; "it depends".

Lambda VPC Interface Idle

To quote an AWS blog post: "If Lambda functions in an account go idle for consecutive weeks, the service will reclaim the unused Hyperplane resources and so very infrequently invoked functions may still see longer cold-start times" (emphasis added)

Related Work

A Tale of Two Projects

As mentioned above, the serverlessish implements the very same idea, in an amazingly similar way. The main differences are that it is built for the AWS Application Load Balancer (instead of API Gateway) and is designed as a Lambda Extension. We have been in contact; updates soon.

Are you AWS?

I believe the whole concept here is gold. But shoehorning it into Lambda requests and translating JSON/HTTP back and forth is hacky. This could be made into something beautiful, with some changes in the involved AWS Services. Let's talk!

News and Updates

There is now a small blog where I post news and updates.

Contact

For bug reports, pull requests and other issues please use Github.

For everything else: