In Beyond the Twelve-Factor App, I present a new set of guidelines that builds on Heroku’s original 12 factors and reflects today’s best practices for building cloud-native applications. I have changed the order of some to indicate a deliberate sense of priority, and added factors such as telemetry, security, and the concept of “API first” that should be considerations for any application that will be running in the cloud. These new 15-factor guidelines are:
- One codebase, one application
- API first
- Dependency management
- Design, build, release, and run
- Configuration, credentials, and code
- Backing services
- Environment parity
- Administrative processes
- Port binding
- Stateless processes
- Authentication and authorization
Disposability is the ninth of the original 12 factors.
On a cloud instance, an application’s life is as ephemeral as the infrastructure that supports it. A cloud-native application’s processes are disposable, which means they can be started or stopped rapidly. An application cannot scale, deploy, release, or recover rapidly if it cannot start rapidly and shut down gracefully. We need to build applications that not only are aware of this, but also embrace it to take full advantage of the platform.
Those used to developing in the enterprise world with creatures like application containers or large web servers may be used to extremely long startup times measured in minutes. Long startup times aren’t limited to just legacy or enterprise applications. Software written in interpreted languages or just written poorly can take too long to start.
If you are bringing up an application, and it takes minutes to get into a steady state, in today’s world of high traffic that could mean hundreds or thousands of requests get denied while the application is starting. More importantly, depending on the platform on which your application is deployed, such a slow startup time might actually trigger alerts or warnings as the application fails its health check. Extremely slow startup times can even prevent your app from starting at all in the cloud.
If your application is under increasing load, and you need to rapidly bring up more instances to handle that load, any delay during startup can hinder its ability to handle that load. If the app does not shut down quickly and gracefully, that can also impede the ability to bring it back up again after failure. Inability to shut down quickly enough can also run the risk of failing to dispose of resources, which could corrupt data.
Many applications are written such that they perform a number of long-running activities during startup, such as fetching data to populate a cache or preparing other runtime dependencies. To truly embrace cloud-native architecture, this kind of activity needs to be dealt with separately. For example, you could externalize the cache into a backing service so that your application can go up and down rapidly without performing front-loaded operations.