$ emrebener
home blogs infrastructure & operations the twelve-factor app 00. what is the twelve-factor app?

00. What is the Twelve-Factor App?

author: emre bener read time: 5 min about: twelve-factor app, software as a service, cloud computing
published: updated: mentions: heroku, adam wiggins, docker, kubernetes, platform as a service, continuous deployment

The Twelve-Factor App is a methodology for building software-as-a-service: web apps and backend services meant to run on a cloud platform, deploy continuously, and scale by adding more copies of themselves. It’s twelve principles covering how an app handles its code, dependencies, config, processes, and logs, and each one is a rule that keeps the app portable and cheap to operate. Read the series straight through, or jump to the factor you need; every one is linked below.

1. Where it came from: Heroku, around 2011

The Twelve-Factor App came out of Heroku. Around 2011, engineers there, with Adam Wiggins as the primary author, wrote down a set of practices they’d distilled from years of running a platform-as-a-service for other people’s applications.

Heroku’s job was to take application code it hadn’t written, in many languages and from many teams, and run it reliably with no human sysadmin assigned to each app. The apps that behaved well under that model kept sharing the same handful of properties, and the ones that fought the platform ran into the same problems. Twelve-Factor is that pattern-matching written down as rules you can apply to your own app before it ever reaches a platform. Because it came from people operating software they didn’t author, it leans toward operability: how an app is configured, deployed, scaled and observed, rather than how its business logic is organized.

2. The problems it set out to solve

Twelve-Factor exists to make an app cheap to onboard, cheap to move, and cheap to scale. Its authors named a few concrete aims:

  • Declarative setup: dependencies, config, and process types declared in a machine-readable form, so onboarding a new developer takes minutes.
  • A clean contract with the operating system (environment variables, a bound port, stdout), which is what makes the app portable across environments.
  • Runs on modern cloud platforms without a dedicated sysadmin babysitting each server.
  • Minimal divergence between development and production, the precondition for continuous deployment.
  • Scaling by running more identical processes, not by re-architecting.

3. Twelve factors, one methodology

The methodology is twelve factors, not one monolithic rule. Each factor is a single concern (code, dependencies, config, and so on), and each stands more or less on its own, so you can adopt them one at a time. Fixing how you handle config doesn’t require fixing how you handle logs first. But they compound: an app that keeps config in the environment and treats its database as an attached resource is also, almost for free, an app you can run identically in development and production.

Two properties hold across all twelve. They’re language-agnostic: the rules are about how an app relates to its environment, not about Ruby or Go or Java, so the same twelve apply whether you’re writing a Django service or a Spring Boot API. And they’re indifferent to your backing services. A backing service is anything the app talks to over the network: a Postgres database, a Redis cache, a RabbitMQ queue, an SMTP server, a third-party API. Twelve-Factor treats all of them the same way, as attached resources you point at with a URL from config.

4. Why it still holds up

Twelve-Factor predates the tools most people now associate with it, yet its core principles describe how a container behaves almost exactly. It was written around 2011. Docker arrived in 2013, Kubernetes in 2014. The methodology didn’t anticipate them; they converged on the same shape it had already described.

Read the runtime factors as a description of a container under an orchestrator and the overlap is hard to miss. A Twelve-Factor process is stateless and exports its service by binding to a port; that’s a container listening on a port, holding no local state it can’t afford to lose. The rest map just as cleanly:

Twelve-Factor principleContainer / orchestrator equivalent
Stateless process bound to a portA container listening on a port
Config from the environmentEnv vars injected by the orchestrator
Logs as an unbuffered stdout streamstdout collected by the platform
Build/release/run separatedImmutable image promoted across environments
Concurrency via the process modelReplica count / horizontal pod autoscaling

That’s why the methodology outlived the platform it was written for. The principles describe the shape of a well-behaved process, and that shape didn’t change when the runtime became a container.

Not everything has aged identically. A few factors read as slightly of their era; Factor 10 (dev/prod parity) predates how easy it now is to run real backing services locally in a container, so its examples feel dated even though the goal is sounder than ever. Later writing has extended the list, too. There’s a well-known “fifteen-factor” variant that adds concerns Twelve-Factor doesn’t cover, like API-first design, telemetry and authentication. You don’t need those extensions to get value here. The original twelve are still the baseline, and most modern additions assume you’ve already met them.

5. The twelve factors, in order

Here are the twelve. The series is written to be read start to finish, since each factor builds on the vocabulary of the ones before it, but every post also stands on its own if you’re here for a specific one.

  1. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/01. Codebase/Index|Codebase]]: one codebase tracked in revision control, many deploys.
  2. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/02. Dependencies/Index|Dependencies]]: explicitly declare and isolate dependencies.
  3. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/03. Config/Index|Config]]: store config in the environment.
  4. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/04. Backing services/Index|Backing services]]: treat backing services as attached resources.
  5. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/05. Build, release, run/Index|Build, release, run]]: strictly separate the build and run stages.
  6. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/06. Processes/Index|Processes]]: execute the app as one or more stateless processes.
  7. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/07. Port binding/Index|Port binding]]: export services via port binding.
  8. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/08. Concurrency/Index|Concurrency]]: scale out via the process model.
  9. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/09. Disposability/Index|Disposability]]: maximize robustness with fast startup and graceful shutdown.
  10. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/10. Dev-prod parity/Index|Dev/prod parity]]: keep development, staging, and production as similar as possible.
  11. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/11. Logs/Index|Logs]]: treat logs as event streams.
  12. [[3-Blogs/Infrastructure & Operations/The Twelve-Factor App/12. Admin processes/Index|Admin processes]]: run admin and management tasks as one-off processes.

Start with Factor 1, Codebase. It’s the simplest of the twelve and the one every other factor quietly assumes: one codebase, many deploys.