Future-proof systems#
Preparation#
Read the following:
Introduction#
- Future-proof system
system that is designed to remain functional, adaptable, and maintainable over time. Change of new hardware and maintaining personal should not significantly affect its operation.
Exercise 8
Look at Designing a future-proof health monitoring system. Which guidelines would you have for this system?
Exercise 9
Do you think mainframe computers are future-proof? Why?

Fig. 5 A pair of IBM mainframes. On the left is the IBM z Systems z13. On the right is the IBM LinuxONE Rockhopper.
CC BY-SA 4.0. By Agiorgio. Source: Wikimedia Commons#
The twelve factors#
- Twelve-Factor App methodology
a methodology for building software-as-a-service applications with portability and resilience in mind.
Following comments based on Twelve Factor commit fcb9858
Codebase#
- codebase
any single repository, or any set of repositories that share a root commit.

Fig. 6 One codebase can be deployed in multiple environments#
one codebase corresponds to a single app.
two apps require two codebases
here we have a distributed system
Exercise 10
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Dependencies#
app declares all dependencies, which results in a deterministic environment, e.g.,
Python
pip install
Ruby
bundle install
usingGemfile
app does not rely on implicit existence of system-wide packages. Dependencies are isolated if possible, e.g.,
Python
virtualenv
app does not rely on the implicit existence of any tools, e.g.,
ImageMagick
orcurl
should be vendored into the app
Exercise 11
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Config#
- config
everything that is likely to vary between deploys
separation
strict separation of config from code
different deployments differ in their configuration
environment variables are better than
config.yml
, becausefiles can be accidentally committed to the repository
files can be scattered in different places
environment variables are language- or framework-agnostic
treat environment variables as granular controls, never group them by environment, i.e., instead of a single
config.js
that contains all the environments, reference environment variables inconfig.js
.
Exercise 12
Imagine a software-as-a-service application that serves multiple customers. Each gets a dedicated instance of the app, and each instance is deployed separately.
Does the following approach follow the config guideline of the twelve-factors methodology? If not, improve it. If yes, explain.
environments:
staging:
DATABASE_URL: postgres://staging-db-url
API_KEY: staging-api-key
production:
DATABASE_URL: postgres://prod-db-url
API_KEY: prod-api-key
Backing services#
- backing service
any service the app consumes over the network as part of its normal operation
e.g., PostgreSQL, RabbitMQ, Dovecot, Memcached, OpenStreetMap etc
each backing service is treated as an attachable resource.
Fig. 7 Backend services are attached using URLs. This makes their replacement convenient.#
Every service can be used as an URL. From the perspective of the deployment, there is no distinction between a self- and externally-managed backend service.
Exercise 13
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Build, release, run#
Distinct stages
build
: transforms into an executable bundle using the dependenciesrelease
: deploys the executable using the configrun
: runs the app in the execution environment
each release is a unique, immutable snapshot that can be referenced
keep
run
minimal, push complexity to thebuild
Exercise 14
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Processes#
app is executed as one or more processes.
app’s processes are stateless and share nothing. This enables convenient horizontal scaling. Each request can be served by any node. The sessions can be stored in Memcached or Redis.
Exercise 15
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Port binding#
an app is completely self-contained, instead of being a module of another service. Example: a PHP app must be started by Nginx. Solution: integrate a web server in your app, e.g., Tornado in Python
Use port binding to route requests to your app. Example your app runs on
localhost:5000
which you use for development. In deployment, the webserver routes the requests to this port.
Exercise 16
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Concurrency#
an app is executed as one or more processes, e.g., PHP as child processes of the webserver started by demand, Java executes a single process, but starts individual threads
apps use unix process model. If the app needs many processes, then all the processes are started using a single point.
Separate different workload types to different processes for scaling
Execution environment manages processes, e.g., systemd, foreman (during development)

Fig. 8 An app divided into three different process types. This allows scaling dependent on the workload type#
Exercise 17
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Disposability#
Processes can be started or stopped easily without impacting the whole applications
e.g., a web server process can be replaced on demand without disrupting the system after an update
Minimize start-up time
minimizes down-time after an update or failover
Graceful shutdown
Web process:
cease to listen on the service port, or send a maintenance message
allow current requests to finish
Worker process:
Return the current job to the work queue, e.g., in RabbitMQ
Tolerance against sudden termination, e.g., hardware failure
e.g., return the requests to the queue and retry, if the service times out
Exercise 18
Does this factor make the system future-proof?
If yes, give a counter example which shows that the system is not future-proof if this factor is not taken into account.
Development/production parity#
minimize the gaps between development, staging and production. Gap examples
time gap: developer’s work takes a long time and is not deployed
personnel gap: developers are not involved in deployment (but ops engineers)
tools gap: developers use local tools, e.g., SQLite instead of PostgreSQL.
Solutions:
use CI/CD
use the same tools as in the production
Logs#
app produces logs as a stream of time-ordered events, e.g.,
text format
one event per line typically
exceptions may span over many lines
unbuffered
use
stdout
orstderr
app is not responsible for routing or storage of logs.
use Splunk for log indexing and analysis
Hadoop/Hive as a general-purpose data warehousing system
these tools can implement anomaly detection
Admin processes#
administrative task processes are separate from business logic processes
admin processes are part of the same environment, i.e., use the config file
Example:
bundle exec thin start
for a web processbundle exec rake db:migrate
for an administration task
Criticism#
Note that the criticism may be directed on a previous version of the methodology. We covered the live version.
this methodology does not mean that monolithic applications are always bad
Further resources#
Patterns of distributed systems
First chapter summarizes general problems of distributed systems. Designing the system with these problems in mind could make the system more resilient and future-proof
API versioning: strategies & best practices
design the API so that it can evolve with backwards compatibility