Load My Code

No frills backup automation

Our Tech Stack

I have been working as a software Engineer since around 2008. In my past 15 years or so of experience, I have never seen a single project fail because of technical debt, bad design patterns or slow running code, but I have seen plenty of failures because of bad business decisions and these include bad processes and architecture choices.

We decided early on to stay away from all the shiny things as we felt complexity is one of the greatest impediments to a software project’s growth and flexibility. We could ship 10 new features in the time required to set up a new kubernetes cluster and we knew very well that if we don’t ship the 10 new features, our competitors will.

Design to last:

Our small team has had good experience with PHP, Node and Java. One of the choices we had on the table was to simply use a Node/Typescript framework and wrap it around a GraphQL server and sell it as soon as possible and the devs would be easier to hire as well since most universities now include Node/JS in their curriculum, so it initially felt like a good business choice. but this also meant we pretty much had to rewrite everything every year as the JS ecosystem hasn’t reached the level of maturity of other mainstream languages. Frameworks and libraries are in constant flux and the code you wrote might end up being legacy code within a week. Maintainability and backwards compatibility are not the main selling points of any JS framework. Our plan is to have slow but sustainable growth and we expect the project to span years or decades.

Hence, we chose PHP and Java, the rate of change introduced in both of these languages is a lot slower when compared to JS. The frameworks hardly change, they are built over well understood engineering patterns that have stood the test of time and the changes they introduce are mostly to abstract away the breaking changes at the language runtime level.

PHP/Laravel was chosen to build the web facing templates and interfaces due to the high development iteration speed that it gives us and Java/Spring is used as the backend for all the heavy lifting. The other reason for choosing Java was security, we somehow did not feel it was safe enough to use JS, as our backend would communicate with customer servers. We did not feel it was right to sacrifice customer security over a bit of development speed. A future developer could write sloppy code in JS or PHP, but it was extremely hard to do so in Java. Java also has ready to use libraries for complex distributed authorization/verification flows and libraries for end-to-end encryption which we intend to use apart from the basic SSL/TLS. The added bonus of using Java was the extreme level of backwards compatibility that it provides. You could take a Java 1.0 jar written 25 years ago and it would run fine under Java 19. Oracle with billions poured into its Java/JVM is extremely fast but the business value we are more interested in is its strong backwards compatibility which would help us spend less time on maintenance and framework upgrades and focus on delivering good features and service to our customers.

Now, if you are wondering, what do we use in the frontend? We use AlpineJS, it is an extremely tiny (no-compile-required)library and is capable of all the patterns we use and might require in our frontend. It has a small API which also means it is less likely to introduce breaking changes over time. We don’t think we require Vue/Svelte or React as we feel drawing a bunch of rectangles on a webpage shouldn’t require a world of added complexity. These frontend libraries would make sense to us if we were building large projects like Google Maps or a web based excel sheet app and we had large teams that required some structure and uniformity. We might change our mind later on this but so far we are doing great without them.

Big Data vs Small Data

If you are confused about all the database choices available in the market and don’t have the experience to make that kind of a decision, The rule for choosing a Database is extremely simple, for the current feature set, you guess the size of data that you would need if you grew 10x every year for the next three years and if everything can fit inside the RAM of a typical bare-metal server now, you close your eyes and choose an RDBMS. In 2022, the most common form factor for a single server is to have 12-16TB of RAM.

We use a replicated MySQL setup for all our database needs, and use an in-memory data grid for all our caching and interprocess communication needs.

Agent

We use an agent to communicate your configuration changes and to schedule and perform backups, we wanted something that is performance-critical, reliable, with security boundaries, parallel, gives us control over memory usage, built with Unicode in mind and has a vast array of libraries that deal with security, networking and I/O chunking, Backup systems are all of these. We also wanted something that produced a single binary with zero dependencies, we did not want to pollute the host system with libraries and deal with bad dependencies.

We decided to go with Rust, it checked all the boxes with the added benefit of everyone in the team knowing it already as most had built some or other side project in Rust.

To summarize, We use PHP for our website and most UI you will see, Java for the backend, billing and security routines, Alpine JS for any interactivity we need, MySQL as the datastore and Rust for our Agent.

We are currently at an early stage and have kept our tech very simple and grounded, we are very flexible to change and we will change as our requirements change or unravel.

(C) 2024 Codologic Pvt. Ltd. #REG: U72900MH2017PTC298460