DevOps/CI/CD Landscape (Open by click and download for better view).

Every architecture is formed based on certain design principles and Microservices is no different. This article will not talk about what Microservices is all about. There are already plenty of articles and blogs to do that. In this article, I will talk about what it takes to devise a Microservices based architecture. We will take a look at some of the design principles one should take into account to design a Microservices based applications.


Services must be designed to work in isolation. When you break up a monolithic system into set of services, it is necessary that these services are decoupled from one another, are made more cohesive and self sufficient. Each service should be able to handle its failure without breaking the whole application or system. Isolating and decoupling enables service to recover itself from the failure condition very quickly. The isolation characteristic of the service has the following benefits: easy adoption of continuous delivery, better scaling, effective monitoring and testability.


Isolation paves the way for autonomy. Services must be designed to be autonomous. It must be cohesive and able to fulfill its function independently. Every service can be independently invoked using a well defined API (URI). The API in a way identifies the service function. Autonomous service must also deal with its own data. More popular term is polyglot persistence where each service has its own persistence store. Autonomy also ensures resiliency. An autonomous service has the following benefits: Effective service orchestration and coordination, better scaling, communication through well defined API, faster and controlled deployment.

Single Responsibility

Service must be designed to be highly cohesive. A single responsibility principle is where the service performs only one important function. The single responsibility aspect gels well with the term ‘micro’. Micro indeed means small, fine grained and only relevant within its scope of responsibility. The single responsibility feature has the following benefits: Services composition is seamless, better scaling, reusability, extensibility and maintainability.

Bounded Context

How big or small your services should be? Million dollar question? Well the answer lies in what is called as Bounded Context design principal. It is a key pattern while devising a Domain Driven Design (DDD) modeling approach. Bounded context is all about defining a context in which your Microservices will be providing its services. It is about evaluating your domain model and identifying discrete boundaries and accordingly designing your Microservices to make it more cohesive and autonomous. That also means communication across boundaries becomes more efficient and your service in one bounded context need not be dependent on service in another bounded context for too many things.

Asynchronous Communication

While drawing discrete boundaries and designing services with its own bounded context, it is necessary that service communication across boundaries must be asynchronous. The asynchronous mode of communication naturally leads to loose coupling between services and allows for better scaling. With synchronous communication, you are blocking a call and waiting for the response. A service in a blocking state cannot perform another task until the response is received and the underlying thread is released. It leads to network congestion and impacts both latency and throughput. Asynchronous communication can also bring in the notion of implementing a well defined integration or communication pattern to achieve a logical workflow involving different services.

Location Independent

Microservices, by design, are good candidates to be deployed in a virtualized environment or docker containers. With the advent of cloud computing, we can have plethora of service instances that can take advantage of dynamic scaling environment. The services could be running on multiple nodes across small or large clusters. Services itself can be relocated depending upon the availability or efficiency of the underlying computing resource. One must be able to address or locate the service in a location independent manner. Often different lookup discovery patterns can be used to consume your service. The client or consumer of the service does not have to bother about where a particular service is deployed or configured. It just uses some kind of logical or virtual address to locate the service.

Microservices is not a technology, framework or a solution. It is an architectural style that provides you an approach or methodology to deal with the complex nature of a monolithic application. The approach starts with the above design principles that you can use to architect Microservices based application.

Information vs Data (time dependence) (Open by mouse click and download for better view).

Cloud Native Landscape v0.9 (Open by click and download for better view).

There are so many software development languages available these days its hard for many software developers to know which is best for a given application project. What many developers don’t consider is the long term maintenance and support needs of their application as well as the scalability of the application in the long term, if its poorly built from startup using a language that will not be fully backwards compatible in the long term then supporting it and expanding its functionality over time may not be viable.

Another point often neglected is the original purpose of the language and what it was developed for. I have come from an assembly language background, then started using “C”, then moved to C++, Java, PHP and all the current languages, so picking a language for a task is based on years of programming skills and engineering software and hardware systems. The result has been an understanding of the effort required to engineer software and what tools are needed to build maintainable clean engineered solutions.

A closer look at “GO” and Node.JS

The Go language, (often referred to as golang) is a system oriented language, its roots are based on “C” and “C++”, it was developed by Google to solve some really annoying issues when you build software at Google scale. Typical of those issues are building huge applications with lots of dependencies and support for multi CPU operation. It wasn’t written to be a GUI or to execute Javascript code (although Javascript also inherits a lot from “C” and “C++”). At Google scale, concurrent execution, communications, garbage collection and flexible data types are important. So Google developed the language in-house and made it public.

Node.js is also a modern programming language build on top of Google’s Chrome V8 engine (which is written in C++). Node.js is not a GUI application, and it’s promoted as a suitable tool for writing back-end system services, like Go. Node.JS is server side Javascript and since it’s native Javascript that its language base is built on it inherits most front-end JavaScript traits. So all the typical methods, functions and object constructs are present in Node.js.

One interesting issue in Node is its inability to directly Export or Import a Module, to achieve this Node uses constructs from RequireJS and CommonJS. Go provides a project like structure that supports multiple files, libraries and there is a keyword called “import” for importing libraries.

Go is suitable for heavy CPU applications and lots of IO, while Node is geared towards server IO use cases, such as a backend server to a client server AJAX application. In fact Node’s native support for JSON makes building REST / JSON api’s easy and is something Node.js excels at.

Object Oriented?

Unlike C++ and Java, Go does not implement OO concepts the same way, there is no Class construct but it does have an “interface” construct and methods can be defined to operate on a common type. Go implements simple data structures and methods that can operate on them. Node implements what are best described as “pseudo” classes using Prototypal  inheritance. On the face of it, Node would look more like a typical Object Oriented application and many libraries are built using this form of OO programming.

Concurrency and Threads

Node has a non-blocking I/O model that does not implement threads at the language level, although threads are implemented underneath the hood. Non-blocking IO makes Node a great choice for wrapping other data sources such as databases or web services and exposing them via a JSON interface. Its heavily geared for web based IO and its eventing model makes handling multiple connections possible. It achieves this by implementing an event loop at the language level. In Node this works very well and overcomes many issues that threads introduce.

“Goroutines” are what Go implements to make concurrency easy to use. The idea is to multiplex independently executing functions, “coroutines”, onto a set of threads. When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won’t be blocked. As a result, goroutines have little overhead beyond the memory for the stack, which is just a few kilobytes. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.

Node is single threading, it provides an event model using callbacks, but there are no threads in Node that your code runs in. node expects calls to return quickly, realistically if you need some level of concurrent operation then run multiple Node applications and use IO to pass messages between processes.


Node has an active community which has also seen a number of functionality enhancements like JXcoreRequireJS and CommonjS being the most common. There is also “Passport” for authentication, “Blanket” for unit testing, URIjs, pdfkit, aws-lib, LevelDB and ElasticSearch to name just a few. All are geared towards using Node.JS as a backend servicing web clients in one form or another either directly or as a backend service.

Go also has tons of packages, but a glance through all of them appears to cement Go at the system utility development model.


Performance is always a contentious issue, rather than reinvent the wheel I did some research on what others have done, this article on a bubble sort Benchmarks: Nodejs vs GO 1.1 and a further update here Node vs GO 2014 by Jonathan Warner showed a simple effective testing method that drew a lot less “negative” comments than other testing comparisons.

The bottom line was Go out performed Node, the conclusion to this trial could be that Go is native executable code built from the ground up to be fast and compact for huge scale deployment, Node runs on the Google Chrome V8 Javascript engine, so there is an extra layer of code that needs to execute… simple logic tells us that it wil always be slower, but its not significantly slower so the Javascript engine is well written and doing a great job. And don’t forget, in a real application you might have a database layer and other external factors that will impede performance in some way regardless of the operating environment and language choice.

At a glance - Google Go

For those that haven’t done any Go yet, it’s “a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language”. It is backed by Google, and is used at Google, Heroku, and other places.


  • Type-safety
  • Statically-linked compilation which makes deployment extremely easy
  • High concurrency
  • Large core library with components like tar, zip, blowfish, gifs, pngs, templating engines, websocket library are in core
  • Primitives aimed at concurrency - Atomic Channels to reinforce that you should share memory by communicating, instead of communicating by sharing memory. They make it very easy to implement concurrent, scalable solutions without race-conditions.
  • Extremely fast and on par with C for some tasks.
  • Easy to keep up with latest release - The gofix utility makes keeping up with new releases trivial, as it automatically fixes your code
  • Deploys as a single executable binary.


  • Type-safety - Can be tedious such as converting strings to byte buffers, and back.
  • Third-party libraries are third-class citizens - With the focus on a large standard core, third-party libraries have been largely left behind.
  • Lack of community - Possibly due to the community being composed of Google.
  • Naive garbage collection – Some reported performance issues with applications stopping during garbage collection, this may have now been fixed.
  • Focus on doing things ‘the right way’ - This is probably shown most in the ‘gofmt’ utility which automatically formats your code so everyone’s code looks the same. Uniformity is highly prized in the Go community.

At a glance - Node.js

For those that haven’t done any Node.js before, it is “a platform for easily building fast, scalable network applications”. With event-driven non-blocking I/O, it forces an asynchronous ‘callback-passing’ style of development. As a Javascript engine it doesn’t require you to learn any new language or syntax (assuming you already know Javascript).


  • Usage of Javascript is very high already, generally considered “Not perfect, but ‘good enough’”.
  • Large existing community and libraries to draw from. Though most browser libraries aren’t applicable, they do mean there is quite a bit of experience with the language.
  • Homogenous web stack - Less impedance mismatch when moving around the stack. When developing for the web you can use Javascript all the way from the browser to the database.
  • Third-party libraries are first-class citizens
    • The focus is on keeping the core library as small as possible (reverse of Go).
    • Excellent package manager (NPM) included from the beginning. The number of NPM libraries are growing astonishingly quickly.
    • Everything is a package. In Node the prevailing wisdom is to make everything an NPM package. Bouncy (an HTTP Proxy), Forever (a Monit-like process manager), and even NPM itself are all packages which can be required and used programmatically.
  • and JSON – Native support for JSON data and execution.
  • Excellent cluster management tools - dnode,, replicant, cluster to name a few.
  • Focus on isolation of processes and fault-handling - Node’s single-threaded design forces it to be scaled by using lots of isolated communicating processes. This has pros and cons, because while it is initially more difficult, it also helps avoid race conditions, and means that scaling across machines is not much harder.
  • Poor error handling and exception handling resulting in ‘Crash-only software’ for handling serious errors. On the bright side if you write each component of the system in isolated, separate processes, the catastrophic failure of any one component can’t bring down the entire system.


  • Single-threaded - Since Node is single-threaded you rely on forking, and communicating between processes to make use of multiple cores. The upside is that Node sees less difference between multiple core concurrency and multiple machine concurrency.
  • Not ‘proven’ at scale – Lots of blog posts on moving away from Node.JS to Go due to high I/O based performance issues, few blog pages on moving the other way.
  • Callbacks - As Javascript was developed for web pages initially, flow control was not designed for threads so callbacks were implemented as the event model.

Along came Docker

Google Go has had a significant impact in the last 2 years with the development and release of Docker, an application container engine that will revolutionize the application deployment space and cloud computing in general. In fact to cement Go as more the systems level language, Docker’s creator Solomon Hykes cited Go’s standard library, concurrency primitives, and ease of deployment as key factors, and said “To put it simply, if Docker had not been written in Go, it would not have been as successful.”

Production Ready?

Both languages appear “production” ready, with 100′s of documented live deployments and an ever growing user base. From the usage models, most Node.JS deployments appear to be as web server back ends while Go appears to have been deployed in system level applications, mainly by Google and now Docker.

Numerous companies have made the switch from Node to Go citing:

  1. Performance improvements as the #1 core reason.
  2. The callback model in Node is cited as “Hell” in large applications.
  3. Large CPU overheads in high I/O output scenarios especially with string outputs back to web clients.

Summary – Since Go compiles down to executable code and Node is running inside the V8 Javascript engine some performance issues are bound to crop up.

Wrapping up - Some thoughts from various communities

I like this one – “In short, Go feels like it is what C would be like if it were developed today.”

and this rather good comparison -

“There are a few key differences. Node.js has a rabid, and rapidly growing community, tons of third-party libraries, and an extremely pragmatic focus. Google Go has a large, complete set of core libraries, an easy path to high concurrency, and is blazingly fast. Go also has a focus on the ‘correctness’ of the solution (evidenced by it’s type-safety) and it’s community prizes uniformity, emphasising doing things the idiomatic way. The Node community tends to be more focused on the functionality, and are more tolerant of doing things in different and unique ways (e.g. Javascript vs Coffeescript).”