Your DB and Web server belong physically together

Ariel Keselman
3 min readMar 22, 2016

--

Many web/mobile apps are built as a physically separated three-tier in which the web server is hosted at a different machine than the data server. Google it and you’ll get plenty of figures like the one below:

The typical three-tier architecture

The image is simplistic, usually there are many web servers and many DBs, and load balancers between the different tiers. This architecture is flexible, it allows to separately manage load on web servers and DBs (by upgrading hardware, or installing more of it) and it fits perfect auto-scaling Baas where a group of people manage the DBs and a second group manages the web servers. The architecture is well tested, understood, it is used in many high profile apps, etc.

However I recently had a couple of insights that made me question the effectiveness of the above architecture when using “smart” clients that run their own logic and cache (mobile or SPAs using React, Angular, etc). The insights are these:

  1. Each time a client hits the web server, the web server will hit the DB (or the cache, in which case the web server effectively acts as a DB, I’ll not mention this further). If your web server doesn’t hit the DB then the client shouldn’t have hit the web server to begin with
  2. Web servers are becoming lighter on computational resources. Two reasons for this: logic moving to the client and DB, and usage of more efficient programming languages like Go instead of bloated frameworks like RoR, Django, Spring, MVC, etc.

The implication is that a physically two-tier (logically still three-tier) where the DB and web-server share a common machine becomes a better architecture. An example: I’m running a web server written in Go, after warmup it uses ~9Mb of physical memory. It doesn’t need a cache, since it sits in the same machine as the DB so hitting the DB is cheap. CPU usage? mostly DB. It has to do merges, indexing, searches etc. The web server uses little CPU, it doesn’t even need to generate HTML (done by the client). The DB is bound on disk IO, the web server is bound on network IO (client-server). What would I gain by separating the web server? 9Mb of memory to the DB? at the cost of introducing a network cable in the middle of my system? no thanks.

This is a more forgiving architecture, I can even use GraphQL and not be afraid of unoptimized DB access. It scales just as well as a three-tier, just ignore the web server. In this architecture the web server becomes like a scripting engine to the DB, a thin layer protecting the DB from malicious third party access. And the joy of one less tier, one less network cable…

EDIT: in reddit someone asked about scaling, so here it goes: Load balancing and scaling remains largely the same. When your 2-tier server is not enough, you fire up another identical one (up to some configuration changes like the port they listen on) and put the now 2-computers behind a load balancer. You have to use a DB that knows how to sync, say Mongo, CockroachDB, etcd, or a few others. It’s the same story when using a 3-tier. This is not Baas with autoscaling that is much easier but also usually locks you in the specific Baas you used.

The idea of putting a DB by itself in a computer is that this minimizes the number of DB servers needed (since they run alone, no other program takes their resources) however when using a light web server, you only take a few Mbs of memory from the DB. This will not be the reason for the need to add more DB servers…. the web server is like a fly on the back of an elephant

Feedback welcome!

--

--