The Twelve-Factor App is a methodology for building software-as-a-service applications created by Heroku co-founder Adam Wiggins in 2011. It codifies best practices for building cloud-native apps that are portable, resilient, and scalable across modern cloud infrastructure. The methodology emphasizes declarative configuration, stateless processes, and strict separation of concerns across twelve core principles. Originally designed for the PaaS era, these factors remain foundational to microservices, containerized applications, and cloud-native development in 2026—and the project was open-sourced in November 2024 (under CC-BY-4.0) to allow community-driven modernization, with active proposals to add an Identity factor, expand Config beyond env vars, and evolve Logs into full telemetry.
What This Cheat Sheet Covers
This topic spans 18 focused tables and 163 indexed concepts, 100 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: The Twelve Core Factors
The twelve factors form a progression from source control through runtime operations. Mastering all twelve together—not just the obvious ones like Config and Logs—is what produces an app that is genuinely portable, operable, and disaster-resilient.
| Factor | Example | Description | |
|---|---|---|---|
git clone repo && deploy to dev, staging, prod | One codebase tracked in version control (Git), with many deploys—same source code runs across dev, staging, and production with different configurations. | ||
package.json, requirements.txt, Gemfile, pom.xml | • Explicitly declare and isolate all dependencies via a manifest • never rely on system-wide packages • use isolation tools ( virtualenv, bundler, npm install). | ||
DATABASE_URL=postgres://user:pass@host/db | • Store config in environment variables—credentials, resource locators, per-deploy settings • never hardcode in source; strict separation of config from code. | ||
DATABASE_URL, REDIS_URL, S3_BUCKET | • Treat backing services as attached resources—databases, queues, caches, SMTP, APIs via URL/credentials in config • swappable without code changes. | ||
Build: npm run build → Release:v123+config → Run:node app.js | • Strict separation of three stages: Build (code → executable), Release (build + config), Run (execute in environment) • no code changes at runtime. | ||
Stateless web workers; state in Redis/DB, not memory | • Execute app as stateless, share-nothing processes • any data that must persist goes to a stateful backing service • enables horizontal scaling. | ||
app.listen(process.env.PORT) → self-contained HTTP server | • Export services via port binding—app is completely self-contained, embeds HTTP server (Tomcat, Jetty, Puma, Uvicorn) • does not rely on runtime injection of a web server. | ||
web=4, worker=10, clock=1 (process types, scaled out) | • Scale out via the process model—divide work by process type ( web, worker, cron)• run multiple instances of each type • horizontal partitioning for concurrency. | ||
Startup: <3s, Shutdown:SIGTERM → drain → exit | • Maximize robustness with fast startup and graceful shutdown—processes are disposable • handle SIGTERM gracefully, stop accepting new work, finish in-flight requests, clean up resources. | ||
Dev, staging, prod use same OS, same DB, same services | Keep development, staging, and production as similar as possible—minimize time gap (continuous deployment), personnel gap (devs deploy), and tools gap (same backing services). | ||
console.log(...) → stdout → centralized logging (ELK, Splunk, OTEL) | • Treat logs as event streams—app writes unbuffered logs to stdout/stderr• execution environment routes to centralized log aggregation; modern practice extends this to full telemetry via OpenTelemetry. | ||
rails db:migrate, python manage.py shell, one-off scripts | Run admin/management tasks as one-off processes in an identical environment—database migrations, REPL console, data imports—using same codebase, config, and release. |