We are all vehicles

A framework for understanding ourselves.

2024-08-20

Preface

This article presents a framework for understanding ourselves as vehicles. This will help us understand the strengths and weaknesses of different types of people, the motivations behind their thoughts and actions, and how coworkers with radically different approaches can still amicably work together.

This framework can be applied to people in many different roles, whether they are data scientists or product managers. However, I will be providing examples specific to software developers because that is what I can best speak to.

The content is built upon an analogy that was invented and shared with me by a former manager. I then developed this framework through my subsequent reflections, based on my personal experiences.

Background

First, let’s set the scene for how this analogy was presented to me, and the impact that had on my development.

Odd one out

This story starts nearly three years ago at my previous workplace. I started working there immediately after they had secured their series A funding round. The team was small, and there was a lot of work ahead of us. It was also a highly competitive, fast-moving space. (LLMs, but before ChatGPT changed the game.) As a result, the engineering culture was very fast-paced.

Additionally, I was just pivoting into backend engineering from data engineering. While I'd done backend work before, this would be my first time doing so in a "real" job. Although I'd proven my intelligence and learning abilities during the interview process, I had role-specific knowledge gaps. Thanks to my relatively low self-esteem ego, I started suffering from a bad case of imposter syndrome.

I felt like I was surrounded by "rockstar" developers. They were able to churn out code more quickly than I could, and they seemed a lot more confident than I was. I couldn't help but compare myself to them, and I felt like I was falling short.

Most of these rockstars were perfectly nice to me and eager to collaborate. However, one of them gave me the impression that they thought I was stupid. They questioned why I couldn't figure out problems or solutions as fast as them, when it was all "so easy". Despite feeling confident enough to argue with them on implementation decisions, I felt that they were fundamentally better than me.

Constructive feedback

Whenever I met with my manager for our one-on-ones, I would ask for constructive feedback. I was convinced that I was doing a terrible job, and I wanted to know how I could improve, or at least to know in advance if I was going to be fired.

Instead, they would always have positive things to say about my work, and would assure me that I was on a good path. However, I didn't feel like I was getting the same respect from all of my teammates, even if they liked me. I couldn't tell if my manager had wool over their eyes, if they were too nice to tell me the truth, or if I was being too hard on myself.

After a few months, my manager finally came to me with constructive feedback. They told me that in their experience, developers fell into one of three categories: tanks, motorcycles, and cars.

Tanks write highly robust code, but they can be slow. Motorcycles execute very quickly, but they can be fragile. However, cars are the best of both worlds. They are as fast and as sturdy as they need to be for the task at hand.

As you can probably guess, I was a tank. My manager told me that they wanted me to be faster, because that was what the company needed from me. However, they wanted me to become a car, rather than overshooting and becoming a motorcycle.

Shifting perspectives

I asked my manager if they had examples of developers who fit the other archetypes. For the motorcycle, my manager quickly named the developer who I'd been comparing myself to. For the car, my manager named a frontend engineer with many years of experience.

It was like a fog had been lifted from my eyes. Suddenly, I realised that I'd been viewing myself and others through a very narrow lens, shaped by my limited conception of an ideal developer. That wasn't fair to me, or to anyone else.

The "rockstar" wasn't perfect or necessarily better than me, just different sides of the same coin. The person who told me that I was the only good backend engineer (yes, really) was a tank too, and clearly preferred that approach. And because I didn't work on the frontend codebase, I had no idea that there was a car in our midst.

My manager left the analogy there, but it's stuck with me ever since. (This article has been in the works for well over two years!) I've found it to provide a very useful framework for understanding the developers around me, as well as myself.

Finding my place

With support and smart decisions from my manager, I was able to hit my stride. First, I was made responsible for a product that was highly suited for a tank-leaning backend engineer. The code was very complex, brittle, and buggy, due to the motorcycle-style development that had been required to get it out the door. I was able to drastically improve the reliability and maintainability of the product, making use of my unique skills while I developed my backend knowledge.

Second, my manager found a mutually beneficial opportunity for me to collaborate with the car frontend engineer. They wanted to shift to full-stack engineering, and needed a backend engineer to train them. From them, I learned how to tread the line between motorcycle and tank behaviour. While we developed features together, I paid attention to the decisions they made and how they evaluated the tradeoffs between different approaches.

Through both of these opportunities, I was able to enter and remain in a flow state. I became comfortable quickly making changes and calling shots, because I could understand the entire system and consider the tradeoffs. This both increased my growth as a developer and maximised my usefulness to the company. I also earned the respect of my motorcycle coworkers, who would commend me for my PRs.

Monkey see, monkey do

Perhaps the most important thing this initial analogy gave me was knowledge of who to emulate and who not to emulate. Not only should I not be comparing myself to motorcycles, but I shouldn't be emulating them either, even if I wanted to improve the skills that they were better at. I could separate the positive task of becoming faster from adopting the negative approach of doing so in all situations.

I would often ask myself "what would a car do?", where I could substitute "a car" for the name of any specific car developer. This helped me find the right path by having a guiding star, in the form of specific developers, to work towards. I now had a way of understanding myself in the context of these car developers, and could evaluate my own thoughts and actions through that lens.

A framework is born

Naturally, the next step was figuring out why different archetypes behaved the way they did, and noticing that conflict between developers tended to fall along an archetypal divide. This included expanding the single sentence descriptions of archetype behaviours from the analogy into mindsets, and delving into how these mindsets differ when situations are the same.

So, did I become a car at my previous job? I can't say definitively, and the organisational distance between myself and that manager quickly grew as the company did. Judging myself intuitively, I would say not quite while I was there, but I probably am one now. My current teammates can attest that I do sometimes cause incidents while moving quickly, but that I also advocate for and implement long-term changes.

Much like it's hard to draw the line between green and blue, I can't pinpoint exactly when the shift happened. At my previous job, I honestly just focused on "going faster but not too fast", based on that initial simple analogy. While I did make progress, this approach was fundamentally about skills rather than mindset. What really helped was having the space and time since then to think deeply, process interactions, and view others with empathy. Of course, I still struggle and make mistakes, but now I have a framework to lean on.

Regardless, this article isn't about categorising myself. It's about what the vehicles framework can tell us about how we think and work, alone and together.

Vehicle mindsets

Let's delve deeper into the different mindsets driving tanks, motorcycles, and cars. We'll consider how these archetypes approach different aspects of software development. In general, tanks focus on long-term stability, motorcycles focus on short-term speed, and cars balance the two while considering the present situation.

Design

While tanks want to fully plan and motorcycles want to dive in, cars balance both foresight and flexibility.

Tank: We need to plan this out fully and consider all possibilities. We should ensure that our implementation is intelligent, scalable, and future-proof.

Motorcycle: Let's take the path of least resistance. We can just work with our existing systems and worry about scale and complexity later.

Car: Let's get the MVP out quickly to gather user feedback. We can re-architect it once we understand the final design. However, we should take care to avoid making future refactors painful.

Testing

While tanks want to fully test and motorcycles want to just ship, cars balance both quality and delivery.

Tank: Every feature requires unit tests and integration tests before it can be considered complete. We can't risk shipping bugs to production.

Motorcycle: Testing takes too much time and gets in the way of shipping. We'll know it works if it works. We can always fix it later if it breaks.

Car: Tests are important, but we need to balance the time with the risk. Let's cover the critical paths now and exhaust the edge cases later. We should improve our testing infrastructure between projects.

Decision-making

While tanks want to analyse everything and motorcycles want to act quickly, cars balance both exploration and execution.

Tank: Let's analyse the data and consider all the outcomes before we make a decision. It's better to delay the project than to make the wrong choice.

Motorcycle: We should move quickly and decisively. We can't afford to analyse all the information. We can always pivot later if we need to.

Car: Let's make a decision that's good enough for now with the information we have on hand and our best judgement. We should be prepared for future changes, but we can't get stuck in analysis paralysis.

Refactoring

While tanks want to refactor early and motorcycles want to push forward, cars balance both technical debt and progress.

Tank: We should refactor our code early and often to ensure that it remains clean and maintainable. We need to pay down our technical debt as soon as possible.

Motorcycle: Refactoring should only be done when absolutely necessary. If the code works, let's leave it alone and focus on our next project.

Car: It's okay to accrue technical debt in the short term, but we should address it when it limits our development speed or product quality. We should avoid premature optimisation but we can't ignore the long-term consequences of our decisions.

Nuance

Before we get too into the weeds of this framework, I'd like to take some time for clarifications.

Skills don't matter

Your vehicle archetype isn't determined by the strength of your skills. Comfort, experience, and tenure can all impact your skill levels, but they don't determine your mindset. I've worked with tanks who are super fast coders and motorcycles who design extremely robust systems.

Instead, your vehicle archetype is determined by how you approach your work and your decisions, and what you value and prioritise. This is independent of situational or individual factors. When push comes to shove, are you consistently biased towards stability or speed, or can you balance both?

Cars are chameleons

You may be wondering if it's best for all developers in a team to be cars. The key feature of cars is that they're adaptable without being fence-sitters. They understand both the tank and motorcycle perspectives, and can choose the appropriate approach for each situation. They are versatile, but they're not necessarily "super developers" who are the best at everything.

I think the real question is what does your team need? If you need developers that act like motorcycles, it might not matter if any of them are cars, because those cars will end up acting like motorcycles anyway. Also, cars can be hard to find and hire, so don't count on being able to build an entire team of them.

Cars aren't perfect

It's important to note that it's rare for someone to be perfectly in the centre of this spectrum. Additionally, even a "perfect" car might not act "perfectly" in every situation. Most people will lean towards one side or the other, and that's okay!

The goal of this framework isn't to idolise cars, or to decide that you're a car and therefore perfect. Instead, it's to help you recognise your tank and/or motorcycle behaviours and mindsets, and consider how to best work with those who lean the other way. It's also to help you understand what you might be overlooking in your own approach, and how you can grow as a developer.

Vehicles are tradeoffs

It's notable that this spectrum is also a set of tradeoffs. Different vehicle archetypes may be more or less useful in different roles, teams, or companies. For example, tanks are often more common in platform engineering teams and mature companies, while motorcycles are often more common in product engineering teams and young companies. However, the opposite archetypes are also valuable in these situations to create a diverse and balanced team.

From this point onwards, we'll focus on tanks and motorcycles specifically, since those are the two extremes of the spectrum.

Conflict and collaboration

At my previous job, there was a lot of conflict between developers, and it could sometimes get nasty. This lead to an unhealthy work environment where collaboration felt toxic, at least from my perspective. I don't think toxicity is unique to any one workplace, and only a minority of developers took part in it. Despite this, it affected my happiness and productivity, and was one of the reasons I decided to leave.

Looking back, I feel that many of these conflicts were caused by clashes between strong-minded individuals with different mindsets: tanks versus motorcycles. If you think your mindset is the correct one, someone with the opposite mindset may seem foolish to you. However, it's important to understand and appreciate your coworkers' skills and attitudes, even if they may be different from yours.

Additionally, toxicity can be contagious. When someone refutes you in a toxic way, it's easy to match that energy and respond with the inverse. It's perfectly fine to have strong opinions that match a tank or motorcycle approach, and they may even be correct. That being said, we should ensure that they come from thoughtful consideration and are respectfully communicated.

Of course, toxic behaviour is not intrinsic to either tanks or motorcycles. It's very common to be a wholesome, non-toxic developer while falling firmly into one of these archetypes. Additionally, cars can still have conflicts and engage in toxic behaviour with coworkers. However, in my experience, this type of toxicity is often rooted in either a tank or motorcycle mindset. Remember, cars aren't perfect.

Let's see how toxicity can manifest in different aspects of collaboration. We will consider hypothetical toxic thoughts or statements from tanks and motorcycles, and contrast them with non-toxic alternative thoughts or responses.

Determining requirements

Instead of assuming that coworkers are unjustifiably ignoring or adding requirements, we should consider their reasoning.

Toxic tank: You always over-simplify everything.

Toxic motorcycle: You always over-complicate everything.

Non-toxic: There are many considerations. Which ones are actually important?

Choosing the right approach

Instead of assuming that coworkers are deliberately choosing the wrong approach, we should consider the tradeoffs.

Toxic tank: It's not hard to do correctly; you're just reckless.

Toxic motorcycle: It's not hard to do quickly; you're just incompetent.

Non-toxic: There is a fast way and a robust way. Which one makes sense for our needs?

Understanding intention

Instead of assuming that coworkers are trying to sabotage us, we should consider their goals.

Toxic tank: You would cause way more incidents if it wasn't for me.

Toxic motorcycle: You're always blocking me from getting stuff done.

Non-toxic: We should all work together to produce the best outcome. Are their intentions positive?

Appreciating differences

Instead of assuming that coworkers are inferior to us, we should consider their strengths.

Toxic: You don't deserve to be here.

Non-toxic: Our differences make us a better team. Are you measuring others by your own stick?

In my opinion, this is the most dangerous form of toxicity because it is a direct value judgment of our peers. Not every person is a good fit for every team or company, but we should keep an open mind when evaluating others.

External motivators

Some time after leaving that job, it occurred to me that I had definitely been a car in other roles right away. It dawned on me that perhaps my initial strong tank behaviour had not been purely intrinsic. I realised that one's position on the tank-motorcycle spectrum may not be fixed, and might change over time or in different environments.

So, let's talk about external factors that motivate developers to act like tanks or motorcycles. I will be focusing specifically on topics that motivate these archetypes in different ways, rather than situational factors like role or experience. I argue that this behaviour is driven by their differing fears, whether they view it that way or not.

Determining these motivators helped me gain a lot more empathy and understanding for coworkers, whether tanks or motorcycles, who had been causing conflict or engaging in toxic behaviour. It also helped me understand the "other side" to my fears, which has enabled me to move past them. Or at least, to consider both opposing fears and decide which one to respond to.

Peer perception

Tanks are motivated by a fear of being blamed for failures. This can lead to over-cautiousness, where tanks might avoid taking on risky projects, resist substantial changes which could improve the product, or spend excessive time on planning and testing.

Tank: If something goes wrong, I'll be held accountable. I need to ensure that my work is flawless so that no one can say I'm incompetent.

Motorcycles are motivated by a feat of being seen as inefficient. This can lead to rushed work, where motorcycles might cut corners, deliver incomplete features, ignore potential issues, or generate substantial technical debt.

Motorcycle: If I don't ship this feature ASAP, I'll be seen as slow and replaceable. My worth is determined by how quickly I can deliver.

Incident response

Tanks are motivated by a fear of causing incidents. This can lead to over-engineering, where tanks might delay small but high-impact changes, or block releases to address every possible edge case.

Tank: If this code breaks, whoever is on-call will be forced to clean up after me. I'd rather spend extra time now to avoid waking up at 3 am in the future.

Motorcycles are motivated by a fear of delaying releases. This can lead to frequent incidents and bugs, where motorcycles might strain team dynamics, or cause stress and burnout for themselves and others.

Motorcycle: Incidents are a cost of doing business. I'd rather deal with them as they come than hold up a release for extra precautions.

Product pressure

Tanks are motivated by a fear of misalignment. This can lead to feature delays, where tanks might spend excessive time seeking clarity or approval before beginning development work.

Tank: If my implementation doesn't align perfectly with the product team's vision, it could lead to wasted effort. I need to fully understand the requirements and implications before moving forward.

Motorcycles are motivated by a fear of missing deadlines. This can lead to motorcycles shipping products that don't meet the right goals or have implementation issues, requiring refactoring or starting over.

Motorcycle: The product team wants this feature yesterday. I need to deliver quickly to keep them happy, without wasting time writing planning documents.

User experience

Tanks are motivated by a fear of negatively impacting users. This can lead to perfectionism, where tanks might spend excessive time testing edge cases and small details, or avoid shipping features that are "good enough".

Tank: If we ship buggy features to our users, we'll lose their trust. I need to ensure that everything is polished and reliable before it goes out the door.

Motorcycles are motivated by a fear of not meeting user demands. This can lead to motorcycles shipping rushed features that are buggy, don't meet user requirements, or are difficult to maintain.

Motorcycle: If I don't ship this feature, deals won't close. I need to deliver quickly to keep our users happy so that that they don't leave us for our competitors.

Reflections

Now that you're armed with the vehicles framework, here are some questions for you to reflect on.