design patterns
Twelve-Factor App: Modern Application Design
The Twelve-Factor App methodology provides best practices for building modern, cloud-native applications that are portable, scalable, and maintainable.
Twelve-Factor App: Modern Application Design
TL;DR
The Twelve-Factor App is a methodology for building software-as-a-service applications that are portable across execution environments, scalable without architectural changes, and deployable on modern cloud platforms. Originally developed by Heroku engineers, these principles remain foundational for cloud-native development.
Key Takeaways
- Cloud-native foundation: These principles underpin containerization, Kubernetes, and serverless
- Operations-friendly: Designed to minimize divergence between development and production
- Horizontally scalable: Applications can scale by adding processes, not by modifying code
- Stateless by design: Process state is externalized, enabling resilience and elasticity
- DevOps-aligned: Supports continuous integration, deployment, and infrastructure as code
Why Twelve-Factor Matters
Modern cloud platforms (AWS, Azure, GCP) and container orchestrators (Kubernetes) are built with Twelve-Factor principles in mind. Applications that follow these patterns:
- Deploy consistently across any cloud or container platform
- Scale horizontally without re-architecture
- Recover quickly from failures through stateless, disposable processes
- Enable DevOps practices like continuous deployment and infrastructure as code
Real-World Adoption
Netflix, Uber, and Airbnb all apply Twelve-Factor principles to manage thousands of microservices at scale. Container technologies like Docker and orchestrators like Kubernetes embody these patterns natively.
The Twelve Factors
| # | Factor | Principle |
|---|---|---|
| I | Codebase | One codebase tracked in revision control, many deploys |
| II | Dependencies | Explicitly declare and isolate dependencies |
| III | Config | Store configuration in the environment |
| IV | Backing Services | Treat backing services as attached resources |
| V | Build, Release, Run | Strictly separate build and run stages |
| VI | Processes | Execute the app as one or more stateless processes |
| VII | Port Binding | Export services via port binding |
| VIII | Concurrency | Scale out via the process model |
| IX | Disposability | Maximize robustness with fast startup and graceful shutdown |
| X | Dev/Prod Parity | Keep development, staging, and production as similar as possible |
| XI | Logs | Treat logs as event streams |
| XII | Admin Processes | Run admin/management tasks as one-off processes |
Visual Overview
Deep Dive: Each Factor
Principle: One codebase tracked in revision control, many deploys
A twelve-factor app is always tracked in a version control system (Git, Mercurial). There is a one-to-one correlation between the codebase and the app:
- One codebase per app: If there are multiple codebases, it's a distributed system with multiple apps
- Multiple deploys: Development, staging, production are all deploys of the same codebase
- Shared code: Use libraries (npm packages, Python wheels) for code sharing across apps
┌─────────────────────────────────────┐
│ Git Repository │
│ (Single Codebase) │
└─────────────────┬───────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
┌───────┐ ┌───────────┐ ┌──────────┐
│ Dev │ │ Staging │ │Production│
│Deploy │ │ Deploy │ │ Deploy │
└───────┘ └───────────┘ └──────────┘
Implementation Checklist
□ Codebase: Single repo, multiple deploys via branches/tags
□ Dependencies: Package manifest present, no system dependencies assumed
□ Config: All config in environment variables
□ Backing Services: Services accessed via URLs in config
□ Build/Release/Run: CI/CD pipeline with immutable releases
□ Processes: Stateless, share-nothing processes
□ Port Binding: Self-contained HTTP server
□ Concurrency: Horizontal scaling via process model
□ Disposability: Fast startup (<30s), graceful shutdown
□ Dev/Prod Parity: Docker/containers for local development
□ Logs: stdout/stderr only, no file logging
□ Admin Processes: One-off tasks via same deployment
Common Pitfalls
What to Avoid
- Sticky sessions: Use distributed session stores (Redis, DynamoDB) instead
- Local file storage: Use object storage (S3, Blob Storage) for uploaded files
- Long-running processes: Consider task queues for background work
- Hardcoded configuration: Even "default" values should be environment-driven
- Assuming process affinity: Don't rely on in-memory state between requests
Related Topics
- Prerequisites: What is Enterprise Architecture?
- Patterns: Microservices Overview
- Cloud Implementation: AWS Well-Architected
Quick Reference Card
Twelve-Factor App Cheat Sheet
CODEBASE One repo → many deploys
DEPENDENCIES Explicit declaration & isolation
CONFIG Environment variables only
BACKING SERVICES Attached via URL config
BUILD/RELEASE/RUN Strict separation, immutable releases
PROCESSES Stateless, share-nothing
PORT BINDING Self-contained, export via port
CONCURRENCY Scale out via process types
DISPOSABILITY Fast start, graceful shutdown
DEV/PROD PARITY Same tools everywhere
LOGS Event streams to stdout
ADMIN PROCESSES One-off tasks in same environment
Sources
- 12factor.net - The original methodology
- Heroku Dev Center
- Cloud Native Computing Foundation
- Building Microservices by Sam Newman