The tech industry hates people that work in it— some ideas about how we could do better
Almost everyone I know in tech does not think of tech the way that I do.
And most people I know in tech would do something else, if the money was better.
Most people seem to hate their job in some way. Not the people, but the job, the pressure, the stress, and the constant nature of that stress.
I’ve been involved at senior and leadership level in developing or supporting the development of many many applications for companies and organisations ranging from the very small to very large including for Governments and some of the largest orgs in the world.
I’ve been doing this at this level for around 2 decades.
I’ve learned a huge amount about what should be done and what should not be done. If there’s one thing I can tell you, it is that I will change my mind again about what I write here at some point in the future, because tech does not stand still.
Maybe there’s a way to put some principles in place that can improve how we do tech that benefits the people that work in it, and still delivers the necessary solutions.
Here are some principles, or guidelines maybe, that I think can help do this:
Principle: Know what the need is
This may seem to be obvious, but it’s not.
The idea of “customer need” or similar is in pretty much every project/product management mantra/framework/practice I can think of.
But there is a difference between thinking you understand your customer‘s needs and actually knowing that the customer has that need.
It’s much much harder to know.
“What the need is” is almost always ignored, or considered to be “clear and unambiguous”, until well after development of any solution has started.
Very few people in tech actually do this properly.
Everybody says they do this, but what most people actually do is guess, or assume the need from their own bias, or from minimal interaction with very few customers.
Identifying needs properly takes a huge amount of effort. Much more than most companies put in, and often the effort put in is expended in an attempt to confirm the bias that already exists.
Building the wrong thing can be very demoralising. Start here if you want to make people who work for you happy.
If you cannot clearly identify a customer need, then you cannot define the solution that you need to create to meet that need, and you shouldn’t start anything until you do.
Principle: Meet the need as simply as possible
You wouldn’t believe how obvious this is either, and how often this is either missed, or what happens more often, the solution that is created is far more complex than the need is, and can create additional needs that were not there to start with.
An example is useful here:
At one of my previous startups, the marketing team were struggling to get the right data out of our analytics. So I sat down with the Head of Marketing (one of the other 4 people in the startup) and worked out exactly what they needed. They needed CSV files corresponding to a specific set of queries of the data. They needed these CSV files every morning and they needed to correspond to the previous midnight to midnight (UTC+0) timespan. In previous startups, I would likely have provided them with a simple web interface, with a username and password and everything else that goes with it (which would have been relatively easy to do but a pain to maintain). However, we were already using slack, so I created an AWS Lambda function to generate the previous 24 hours data on a schedule during the early hours, and saved the data into S3. I then sent the data in S3 in a slack message to a slack channel only available to the Head of Marketing and myself. He then downloaded it every morning into Excel. This was our marketing process for extracting data from analytics for 18 months with only minor tweaks to the queries needed over that time. The Head of Marketing was ecstatic because it was immediately available to him every morning and he could do whatever he wanted via Excel without worrying about deleting data on a shared drive or similar because it was saved and in S3. It could also be recreated without issue if needed.
This is an example of meeting the need, and only the need.
Maintaining that solution was very straight forward. The amount of code was limited and there was no running server. The Head of Marketing could get his data every day and could even leave it a few days if needed because the data didn’t get deleted (until archived months later). The solution lasted 18 months because we figured out the specific need before doing any delivery work.
If I’d provided a web interface, I would have been on the hook for managing and supporting a web interface, including the underlying server (or serverless implementation) and the security implications that authentication and authorization on a web server requires for that kind of solution. None of that was required.
People like to build simple things. It’s usually quicker and easier, and the response is often more joyful.
Win-win.
Understand and meet the need and only the need.
Principle: Build to maintain because maintenance is far far more painful than initial build
Most tech people, when they look at a new project, will consider how long the initial build will take. This is generally based on experience of how much coding is involved, how good they and the team around them are, and how complex the logic of the application is.
What almost nobody is good at is understanding the level of maintenance required for the solution once built.
One of the biggest frustrations that I have when talking to people who have worked in tech for a long time is that they believe that the “maintenance“ aspect of a solution is almost a “tax” on a project. It’s just something that has to be paid, and there is no way of minimising that tax.
In other words, if you build any solution and it has X lines of code, then you’re going to need Y humans and Z days per month simply on maintaining that solution.
The idea that maintenance is “baked in” seems to also get worse among people who are advocates of “never-non-open-source” (those people who constantly say that open source solutions are the best and the only ones people should ever use).
Reducing maintenance time is a fundamental good in every single project, and if you can prove that increasing the amount of initial build time is very likely to achieve a reduction in maintenance then longer builds are a reasonable price to pay.
Let me explain:
(These graphs are idealised and not based on real data so don’t come at me, and are intended to help explain the point)
The area under the graph is Total Effort.
It’s pretty obvious to me which one is better over time.
I am not saying that maintenance is never needed, or that maintenance will not increase over time as an application gets older (as that almost always happens).
This is a big part of the “why” of serverless
The point is that considering maintenance in the design right at the start can make a huge difference to the amount of effort required over the entire project.
This is a major reason why I advocate for a serverless approach, because the maintenance involved in a well designed application is so much lower.
Note: the “serverless approach” in the above scenario does not advocate for the use of container-based solutions because those require significantly more maintenance than avoiding all container- and instance-based solutions. I am not against containers, but I am advocating against them because they are harder to maintain over the long term than, for example, zip files in AWS Lambda functions.
“… but you’re wrong”
Focusing on maintenance will mean that some decisions seem “wrong” to experienced tech people.
I have been told on many occasions that my approach is wrong or something that people “aren’t used to” so will take “longer”. I’ve had to stand my ground on multiple occasions to get this across to people.
I am very willing to accept that I don’t know everything, but I am not going to accept that people can’t do things because they aren’t used to them.
People can learn things, and adapt. There is nothing that says that the way we used to do it in the tech industry is always “right”.
However…
One of my worst experiences in tech was when a senior leader who was supposed to be following the guidelines and principles I had created for the org as an expert consultant, simply refused to accept that I had any understanding or experience of how to build large scale solutions.
He totally undermined my approach to the team that he led, which was one of several that were supposed to be integrating their solutions over time. It led to his being nice to my face and in meetings, and behind my back their team completely ignored my advice, did their own thing, and ended up with a solution that did not integrate or work well with the multiple other aspects of the solution being built. He blamed me for this.
What ended up happening was that all the other teams ended up taking a few weeks longer on the initial build, but ended up being able to fix bugs and maintain their solutions much more easily than this other team. They completed their solutions approximately on time. The launch of the application was however delayed because of only one team, and I couldn’t help them very much because the team leader had ignored my advice and his team had been poisoned against me.
It might seem obvious, but one of the big things about maintenance is that the person that builds something is almost certainly not going to be the one that maintains it in the distant future.
Whatever you create, make it so that it is easy to maintain. Don’t allow a deadline to drag your focus from this (unless it is absolute).
Principle: Use the shortcuts Luke!
Your solution is about how to meet the Need you have identified.
Your solution is not about how clever you are as a programmer.
Your solution should not be about ensuring that you keep your job by making it impossible for others to understand what you have built…
…although I also suggest that it is also a good idea to not intentionally do yourself out of a job by running out of work!
Let me assure you that I’ve only ever worked in one place where we kept running out of work to do, and that’s because I was the CTO, and I was following these principles (although they weren’t laid out like this). At that point, we could start experimenting with new ideas and features, because maintenance was easy, and that was when work was fun.
So what do I mean by shortcuts?
Do not build things yourself that other people have built and are cost-effective to use.
The majority of solutions that have a web interface use an open source backend solution running on the cloud in some form.
With the rise of “serverless” solutions (I’m using the quotes intentionally) there has been a rise in limiting the use of instances and servers.
However for most of the bigger orgs, the solutions that they create tend to be running in kubernetes, and use something like python or node.js to create the web application to run on it.
Then there is the necessity to write the web application, use a data store of some sort which is very often but not always an RDBMS in the cloud, and then deploy the kubernetes cluster to a cloud provider.
Some see this as “serverless” especially if they use very small container runtimes which is possible to do. I don’t, because you’re still needing to maintain that container which significant effort.
The reason I find this baffling is because the maintenance involved in this is enormous in comparison to what I do.
My approach is to use the shortcuts available from the cloud providers.
All the kubernetes solution does is to provide compartmentalised compute. You still have to define what goes in each compartment, and even if you get the cloud provider to run the kubernetes cluster (so you don’t have to) it’s a lot of effort to achieve this.
Why not just bypass this whole issue?
Why not just… give the cloud provider the code, and let them figure out the rest?
Taking AWS as an example (it’s what I know best):
- API Gateway for HTTP layer
- AWS Lambda (zip files only) for compute layer
- AWS Lambda functions are one function per route for HTTP layer
- AWS Lambda development focus is on minimising cold starts*
- No instances or containers
- Long running tasks (longer than AWS Lambda timeouts) are broken down into steps and either use Step Functions or custom process (as these would never use a request-response architecture)
- Use DynamoDB for small and rapid data storage and retrieval elements
- Use S3 for blob/file storage and retrieval
- Use an authn/authz solution e.g. Cognito or similar
- Manage all the above via CloudFormation solution such as SAM or CDK
*Note: Don’t start with java!!! Minimising cold starts comes under the “reducing maintenance“ principle. This is because cold starts are much harder to reduce once the code has been created and deployed. It’s also why I always tell companies to avoid java as the first choice of language for Lambda functions. It is possible to build really good Lambda functions in java if you are experienced but most are not to begin with and end up with very bad cold start performance even with all the new stuff that AWS has produced.
These are all shortcuts to avoid having to build elements of a solution that are not core to the business and therefore the solution.
It has not been “core” to any business for a very long time to “build” an HTTP layer or a “container”.
Knowing how to build these solutions is not easy if you haven’t done it before, but essentially the design of the solution partially moves from the “framework” to the “infrastructure as code”. They are far more intertwined.
Which means that you cannot separate out your Dev and your Ops teams in the same way.
It also means that you cannot run everything “locally” because there is simply no point in trying to replicate “the cloud” on a local machine. Better to actually develop in the cloud, and create tests for the much smaller amounts of code that you create, before deployment.
It’s much easier.
Because you’re using the cloud to shortcut your way to a solution, shorten the build time, and reduce maintenance.
If you are very good at working with shortcuts you can create a solutions much more quickly, and make solutions more maintainable and extensible.
This takes practice, but once you have seen it, you can’t unsee it.
Principle: Understand how the solution can be retired and/or replaced
This is one thing I don’t think anyone in tech is very good at, including me.
It is however one thing I am increasingly aware of.
One of the reasons I think that people who do not understand technology struggle to understand the costs of technology is because, as an industry we are very bad at knowing when to replace a solution.
The techies on the front line will be spending a lot of time fixing issues with a solution that the company says is critical to their business, and the team will keep working on it faithfully.
But very few people will think “is this the right approach?” or “should we be building a replacement which is easier to maintain?”.
Our understanding of risk and the costs of delivering the solution and how we understand maintenance are all linked to this.
If we see maintenance as “just another tech tax” then there really isn’t much point in building another version of a solution, because the team will just have to maintain that new thing.
That’s pointless.
But if the new solution is easier to maintain, because it was built to be maintained more easily, then the conversation changes and the risk changes.
Add to that, that if the need is well understood, and the solution is reaching a recognised threshold of maintenance (“beyond this point/amount of effort expended per month we need to consider replacing this solution with a new one”), then it becomes a lot easier to discuss building a replacement much earlier, and costing in the effort of delivery.
The majority of solutions that I see are maintained until the solution effectively becomes virtually impossible to maintain or impossible to replace… or both.
When that happens, the cost of maintenance or replacement becomes so high, that the business suffers.
If you as a team or org can identify a way of having a regular conversation around whether a solution is worth maintaining for another period or whether the investment in a new solution is the right approach, then so long as the need is front and centre of that conversation, who built the solution and whether they are doing a “good” or a “bad” job is secondary.
A team with the best intentions cannot maintain a solution forever, whatever that solution is.
People don’t like doing a bad job. Doing maintenance is painful if the solution is difficult to maintain.
Identifying when to replace a solution should be regularly considered and should have some accompanying metrics.
Principle: Teams are people not resources
There are going to be times when deadlines need to be hit in every organisation.
But the fact is, that we’ve created a system for the tech teams in our organisations where non-critical and totally artificial deadlines are setup for them almost daily.
And they are setup to constantly fail.
The other aspect is that we have normalised this behaviour to the point that senior leaders expect the deadlines provided to be hard and fast, and not guidelines, because they can see the dates and times in the online management solutions.
In tech, we don’t price in breaks, or days when the tech just doesn’t work, or sickness, or anything like that any more.
And when we push people to hit deadlines, we definitely don’t make them consider whether the solution they are creating is maintainable.
Essentially we push people to create things that are “somebody else’s problem”.
We also don’t give anyone space and time to learn anything.
And don’t give me the “innovation tokens” idea because of “limited capacity”. This isn’t the right way to think about people. If there is limited capacity because the deadlines are racing at people, then someone, somewhere didn’t give people the right amount of time to learn something new, or the right amount of time to deliver the project.
I would never have built serverless things unless I had been in total charge of my timescales and how I delivered things.
We learn by making mistakes and then not being yelled at or penalised for doing so.
Your people will never give their best if you don’t give them space to learn.
They will not be able to build great solutions, and help their future selves and future colleagues out by considering maintenance if they are constantly under pressure.
I hate the idea of “post mortems” because NOBODY DIED. We’re not dissecting remains of something dead. Maybe call it something else?
The culture of technology is so bad, in so many ways, that it’s no wonder that people that come into tech are enthused for a short period, and then become disillusioned with it.
I had a principle as a startup CTO which was that my team only needed to do 6 good hours in a day, and it was up to them when they finished.
It was informal and not a “hard and fast rule”, but it was important. If someone felt they’d done good work, and wanted to go home early, then they absolutely could.
That startup produced some of the most effective and efficient people I’ve ever worked with in tech. It wasn’t perfect, because nothing ever is, but I like to think that people were happy there.
I’d far rather have that, than a lot of people stressed about hitting a deadline. It was a better attitude than most companies I’ve worked in (I may be delusional here too!) and the team was not put under pressure by me. We still delivered what we needed and often well before it was needed.
One thing that is worth saying is that sometimes people need to leave, and sometimes people need to be fired. There is nothing that says you need to be vindictive or mean when somebody leaves.
Sometimes also a company or organisation isn’t right for me. Mental health is important too and I’ve left a number of roles because of my mental health.
The tech industry has a lot to learn here.
Look after people, and they will look after you and the company. It’s not a family, it’s a job, so treat people with respect.
Conclusion
This wasn’t the post I set out to write.
But this is what came out.
When I work with tech teams and companies, the biggest thing is that it is often really difficult to identify and understand how a company and a team should work on a high level.
There are lots of approaches and strategies e.g. Agile. Most of the approaches seem to get reduced to a set of 1s and 0s by a tech company somewhere and make the humans that have to deliver within the approach much less happy than they could be.
What I’ve tried to put into words is how I want to work with people, and some of the principles I give to people when I am working on a project.
The role I take sometimes is as a non-exec director or maybe I’m a fractional CTO or maybe I’m just advising, but whatever the role, these are the kinds of things I end up saying in one form or another over and over again.
And the biggest problem is that I end up fighting against the tech industry.
The tech industry thinks that it has a lot of the answers.
But so often the tech industry answers to these problems end up being very hard on the people who end up doing the work, the techies themselves.
And the problem there is that the techies seem to think that anything that looks different is “wrong”.
In the end, what I think I most care about is whether people are able to do their jobs without being bullied or feeling undue pressure and affecting their mental health.
I’ve been in too many places in tech where mental health and pressure are secondary (and sometimes much further back than that) to delivery.
People that work in the industry don’t hate people, but the industry overall is enabled by all of us. There are many lovely people in the industry, but it’s far too often “copy and paste” practices from one org to another that mean that we don’t learn and continue to propagate bad practices.
We need to push back on the practices in the tech industry that make many people unhappy because they will invariably do a better job when they are happy.
The tech industry is really not a great place to work for many many people.
In my own small way, I’m trying to change that.
Maybe you should too.