Most software developers are probably familiar with polyglot programming -- if not by name then by experience. It is the concept of using several different programming languages within an application context, in order to utilize the strengths of each language for different parts of a system’s functional domain, rather than enforcing one specific language across the whole application stack.
The polyglot concept is also commonly found in other parts of the tech stack in the form of polyglot persistence. Like the name suggests, this paradigm introduces several different persistence technologies to support an application and is popularly found in setups where a relational database technology is used for persistence of domain data, while other non-relational database technologies are used for raw statistical data, aggregate analytical data, or simply data that does not benefit from complex relational constraints.
But why stop there? Why not apply the polyglot concept to all aspects of the technology stack? At the very least, as software developers and engineers, we should consider the possibility of a fully polyglot tech stack when designing applications; especially when the systems approach enterprise size, or transition into microservices or similar “system of applications” topologies.
It is easy to fall into a static rhythm when developing software; especially when it comes to web applications, where many projects can (initially) share a lot of similarities in requirements and features. Maybe the following sounds familiar to you (as it does to me):
You experience a few different projects where the same general technologies work seamlessly to create a good product, and you begin to favour these technologies. You favor them to such an extent that whenever you begin a new project, one of the first things you do is evaluating how you might utilize these familiar technologies to achieve the desired goals of the project. You do this even if you know this might not necessarily be how this technology was intended to be used, and it might even require a few “hacks” or illogical design choices. But you are comfortable with the technologies and already have some idea of how to go about implementing oddities.
This “shoe horning” of technologies may very well produce a correct product, but as software developers and engineers we must always consider more than just the fulfillment of a project’s requirement; we must also consider scalability, maintainability, testing etc.
The complete technology stack of any medium complex application generally involves a handful of different elements that must be taken into consideration when designing the system, and it is with these decisions that a fully polyglot stack should take precedence over your familiar technologies.
Force yourself to use some resources to analyse the market and discover technologies that may be more suitable for the project. You may find technologies that saves both time, resources, and complexity - every technology has different strengths and weaknesses. And as an additional bonus, it may also help to diversify your own technical skills by learning new technologies you may not otherwise have considered.
The ever-growing modern software infrastructure landscape these days also makes it much easier to implement more diverse polyglot tech stacks.
The serverless cloud, with IaaS (infrastructure as a service) and PaaS (platform as a service), continues to make architecture and infrastructure configurations more seamless and less cumbersome to maintain. This helps to allocate developer resources into actually writing the software that matters for the application, and makes it much easier to integrate diverse technologies in the cloud.
Diverse technologies also help to advocate powerful but complex design patterns that could be useful for the project’s requirements, but would normally be put aside due to the added complexity of the implementation; paradigms such as CQRS, where separate technology stacks for the read and write model could provide powerful scalability and performance by using technologies that favour fast and dynamic querying for your read model, and different technologies that favour performant data consistency and domain modeling for your complex write model.
An arbitrary example of what may happen when you diversify your tech stack is shown in the figure below. Here, a made-up application exists with a read and write model, initially existing entirely via a SQL database with all aspects of the code domain, analytics, and auditing serviced through Java applications. These are accessed through REST APIs via a React UI.
The counterpart, using a polyglot tech stack, immediately seems much more overwhelming and complex, but for an equally complex domain this may be the better and more performant solution.
The read model becomes more dynamic through the use of GraphQL, and performant with the powerful search engine of Elasticsearch, which also better facilitates auditing and analytical queries. The existing write model is kept as is, where the PostgreSQL database keeps a strong relational data consistency. An event log technology (here Kafka) is introduced for synchronising the two models. And finally, a Redis data source was added for handling data that is not directly related to the domain model but is needed for the application usage, e.g. authorization tokens, session keys etc.
The polyglot solution appears much more complex at first glance, but the codebase may easily become much more maintainable, and logically segregated into the different architectural components. And most importantly, the choices allow for the different technologies to perform the tasks they are best at, making for a more performant overall solution. But it comes at the expense of architectural complexity.
So, would both solutions work? Absolutely. But using a polyglot tech stack may benefit the resulting product in the end, and it could save expensive refactoring and expansion tasks in the future.
Having advocated for how much we should consider a fully polyglot tech stack when we design and develop applications, it is important to keep in mind that there is nearly always an exception to a rule.
Static websites and basic CRUD (create-read-update-delete) applications are often simple enough that diversifying the tech stack can lead to wasted resources and precious time. And in many cases they may not even use more than one or two technologies, further limiting the possibility of even considering diversification of the tech stack. In these projects, polyglot persistence is usually enough to harvest a lot of the advantages of a diverse tech stack, while the rest of the stack follows conventional design or your own comfort choices.
It is also worth considering the additional time and resources that are required when diversifying the tech stack. If you are including technologies with which you have little to no prior experience they will take time to learn and implement. This may not always be applicable with the constraints of your project, e.g. if you are on a tight deadline or budget.
With that said, this should not stop you from considering other technologies than those you are comfortable with, when you design and implement new systems. Always try and consider whether there is a better technology for the task, and avoid the static rhythm.