Category: engineering

12 factors of modern SaaS

TL;DR: it’s a guide with best practices for any engineer who builds & deploys SaaS, based on experience working and scaling many apps on Heroku platform.


In the modern era, software is commonly delivered as a service: called web apps, or software-as-a-service. The twelve-factor app is a methodology for building software-as-a-service apps that:

  • Use declarative formats for setup automation to minimize time and cost for new developers joining the project;
  • Have a clean contract with the underlying operating system, offering maximum portability between execution environments;
  • Are suitable for deployment on modern cloud platforms, obviating the need for servers and systems administration;
  • Minimize divergence between development and production, enabling continuous deployment for maximum agility;
  • And can scale up without significant changes to tooling, architecture, or development practices.

The twelve-factor methodology can be applied to apps written in any programming language and use any backing services (database, queue, memory cache, etc.).

I. Codebase

One codebase tracked in revision control, many deploys. One app, one codebase. Each component maps to one app (or service) in a distributed system.

One codebase maps to many deploys

II. Dependencies

Explicitly declare and isolate dependencies. Never depends on implicit system-wide packages. Declare all dependencies completely and exactly. Use a dependency isolation tool (virtualenv for Python) to prevent leaks or dirty dependencies.

III. Config

Store config in the environment. Dev, staging, production environment should have different configs. Separate config from code.

IV. Backing services

Treat backing services as attached resources, i.e., local and third-party services can be used interchangeably. Resources can be attached/detached at will.

A production deploy attached to four backing services.

V. Build, release, run

Strictly separate build and run stages. Restrict changes to the code at runtime.

Code becomes a build, which is combined with config to create a release.

VI. Processes

Execute the app as one or more stateless processes. Processes are stateless and share-nothing. This will allow the app to scale horizontally. Any data that needs to persist must be stored in a stateful backing service, typically a database.

VII. Port binding

Export services via port binding. The app is completely self-contained and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app exports HTTP as a service by binding to a port and listening to requests coming in on that port.

VIII. Concurrency

Scale-out via the process model. In the twelve-factor app, processes are a first-class citizen. Processes in the twelve-factor app take strong cues from the Unix process model for running service daemons. Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a process type. For example, HTTP requests may be handled by a web process, and a worker process handles long-running background tasks.

Scale is expressed as running processes, workload diversity is expressed as process types.

IX. Disposability

Maximize robustness with fast startup and graceful shutdown. App processes are disposable and can be spun up / spun down easily. App on shutdown should exit gracefully, such as returning job to the queue or closing existing connections upon receiving SIGNTERM.

X. Dev/prod parity

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

XI. Logs

Treat logs as event streams. The app never concerns itself with routing or storage of its output stream. On localhost, it can be just stdout. On a production system, the streams are captured by a log system.

XII. Admin processes

Run admin/management tasks as one-off processes.

One-off admin processes should be run in an identical environment as the regular long-running processes of the app. They run against a release, using the same codebase and config as any process run against that release. Admin code must ship with application code to avoid synchronization issues.



From F to A+

TL;DR: this post is about how I improved my site HTTPS rating from F to A+ .

Make HTTPS great again.

Not all HTTPS-enabled sites are created equally, so welcome to the Internet of broken protocols and pardon my usage of a political phrase.

When I set up this site long ago, it was running on VPCs with many components which with today’s standards, were considered vulnerable: OpenSSL 1.1.0g, PHP5.4, Apache2.1 on Debian 7. You named it.

That’s why used to rate my site as F:




It’s rated A+, and I’m pretty proud of it.



Here are the detailed steps on how I improve my site security from F to A+ in few simple steps.

1. First thing first: bye-bye to outdated OpenSSL

The previous version of openssl on Debian was suffering from these 2 critical vulnerabilities: SSL Pulse (CVE-2014-0224) & Padding Oracle (CVE-2016-2107). That’s the reason why SSLLab report an F.

The fix was fairly simple: upgrading OpenSSL.

sudo apt update && sudo apt upgrade openssl libssl-dev

After that, check the version:

openssl version
OpenSSL 1.1.1d  10 Sep 2019

2. No more outdated ciphers

SSLLabs also reported another two issues which cap the grade at B:

  • “This server accepts RC4 cipher, but only with older protocols. Grade capped to B”
  • “This server does not support Forward Secrecy with the reference browsers. Grade capped to B.”

Ok, onto finding Apache2 config files:

# assuming Apache2 is at /etc/apache2 
grep -i -r "SSLEngine" /etc/apache2
/etc/apache2/sites-available/default-ssl.conf:   SSLEngine on
/etc/apache2/sites-available/  SSLEngine on

Here we go, the config files are default-ssl.conf and From there, I decided to remove RC4 due to its flaws, and then enable Forward Secrecy in the config files:

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on

After that, restart Apache2 and recheck

apachectl -k restart

3. Why stop at A when you can get A+?

At this step, ssllabs rated the site as A, which is pretty good result. But I figured I can get to even better result A+ and being me, I wouldn’t stop. So the next step, is to enable HSTS:

I opened up the Apache2 config files and add this HSTS header:

Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"

Feel free to read up about HSTS if you’re curious.


After everything, the site is now rated as an A+ result. I’m pretty happy about it and a bonus is that the site also loads 45% faster. So, strongly recommend you give it a try: and let me know what score do you have?


Support for Keyboard Shortcut to Close Chrome tabs

A quick guide to fix issue with my “Keyboard shortcuts to close Chrome tabs” extension


Unable to use the shortcuts anymore, or unable to open the Options page:

error message


Right click on Chrome menu bar > Manage extensions. Look for the name “Keyboard shortcut to close Chrome tabs” (yes, I could choose a shorter name), make sure it is not corrupted. Here is an example of a corrupted extension:


If it is corrupted, click the Repair button. Expected to see:

Now reload Chrome and retry.

Root cause

An error while Chrome was trying to restore your profile settings, or a corrupted file system might cause this issue. In my case, it was when I switched from my Mac to my Windows machines, Chrome failed to restore all the installed extensions.