12-Factor App: Principles and Modern Cloud-Native Application
Fast recall
Quick revision
Core answer
@ConfigurationProperties + env vars, package as fat JARs or containers, emit logs to stdout (not files), use Kubernetes for process management and scaling, Flyway/Liquibase for schema. Modern additions (Beyond the 12): API versioning, telemetry/observability, authentication as service, multi-tenant awareness.Cloud-native fundamentals, ability to map principles to real code/infra
Reciting factors without showing how they map to actual Spring/K8s practices
Discuss 'Beyond 12 Factors', trade-offs (e.g., stateless vs performance caching), CNCF patterns
Interview-ready guide
Interview answer
The 12-Factor App is a methodology codified by Heroku in 2011 for building SaaS applications that are easy to deploy, scale, and operate in the cloud.
The twelve factors
- 1Codebase - one repo, many deploys
- 2Dependencies - explicit, isolated
- 3Config - in environment
- 4Backing services - attached resources
- 5Build, release, run - strict separation
- 6Processes - stateless, share-nothing
- 7Port binding - self-contained, exports via port
- 8Concurrency - scale horizontally via process model
- 9Disposability - fast startup, graceful shutdown
- 10Dev/prod parity - keep environments similar
- 11Logs - event stream to stdout
- 12Admin processes - one-off commands as identical processes
Why 12-Factor exists
- Heroku engineers codified patterns from reliably-deployable SaaS apps
- Goal: apps built once, deployed anywhere, scaled horizontally, managed by simple orchestration
- Predates Kubernetes but reads like a design spec for it
- Modern cloud-native traces back to these principles
Each factor with Java/Spring application
I. Codebase
- One repo per app; many deploys from same codebase
- Git repo; tags/branches for environments, not separate repos
II. Dependencies
- Declare all deps explicitly; never system packages
- Maven/Gradle pinned versions; fat-jar packaging; distroless/JDK base images
III. Config
- Config differing between deploys in environment (env vars)
- application.yml for defaults; @ConfigurationProperties pulls SPRING_DATASOURCE_URL etc.
- Never check secrets into Git
IV. Backing services
- DBs, queues, caches as attached resources, swappable via config
- DataSource URL = dev Postgres locally or RDS in prod; Kafka brokers from env
V. Build, release, run
- Build: compile, test, package (container image)
- Release: artifact + env config = versioned release
- Run: execute release
- CI builds :1.2.3 image; CD promotes to staging/prod; rollback = prev image
VI. Processes
- Stateless, share-nothing; state goes to backing services
- No file-on-disk state; no session-in-memory (use Spring Session + Redis)
VII. Port binding
- Self-contained; exports HTTP by binding to port; no external webserver
- Embedded Tomcat/Netty; server.port from env
VIII. Concurrency
- Scale by more processes (horizontal); atomic scale units
- K8s Deployment replicas; HPA on CPU / custom metrics
IX. Disposability
- Fast startup (seconds), graceful shutdown (flush, close pools on SIGTERM)
- server.shutdown=graceful + timeout-per-shutdown-phase=30s
- K8s preStop hook + terminationGracePeriodSeconds
X. Dev/prod parity
- Same DB engine, same queue; short commit-to-deploy gap
- Testcontainers spins real Postgres/Kafka in tests; avoid H2
XI. Logs
- Event streams to stdout; aggregation = infra's job
- Logback JSON to stdout; Fluent Bit/Datadog ships to log store
XII. Admin processes
- One-off admin tasks (migrations, backfills) as identical processes against release
- Flyway on startup; K8s Jobs using same image + different command
Beyond 12 Factors - Kevin Hoffman + modern
Hoffman's additions
- API first: design contract before implementation
- Telemetry: metrics, traces, structured logs from day one
- Authn/authz: cross-cutting concern early; OAuth2/OIDC, mTLS
Modern 2020s additions
- Security by default: vault secrets, image scanning, SBOM, non-root containers, read-only rootfs
- Multi-tenant awareness: bake into data model + observability from day one
- Idempotency: HTTP idempotency keys, consumer dedup; essential for retries
- Progressive delivery: feature flags, canaries, blue/green
- Cost awareness: resource limits, autoscaling, ephemeral environments
- Graceful degradation: circuit breakers, fallbacks, cached data
Where 12-Factor strains
- 1Stateful services (DBs, brokers) inherently violate 'stateless processes'
- 2In-memory caches for performance violate strict statelessness
- 3Long-running jobs (hours): disposability hard; use checkpoints + idempotent processing
- 4Stateful workflows (sagas, sessions): state in backing service; process stateless
- 5WebSocket servers: external state ideal; sticky connections as trade-off
Putting it together - 12-Factor Spring Boot service
Repo, Dockerfile, CI/CD, manifests all follow the factors
- Maven build → container image with temurin base
- application.yml placeholders for env; secrets from Vault/CSI
- K8s Deployment + HPA for scaling
- Graceful shutdown config in Spring + K8s
- Testcontainers for integration tests
- JSON logs to stdout
- Flyway migrations + K8s Jobs for admin tasks
Trade-offs and when to deviate
Why 12-Factor wins
- Portability: any k8s/PaaS
- Scalability: horizontal built-in
- Maintainability: clear separation
- Observability: consistent stdout + env
Costs
- Lots of env vars painful; use ConfigMaps + Secrets
- Secrets in env visible to pod access; use Vault/CSI/RBAC
- Strict statelessness hurts caches; pragmatic: recomputable caches
- Fast startup vs Java bootstrap cost; AOT (Spring Native), SnapStart
- High-volume stdout can overrun pipes; sample/rate-limit
Anti-patterns
- 1Config in code
- 2Per-env repos
- 3File-based logs (stdout is k8s-native)
- 4JVM memory sessions
- 5DB migrations outside release
- 6Long sync startup (JPA warmup)
- 7Health checks not checking dependencies
When to deviate
- Data services: StatefulSets, PVCs, backup strategy
- ML inference with large models: preload, readiness probe gate traffic
- Legacy: migrate incrementally, logs first
- Monoliths modernizing: externalize config + logs first
Strategic take
- 12-Factor is floor, not ceiling
- Following doesn't make you cloud-native; makes you deployable
- Modern adds observability, resilience, security, FinOps, progressive delivery
- Biggest benefit: onboarding speed; new service understood in 30 min; pipeline boilerplate
- Deviate for good reasons; deviating without knowing = snowflake services
Interview angle
- Don't recite all 12
- Connect principles to real code/infra
- Name factor, explain meaning, give Java/K8s example, note where it strains
Bottom line
- 12-Factor = minimum for cloud-native; modern layers on observability, resilience, security
- Stateless processes + env config + stdout logs = deployable anywhere
- Interview-wise: demonstrate application to real Spring Boot + K8s
12-Factor App: Principles and Modern Cloud-Native Application
Direct Answer
The 12-Factor App is a methodology codified by Heroku for building SaaS applications that are easy to deploy, scale, and operate in the cloud. The twelve factors are: (I) Codebase (one repo, many deploys), (II) Dependencies (explicit, isolated), (III) Config (in environment), (IV) Backing services (treated as attached resources), (V) Build, release, run (strict separation), (VI) Processes (stateless, share-nothing), (VII) Port binding (self-contained, exports via port), (VIII) Concurrency (scale horizontally via process model), (IX) Disposability (fast startup, graceful shutdown), (X) Dev/prod parity (keep environments similar), (XI) Logs (event stream to stdout), (XII) Admin processes (one-off commands as identical processes). For Java/Spring Boot: externalize config with @ConfigurationProperties + env vars, package as fat JARs or containers, emit logs to stdout (not files), use Kubernetes for process management and scaling, Flyway/Liquibase for schema. Modern additions (Beyond the 12): API versioning, telemetry/observability, authentication as service, multi-tenant awareness.
Common Mistakes & Pitfalls
Reciting factors without showing how they map to actual Spring/K8s practices
Check your understanding
Answer these without looking back at the article.
- What breaks in a service that ignores Factor VI (processes should be stateless)?
- How does Factor IX (disposability) interact with Kubernetes rolling deploys?
- Name a realistic case where strict statelessness should be relaxed.
- What does 'Beyond 12 Factors' add and why?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.