Twelve-Factor App
A methodology for building cloud-native applications with 12 principles: codebase, dependencies, config, backing services, build/release/run, processes, port binding, concurrency, disposability, dev/prod parity, logs, admin processes.
What is Twelve-Factor App?
In short
The Twelve-Factor App is a set of twelve rules for building web applications that run cleanly on cloud platforms like Heroku, AWS, and Kubernetes. It tells you to keep config out of code, treat your app as stateless processes you can throw away and restart, store state in attached backing services, and ship logs to stdout, so any copy of the app can scale horizontally and deploy without surprises.
What it actually is
The Twelve-Factor App is a methodology written by engineers at Heroku in 2011, based on what they saw across thousands of apps deployed on their platform. It is not a framework or a library you install. It is twelve principles you follow so your app behaves predictably on cloud infrastructure that can start, stop, and move your processes at any moment.
The twelve factors are: one codebase tracked in version control with many deploys; explicitly declared dependencies; config stored in the environment; backing services treated as attached resources; strict separation of build, release, and run stages; running the app as stateless processes; exporting services via port binding; scaling out through the process model; fast startup and graceful shutdown (disposability); keeping development and production as similar as possible; treating logs as event streams; and running admin tasks as one-off processes.
The common thread is that the app makes no assumptions about the machine it runs on. It does not write to local disk for anything it needs to keep, it does not read a config file baked into the build, and it does not depend on a server staying up. That is what lets a platform run twenty identical copies behind a load balancer and replace any of them without you noticing.
How the key factors work in practice
Config in the environment is the factor most people get wrong first. Database URLs, API keys, and feature flags live in environment variables, not in a settings file committed to git. The same build artifact then runs in staging and production unchanged, with only the env vars differing. This is why you set DATABASE_URL in your hosting dashboard instead of editing a .env file you commit.
Stateless processes and backing services go together. Your web process keeps nothing important in memory or on local disk between requests. User sessions go to Redis, uploaded files go to S3, and rows go to Postgres. Each of those is a backing service attached by a URL in config, so you can swap a local Postgres for Amazon RDS by changing one variable with no code change.
Disposability and the process model are what make scaling cheap. Because every process is stateless and starts in a few seconds, the platform scales by running more copies (horizontal scaling) rather than buying a bigger box. Graceful shutdown means a process catches SIGTERM, finishes its current request, and exits, so a deploy or autoscale event never drops work in flight.
Logs as event streams means the app writes plain lines to stdout and never manages log files itself. The platform captures that stream and routes it to a tool like Datadog or an ELK stack. The app does not know or care where its logs end up.
When to use it and the trade-offs
Follow the twelve factors when you are building a long-running web service or API that you want to deploy continuously and scale horizontally on a cloud platform or a container orchestrator. It is the default expectation for anything running on Heroku, AWS ECS, Google Cloud Run, or Kubernetes, and most of the factors map directly to how those platforms want apps to behave.
The trade-offs are real but small. Pushing all state into backing services means more network calls and more moving parts to operate, so a tiny internal tool that one person runs on one server gains little from the full discipline. Strict statelessness also rules out keeping a large in-memory cache local to the process, which can hurt latency unless you add a shared cache like Redis.
The factors also predate containers and serverless, so a few feel dated. Port binding and the process model assume a long-lived process, which does not map cleanly onto AWS Lambda where the platform handles concurrency for you. Treat the twelve factors as strong defaults rather than law, and you will still get the main payoff: deploys that are boring and apps that scale by adding copies.
A concrete example
Picture a Node.js API for an online store. The codebase is one git repo. Dependencies are pinned in package.json and package-lock.json, so npm ci builds the exact same tree every time. There is no hardcoded database string anywhere; the app reads process.env.DATABASE_URL and process.env.STRIPE_SECRET_KEY at boot.
It runs as a stateless web process listening on the port given in process.env.PORT. Sessions live in Redis, product images live in S3, and orders live in Postgres, each attached by a URL. To handle Black Friday traffic, the platform runs forty copies of that same process behind a load balancer instead of one large server.
When you deploy, the platform builds the artifact once, combines it with the production config to make an immutable release, then runs that release. If a copy needs to move to another node, it gets SIGTERM, finishes its in-flight requests, and exits in under ten seconds. Database migrations run as a one-off admin process against the same release, not as a special script with its own config. Logs stream to stdout and get shipped off to a central viewer. Nothing about the app depends on which machine it landed on.
Where it is used in production
Heroku
Created the methodology and built its entire platform around it; every Heroku dyno is a stateless twelve-factor process configured through env vars.
Kubernetes
ConfigMaps and Secrets, liveness probes, and pod replicas map almost one to one onto config-in-environment, disposability, and the process model.
Amazon Web Services
ECS and Elastic Beanstalk expect stateless containers that read config from the environment, store state in RDS and S3, and emit logs to CloudWatch.
Google Cloud Run
Runs stateless containers that bind to a port from the PORT env var and scale to many identical instances on demand, which is the process model and port binding directly.
Frequently asked questions
- Why keep config in environment variables instead of a config file?
- Because the same build artifact should run unchanged in dev, staging, and production, with only the environment differing. If config is baked into a committed file, you cannot reuse one build across environments, and secrets like API keys end up in git history where they leak.
- What does stateless mean here, and where does my data go?
- Stateless means the process keeps nothing important in memory or local disk between requests, so any copy can be killed and replaced safely. Persistent data goes to attached backing services: rows in Postgres, sessions and cache in Redis, files in S3.
- Are the twelve factors still relevant with containers and serverless?
- Mostly yes. Containers and Kubernetes match the factors closely. Serverless like AWS Lambda bends a couple, since the platform handles concurrency and process lifecycle for you, so port binding and the process model matter less. The config, statelessness, and logging factors still apply everywhere.
- How is the build, release, run separation different from just deploying?
- Build turns code into an artifact, release combines that artifact with the current config into an immutable, numbered bundle, and run executes it. Keeping them separate means you can roll back instantly to a previous release and you can never change code at runtime, which makes deploys reproducible.
- Do I have to follow all twelve factors?
- No. They are strong defaults, not a checklist you must pass. For a long-lived cloud web service, following them all pays off. For a small internal tool on a single server, the full statelessness and backing-service discipline buys you little, so apply the factors that fit.
Learn Twelve-Factor App hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
See also
Related glossary terms you might want to look up next.
Docker
A platform for packaging applications into lightweight, portable containers. 'Works on my machine' becomes 'works everywhere.'
Microservices
An architecture where an application is split into small, independent services that communicate over the network. Each service owns its own data and can be deployed separately.
Serverless
A cloud execution model where the provider manages all infrastructure and you pay only for actual compute time. AWS Lambda, Vercel Functions, and Cloudflare Workers are serverless.
Virtual Machine
A software emulation of a physical computer running its own OS on shared hardware. Heavier than containers but provides stronger isolation.
Hypervisor
Software that creates and manages virtual machines by abstracting physical hardware. Type 1 (bare-metal) runs directly on hardware; Type 2 runs on an OS.
Cloud Region
A geographic area containing one or more data centers (availability zones). Choosing the right region reduces latency and satisfies data residency requirements.