Closed monkut closed 7 months ago
Hey, just wanted to provide some quick thoughts here! (Note: Ok, now having finished with writing what follows, it seems my thoughts turned out to be not-so-quick 🙃 - sorry, I'll provide a quick TL;DR.)
Unless new features are critical (e.g., supporting a new Python version), we should probably not add them to Zappa right now, as I'm in the process of replacing Zappa's ancient self-management of infra with the ability to interface with modern Infrastructure-as-Code (IaC
) platforms that will enable all of the current features of Zappa, plus allow the use of pretty much every AWS feature that anyone could ever want.
Regarding the two features specifically mentioned, as far as adding either to Zappa:
IaC
transition is complete. Although, as this is a feature that can already be enabled on any Lambda function in ~30 seconds using the AWS console, I'm not sure if the effort would be worth it.Of course, using IaC
, knowledgeable users can enable either of these features (and countless more), but doing so via IaC
requires far more intentionality than simply playing around with the settings found in a single JSON file (zappa_settings.json
).
For context, here are a few of the premises of Zappa (all IMHO, of course): what it is (and is not) and the scope of the role it should aim to play within the broader context of the overall AWS ecosystem and related tools:
IaC
) platforms, to be used if desired. Given the proliferation and maturation of IaC
platforms since Zappa was first released 8 years ago, our focus on enabling/supporting/encouraging their use for infra configuration should be significantly increased compared to where Zappa's focus was 8 years ago, which was more on increasing the amount of infra configuration that Zappa could automate itself directly via the AWS API.IaC
platforms are much better suited to do that job, and we should not try to make Zappa into another IaC
platform. If I were to rewrite Zappa from scratch today, I'd probably completely remove any direct configuration of AWS infra all together, and instead focus on supporting common IaC
platforms that could be used to configure the necessary infra for Zappa. Default templates for the supported IaC
platforms could be included (and/or automatically generated) that would enable the relevant IaC
platform to configure the "default Zappa" infra that Zappa currently configures itself directly via the AWS API. These templates could be used as-is, or they could be used as a starting point that users/orgs could then customize to meet their specific needs.
IaC
platforms will render most "can Zappa add support for x
?" questions moot, limit the scope (Zappa has continually been suffering from scope creep ever since it was originally released) of what Zappa needs to do/support, and allow for developer focus to shift toward ensuring that Zappa is able to fulfill its primary purpose via a consistent, fast, high-quality, and bug-free experience.IaC
platforms that already support extensive AWS infra configuration, rather than attempting to support the ever-growing list of AWS infra configuration options that Zappa, in its current state, would need to manually configure itself via the AWS API. Doing so will only serve to entrench Zappa further in its current no-man's-land state of functioning partly as a pseudo-IaC
tool and delay how quickly we can extricate ourselves from that undesirable state.IaC
platform). However, here are examples of some of the things that I think should continue to be prioritized as necessary:
IaC
) where useful/appropriate, Docker/containerization, OSes, etc.IaC
support to feature requests) within finite time constraints. This includes things like:
Whew 😅. Ok, with that context in mind, let's discuss the features that were brought up.
"Reserved concurrency" and "provisioned concurrency" are actually quite different features, targeting different use cases (with potentially drastically different cost implications) so I think each should be discussed separately. To that end:
Limits how many simultaneous invocations there may be of a given Lambda function. For example, most accounts start out with a total limit of 1000 simultaneous Lambda invocations across all functions (note: this is a limit that can easily be raised by asking AWS support - I've seen it be set well into the millions at large, corporate entities - AWS just prefers to start accounts with relatively low limits so an inexperienced user/org doesn't accidentally run up a $100k+ bill due to a bug that is launching way more Lambda invocations than expected), and, assuming that an AWS account has that default level of 1000, then setting the "reserved concurrency" on function x
means that function x
will be able to have up to 400 simultaneous Lambda invocations, but cannot exceed 400, even if there is demand for more. What it also means is that all other functions would now only have a pool of 600 "unreserved" Lambda invocations they can simultaneously share, as the 400 "reserved" for function x
cannot be used by any other function.
Background
. TL;DR: it's 2024; rather than continuing to function as a quasi-IaC
solution that slowly adds (or doesn't add) AWS infra features in piecemeal to a zappa_settings.json
that has continually become more of a confusing mess as scope creep has continued for nearly a decade, Zappa should focus on increasing support for the various IaC
platforms which exist specifically to allow for detailed configuration of AWS infra to be defined, which would offer the ability to configure this setting (and countless more) immediately, without the need for Zappa to develop and maintain its own manual implementation for configuring the setting by directly interacting with the AWS API.zappa_settings.json
, users may not fully understand what it does (and/or get it mixed up with "provisioned concurrency"), and enabling it in one of the most common use cases (i.e., a user/org is deploying their web app's backend API via Zappa, and only has a handful of other Lambda functions - if any at all - that are typically going to be comparatively very minor/not user-facing/etc. in terms of importance/priority/etc. when compared to the API) would, if anything, just increase the likelihood of causing performance degradation (because now their main Lambda function for their API would no longer be able to use all 1000 available account-wide simultaneous Lambda invocations - it would be limited to whatever was set for "reserved concurrency").
IaC
platform (which are typically much more extensively documented than Zappa) may provide some benefit.If the community actually does indicate that they have a strong desire for the ability to enable "reserved concurrency" via Zappa's config, and someone submitted a high-quality PR with complete test coverage that didn't require an extensive review process, I suppose I wouldn't be opposed to merging it, as full integration with IaC
platforms will likely take a while. But, this isn't something I would personally commit to adding support for, as I don't think it's an important enough feature to warrant pausing my work toward replacing Zappa's outdated manual infra configuration system with the ability to use various IaC
platforms to do the infra configuration for Zappa.
Keeps a defined amount of Lambda function instances active/"spun up"/warm, regardless of activity. For example, if the "provisioned concurrency" of function x
is set to 100, then 100 instances of function x
will run 24/7 indefinitely, even if function x
is not invoked for days/weeks/months/years. If function x
then receives 500 simultaneous invocations, 100 of those invocations will be able to take advantage of a "warm start", while the other 400 will have to "cold start". After ~5 minutes after the completion of function x
's invocation, if function x
does not again receive more than 100 simultaneous invocations, the 400 instances that were spun up in addition to the 100 kept active by "provisioned concurrency" will get spun down again. Users of "provisioned concurrency" not only have to pay for the Lambda runtime, but they also have to pay an additional fee is levied by AWS for the use of the "provisioned concurrency" feature. In other words, the cost/min of running a Lambda function instance via "provisioned concurrency" is greater than the cost/min of running a Lambda function instance that is created normally, even if it is then "kept warm" by other means (discussed below).
$LATEST
alias of the Lambda function (which always targets the most recent version of the Lambda function), an easy way to ensure that the latest version of the deployed API is always the one served to users. However, the special-case $LATEST
alias cannot be targeted by "provisioned concurrency" (a long-standing limitation imposed by AWS, although it seems like it should be simple enough thing to enable with the pool of engineering talent they have available 🤷♂️).
$LIVE
) targeting the latest version number (an auto-incrementing integer) of the Zappa-deployed Lambda function. While the special-case $LATEST
alias cannot be the target of "provisioned concurrency", any custom alias that is user-created can be the target. Set this alias to be the target of "provisioned concurrency" and make sure to change API Gateway (if being used) to also target your custom alias rather than $LATEST
.zappa update
is run, all you have to do is use the AWS API to fetch the new version number of the function, and then use the AWS API to change the custom alias that "provisioned concurrency" is targeting to refer to the new version number. This can be done using the AWS CLI, via a Python script using boto
, etc.$LATEST
alias (which Zappa has done since day 1), which would require Zappa to several additional API requests (slowing deploy time) for each deploy/update, even though only users using "provisioned concurrency" would benefit. Zappa would at least need to add further logic to handle functions deployed with older versions of Zappa that target $LATEST
in order to convert them to the new practice of using a custom alias. There are probably other ramifications that would manifest as well.1
set on the Lambda function, without needing to pay the additional "provisioned concurrency" premium.Background
. TL;DR: it's 2024; rather than continuing to function as a quasi-IaC
solution that slowly adds (or doesn't add) AWS infra features in piecemeal to a zappa_settings.json
that has continually become more of a confusing mess as scope creep has continued for nearly a decade, Zappa should focus on increasing support for the various IaC
platforms which exist specifically to allow for detailed configuration of AWS infra to be defined, which would offer the ability to configure this setting (and countless more) immediately, without the need for Zappa to develop and maintain its own manual implementation for configuring the setting by directly interacting with the AWS API.zappa_settings.json
. Zappa has always been something that students/beginners can play around with and test without needing to worry much about accidentally racking up a huge AWS bill (a Lambda function doesn't cost anything until it gets invoked). Adding an easy way to enable "provisioned concurrency" in zappa_settings.json
would fundamentally remove that implicit safety that users have come to expect over the past 8 years. A student is playing around with Zappa, deploys a dozen or so Lambda functions, forgets about them. Today, nothing happens. If we had a provisioned_concurrency
setting that he set to 1000
, a month later, AWS sends him a $50k bill. Since part of Zappa's mission is to provide its functionality to as many users as possible, including students/beginners, I am extremely hesitant to add any configuration setting that could easily be inadvertently/unknowingly enabled and result in users unwittingly being charged major sums of money by AWS.
slim_handler
setting will kill cold start time, because the application has to be downloaded from S3, extracted, installed, configured, and initialized on every cold start. The other major mistakes I've seen made are apps that do too much in their lambda_handler
function/module (hint: more than the bare minimum is usually too much - try to do things after your app has been instantiated) and/or apps that have to make many requests outside of Lambda to get everything they need to initialize. For example, users will store keys in KMS, secrets in Secrets Manager, assets in S3, need data from RDS (or, even worse, need to make requests to external APIs) in order to get all of the settings their application needs to initialize. All of those requests will slow cold starts significantly. All settings needed to initialize an app should be kept in the Lambda functions' environment variables. Getting anything else (like from S3, RDS, or a 3rd party API) should be done after your app has been instantiated.slim_handler
.)I really don't think adding "provisioned concurrency" support to Zappa is a good idea. The fact that it would break the implicit contract Zappa has had with its users since its inception that "you can (safely) use Zappa to mess around with deploying your apps to Lambda" by adding a setting that could deploy a Lambda function that would immediately begin accruing charges on their AWS bill is a complete non-starter by itself, IMO, and that's far from the only concern it would bring.
Hi there! Unfortunately, this Issue has not seen any activity for at least 90 days. If the Issue is still relevant to the latest version of Zappa, please comment within the next 10 days if you wish to keep it open. Otherwise, it will be automatically closed.
Hi there! Unfortunately, this Issue was automatically closed as it had not seen any activity in at least 100 days. If the Issue is still relevant to the latest version of Zappa, please open a new Issue.
Lambda now provides a reserved and provisioned concurrency setting/configuration.
https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html#reserved-and-provisioned
https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html
zappa currently provides a
keep_warm
function to periodically keep a single lambda instance "warm". However, the currentkeep_warm
method is not expected to reduce cold starts for more than a single instance.This issue requests that reserved and provisioned concurrency are properly integrated with zappa. Potentially consider depreciating
keep_warm
in favor of these new concurrency settings.