My Journey From a Freelance Developer to a Fractional CTO

journey from freelance developer to fractional cto CTO

My Journey From a Freelance Developer to a Fractional CTO

I have been working as a freelance developer since 2017. Last year, I moved to tech lead roles such as software architect, tech lead, and fractional CTO. I have never planned to shift to tech lead roles, because I thought it’s too stressful. I was wrong and I want to share with you how to get there and when it’s a good idea to move to tech lead positions.

First Years as a Junior Developer

Let’s start from the beginning. Why do you want to become a freelance developer? When I graduated from university I was eager to learn new technologies. I made a list of local tech companies and was hired at a company that was at the top of my list. Success!

I thought I can learn a lot from senior developers and that way I can grow as a developer. After several months, I found out senior engineers didn’t want to learn anything new and were pushing management to use only old technologies they are comfortable working with. It turned out it was not a good approach because requirements for modern web apps are hard to achieve with old frameworks. I believe project requirements is important aspect for choosing specific technology and developers shouldn’t be too religious about specific frameworks. If we consider simple projects, it doesn’t really matter, but this doesn’t count for complex platforms at tech companies.

I didn’t grow as a developer thanks to senior engineers but thanks to my curiosity and willingness to work on challenging problems and learning new things. There were too many incompetent people at that company. After several months, I knew I was at the wrong place and I needed to escape. When I talked to some of my friends they told me the same issues at companies they were working at. I knew I wouldn’t be happier at another local company.

I got an idea to work remotely as a freelance developer. I came across blog posts about remote work and some remote friendly companies. I thought I should try it out. I knew I needed to specialize in a tech stack to be able to provide customers the complete solution from back-end to front-end. I really enjoyed working on the front-end in React. For this reason I chose Node.js for back-end development.

I was still employed at a local company. Over time, I solved some technical challenges and my opinions were given more importance. It was in 2015 and it was the beginning of React. Senior back-end developers didn’t like Javascript and told me that React is just hype and it would disappear soon. My manager listened to me what tech stack to use for a new project. That was my opportunity to get good experience in my preferred tech stack including React. Then, I worked for another local company, but after one year I left.

First years as a Freelance Developer

I created my personal website, wrote some blog posts, applied to freelance networks, applied to some freelance jobs and it worked! I got my first freelance project and started working on an exciting project. First two years I learned a lot from my mistakes. Over time, I was getting better projects and I had the opportunity to work with talented engineers. I was working on complex projects in big teams, where I learned a lot and was growing as a developer.

Shifting from Junior Developer to Senior Developer

I didn’t work on projects in one specific domain. I was working on various projects with various challenges and learned a lot of patterns and good practices for specific use cases. At that time I was thinking this is so great, it sounded like a dream.

For some reason, it was challenging for many companies to find experienced React developers. As I was enjoying React, I was getting more projects in React and learned about various libraries and patterns around the React ecosystem.

I became a React expert. I think you can consider yourself an expert in a particular technology if you teach other senior developers best practices, patterns, how to use it, etc. I came across many senior React developers who had more years of experience in React than me. However, I had more years of experience as a freelance developer. I was working on more projects and technical challenges in various domains. For this reason, I have a better experience and I was teaching other senior React developers.

Over time, React and front-end development were too easy for me. For some time, I didn’t come across many technical challenges and wanted to work more on full-stack developer positions. As I was growing as a full-stack developer I noticed a lot of mistakes other full-stack devs were making.

It blows my mind that many developers don’t know fundamentals in coding and structuring code. Things such as avoiding monoliths and breaking down code in smaller pieces, not making too many overrides, preliminary optimizations, not reinventing the wheel, etc. I feel like I see the same basic mistakes in almost every project.

On the other hand, I came across a developer who has no formal education in software engineering. He is a self-taught developer and his code is very well structured. I asked him how he learned that because it’s very unusual. He told me he worked with really good engineers and learned from them.

Before I started working as a freelance developer, I would never say I would work on a project for big tech companies such as Apple or Binance. I am so grateful for this opportunity and experience working with talented people.

Shifting from Senior Developer to a Tech Lead

At the beginning of every project, managers and other engineers were considering me as another developer. As I was educating other developers about best practices, patterns, etc I was getting the most challenging tasks. Formally, I wasn’t titled as a lead developer but I felt like that. What changed at this point was that I was not working on product development and its technical challenges, but I was helping the whole team to solve various challenges in such a way that the project can progress much faster. I don’t know why, but for me it was more fun to work on challenges that other devs didn’t know or didn’t want to solve.

At this point, I thought it could be interesting to try tech lead roles such as software architect or fractional CTO. I knew it’s a big difference to work as a CTO on a project with less than 5 developers and 10+ devs. From what I remember from big projects with 10+ developers, CTO had a lot of meetings, they were prioritizing and assigning tasks. I knew I am not experienced enough for such a role in a big team.

I got my first role as a fractional CTO and I faced different kinds of challenges. I worked closely with a product manager who didn’t have any experience with software products. I needed to help and teach them how to manage software products. I needed to work on important things that other devs didn’t want to do, such as setting up infrastructure and a CI pipelines. I needed to review the code to be sure that we wouldn’t accumulate technical debt. Another aspect was setting up additional necessary tooling and integrations such as admin panel, email provider, etc. The CEO wanted me to commit part-time because of their limited budget. First two weeks, it was really hard to balance all these things to finish everything within part-time commitment. After the first month, there was less amount of work I needed to finish and there was more time to implement some new features. When the development process and infrastructure were settled, the CEO found my replacement with lower compensation. My first fractional CTO project ended successfully.

I got another exciting opportunity as a software architect. What was interesting about this project was that they were looking for somebody who knows how to scale the project and fix performance. They were expecting to grow the number of users from 50k to 1mil and didn’t really know if their infrastructure could handle such a big number of users. The code structure was really bad, but I was able to make some optimizations that had a big impact on performance.

Just to give a better idea what were my tasks as a software architect for a growing startup:

The main issue of this project was ad-hoc crashes and it was hard to figure out the root cause. I suggested adding an APM platform that would help us to get better visibility of what was causing the app crashes and why the performance is so bad. Adding an APM platform was pretty easy. I just needed to add additional metadata to spans and set performance dashboards to detect and diagnose end-users’ experience with mission-critical services.

Another task was to run load tests for some user flows and find out how the project performs if thousands of users log in within a minute. I found the best tools for this task are JMeter, Clinic.js profiler and autocannon. The project was running on Heroku and a its back-up was running on AWS. When I ran load tests I found out that the project running on AWS had much better server throughput than the project running on Heroku. In both cases I used similar server configuration.

My another task was to improve login performance. It took users around 13 seconds to log in. I have never seen something like this before. Thanks to checking the whole flow in APM, I noticed that users were redirected seven times to get from the login page to their homepage. The project used a framework for SSR that is not very common and not well documented. When I eliminated redirects, login flow took 2 seconds instead of 13.

Another task was optimising server throughput. I found we can improve server throughput by eliminating excessive api calls. In this project they used server side rendering where the client project had its own web server. The back-end logic was implemented in the api server. They used Launchdarkly for managing feature flags. Launchdarkly was initialised in the api server. If a client wanted to get a feature flag, it made an api call to the api server. Some views and pages made a lot of api calls because of getting feature flags state. I was thinking: what if we fetch all feature flags on the client and notify the client if a flag state is changed? A lot of services and platforms provide a webhook if some data changes. I checked launchdarkly documentation tofind if it has a webhook for notifying changed feature flag. There is just one small issue where ad block browser extensions block launchdarkly. In this case, we can initialise launchdarkly in the web server and use EventSource to notify the client if a flag was changed.

Another optimization was improving performance for search functionality in Mongo Atlas. There was a collection with around 1mil records. The team decided to add a default date filter to search on smaller data set to make search functionality fast. My task was to make it performant without the default date filter. When I tried to use the text index, the query wasn’t performant enough and it took around 7 minutes to get the search result. Previously, another developer set search index, but search functionality didn’t work well. The search text operator uses fuzzy.maxEdits option that you cannot turn off and for this reason users didn’t get expected results. When I did a bit of research on how to fix this, I found it’s possible to use phrase search. I updated the query a bit and search functionality worked as expected and was performant for 1mil records within seconds.

Heroku is definitely not a good option for a project that needs to scale and be optimised. For example Heroku doesn’t support HTTP2 protocol. The project uses AWS Route53 for managing DNS. Redirecting the root domain to Heroku is possible only by CNAME record. The issue is that AWS Route53 doesn’t support redirecting the root domain through CNAME record and for this reason it’s possible to do this only by using Cloudfront distribution. Another option is using a Heroku plugin for assigning static api address, but these plugins are extremely expensive for a project with higher traffic. We also couldn’t optimise TLS and SSL handshake because there is no way to access reverse proxy settings.

To be able to do the above tasks I needed to update node.js and apollo versions in a pretty large project. Another example is setting linting and formatting. It’s always very surprising to join a project with no formatting configuration.

By these examples, you can see what were the kind of tasks of software architect or fractional CTO. If you want to move a tech lead role, the best you can do is to work on the most challenging tasks. As you can see these kinds of challenges are not in regards to product development, but they are related to setting up processes and making optimisations. If you are working on tasks that other senior engineers are not able to or don’t want to do, then you should definitely consider moving to a tech lead role.



Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: