DEV Community

Atlas Whoff
Atlas Whoff

Posted on

The 12-Factor App in 2025: What Still Applies and What's Changed

The 12-Factor App Was Written in 2012

Heroku's original 12-factor methodology is still widely referenced. Some factors are timeless. Others need updating for container-first, serverless, and cloud-native development.

Here's an honest look at each factor in 2025.

The Timeless Factors

I. Codebase

One codebase tracked in version control, many deploys.

Still true. One repo, multiple environments (staging, production) via branches or tags.

git flow: main → production, develop → staging
# Or trunk-based: main → production directly
Enter fullscreen mode Exit fullscreen mode

II. Dependencies

Explicitly declare and isolate dependencies.

// package.json: explicit versions
{
  "dependencies": {
    "express": "4.18.2",
    "prisma": "5.7.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Docker extends this: FROM node:20-alpine pins the runtime too.

III. Config

Store config in the environment.

// Never:
const apiKey = 'sk-prod-abc123';

// Always:
const apiKey = process.env.STRIPE_SECRET_KEY;
Enter fullscreen mode Exit fullscreen mode

Now validated with Zod at startup — smarter than raw process.env.

IV. Backing Services

Treat backing services as attached resources.

// Database, Redis, S3 — all via URL
const db = new PrismaClient({ datasources: { db: { url: process.env.DATABASE_URL } } });
const redis = createClient({ url: process.env.REDIS_URL });
const s3 = new S3Client({ region: process.env.AWS_REGION });
Enter fullscreen mode Exit fullscreen mode

Swap prod PostgreSQL for local by changing one env var. Still essential.

X. Dev/Prod Parity

Keep development, staging, and production as similar as possible.

Docker Compose makes this achievable:

# docker-compose.yml
services:
  app:
    build: .
    environment:
      DATABASE_URL: postgresql://postgres:password@db:5432/myapp
  db:
    image: postgres:16  # same version as production
  redis:
    image: redis:7      # same version as production
Enter fullscreen mode Exit fullscreen mode

Factors That Need Updating

V. Build, Release, Run

Strictly separate build and run stages.

Docker multi-stage builds automate this:

# Stage 1: BUILD
FROM node:20 AS builder
RUN npm run build

# Stage 2: RELEASE + RUN (immutable image)
FROM node:20-alpine
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]
Enter fullscreen mode Exit fullscreen mode

The image tag IS the release. myapp:v1.2.3 is immutable.

VIII. Concurrency

Scale out via the process model.

Originally: run multiple Unix processes. Now: run multiple containers/replicas.

# Kubernetes
replicas: 5
# or auto-scale based on CPU/memory
Enter fullscreen mode Exit fullscreen mode

Serverless takes this further—scale to zero, then to thousands.

IX. Disposability

Fast startup, graceful shutdown.

// Graceful shutdown is more important than ever
process.on('SIGTERM', async () => {
  await server.close();     // stop accepting new connections
  await prisma.$disconnect(); // close DB connections
  await redis.quit();        // close Redis
  process.exit(0);
});
Enter fullscreen mode Exit fullscreen mode

Kubernetes sends SIGTERM before killing containers. Handle it.

Factors That Need New Thinking

XI. Logs

Treat logs as event streams.

Original: write to stdout, let the platform handle it.

Now: structured logs + distributed tracing:

import pino from 'pino';
const logger = pino({ level: 'info' });

// Instead of: console.log('Payment processed for user', userId)
logger.info({ userId, orderId, amount }, 'Payment processed');
// Logs are queryable JSON, correlatable with trace IDs
Enter fullscreen mode Exit fullscreen mode

XII. Admin Processes

Run admin/management tasks as one-off processes.

Migrations as one-off jobs before deployment:

# Kubernetes Job for migrations
apiVersion: batch/v1
kind: Job
metadata:
  name: migrate
spec:
  template:
    spec:
      containers:
      - command: ["npx", "prisma", "migrate", "deploy"]
Enter fullscreen mode Exit fullscreen mode

What 12-Factor Misses in 2025

  • Observability: Logs alone aren't enough—you need metrics, traces, and structured errors
  • Security: Secrets management (Vault, AWS Secrets Manager) beyond env vars
  • GitOps: Infrastructure as code, deployment via PR review
  • Service mesh: mTLS, circuit breakers, traffic shaping between services

The 12-factor app is a foundation, not a ceiling. Use it as a checklist, then layer modern practices on top.


12-factor patterns baked into the architecture: Whoff Agents AI SaaS Starter Kit.

Top comments (0)