The 12-Factor App principles are best practices for building scalable, maintainable, and robust software-as-a-service (SaaS) applications. Initially defined by developers at Heroku, these principles guide how to design applications that can thrive in modern cloud environments. Here’s a breakdown of the 12 factors:
1. Codebase
One codebase tracked in version control, many deploys
- Maintain a single source of truth in a version control system like Git.
- Deploy the same codebase across multiple environments (e.g., staging, production).
2. Dependencies
Explicitly declare and isolate dependencies
- Use a dependency management tool (e.g.,
requirements.txt
for Python orpackage.json
for Node.js). - Avoid relying on system-level packages to ensure consistent environments.
3. Config
Store config in the environment
- Configuration should be stored in environment variables (e.g., API keys, database URLs).
- Separate code from configuration to make your application more portable.
4. Backing Services
Treat backing services as attached resources.
- External services like databases, message queues, or caches should be treated as interchangeable resources.
- Use environment variables to define service locations, making it easy to swap providers.
5. Build, Release, Run
Strictly separate build and run stages
- Build stage: Compile code and assets.
- Release stage: Combine build artifacts with config to create a deployable release.
- Run stage: Execute the app in the runtime environment.
6. Processes
Execute the app as one or more stateless processes
- Application processes should be stateless and share nothing (e.g., session data should be stored in a database or cache).
- This allows scaling by adding more processes.
7. Port Binding
Export services via port binding
- The application should self-contain its web server, binding to a port (e.g.,
localhost:5000
) and exposing services over HTTP.
8. Concurrency
Scale out via the process model.
- Applications should be designed to handle workload by spawning multiple processes.
- Use workload-specific processes (e.g., web workers, background workers).
9. Disposability
Maximize robustness with fast startup and graceful shutdown
- Processes should start and stop quickly to support scaling and fault tolerance.
- Ensure the app responds gracefully to termination signals.
10. Dev/Prod Parity
Keep development, staging, and production as similar as possible
- Reduce gaps between environments to minimize deployment issues.
- Sync dependencies, environments, and tools across all stages.
11. Logs
Treat logs as event streams
- Applications should not manage log files directly. Instead, output logs to
stdout
orstderr
. - Use a log aggregation service for analysis and monitoring.
12. Admin Processes
Run admin/management tasks as one-off processes.
- Tasks like database migrations, analytics scripts, or maintenance should be performed as separate processes in the same environment as the app.
Adhering to these principles helps ensure that applications are portable, resilient, and easily managed, particularly in modern distributed or cloud-native architectures.