What Does It Mean to Be a “Good” Engineer?

At HubSpot, we first defined and published our company values in 2013 with the Culture Code. Last year we published our Product Values to be more transparent, internally and externally, about what we value as a product and engineering organization. But one thing that’s become clear as we’ve grown (both in terms of size, scope, and global reach) is that candidates and employees alike want more clarity on what behaviors support those values on a daily basis. What does it mean to be a _good_ engineer_-1

There’s a lot of noise out there about the importance of holding onto the fabled “10x engineer,” who exhibits superhuman levels of productivity (and subhuman levels of empathy). But we want to combat the notion that there’s only one way to be an effective engineer, and that traits like proactivity, kindness, and teamwork don’t contribute to making an impact.

Our values are only as real as the degree to which they are personified in the code we ship, the individuals we hire and promote, and the leaders we value and reward, so the more context we can provide for people on the front line about the behaviors that are meaningful to our team, the more likely it is that we bring our values to life every day in the work we do on behalf of our customers.

The initial internal draft for this post riffed off an old post by Ben Horowitz on good and bad product managers. While useful and illustrative in its contrast, it reinforced the idea that there are “good” engineers and “bad” engineers and that those are either badges of honor (in the case of good engineers) or shame (in the case of bad engineers). 

The reality is a bit murkier--all of us, at some point, have embodied behaviors that we describe as effective or ineffective on the list below. The goal of this post is to keep all of us (including me) focused on demonstrating positive behaviors that help us become a better product team every day. 

Value #1: Customer First

At HubSpot, our mission is to help millions of organizations grow better, so it’s imperative that our engineers and tech leads demonstrate customer-centricity in their approach. 

Effective behaviors:

  • Interacting with customers in order to better understand how they use the product. Striving to understand the problem we’re solving and building solutions that delight customers.
  • Building with empathy. Testing the product with customers’ use cases and workflows in mind.
  • Understanding that code that doesn’t provide value to customers or make HubSpot better isn’t worth writing.

Ineffective behaviors:

  • Caring more about using a new technology or approach than the value it adds for our customers. 
  • Sitting out of user calls and research sessions.
  • Not using the product—and maybe not even being sure of what the product does.

Value #2: Complacency Equals Failure

In our original Culture Code deck, one of my favorite slides illustrated that as organizations grow, they regress to the mean. I want our team to push relentlessly against complacency in our approach, our philosophy, and our execution. Why? Because your customers have no time for your complacency. In a market where customers have thousands of options for their tech stack, our team needs to feel that just perpetuating the status quo to avoid ruffling feathers or owning meaningful change is failure, not success. 

Effective behaviors:

  • Leaving things better than you found them.
  • Questioning the status quo. Seeing when systems are no longer adequate and identifying where and how to adapt them.
  • Caring about your team’s mission and goals. Understanding team strategy, developing your own perspective, and giving feedback and suggestions. Being passionate about the team and sharing that passion with others.

Ineffective behaviors:

  • Writing code, but not connecting it to outcomes.
  • Not testing your code.
  • Trying to pass off laziness as keeping it simple.
  • Following known patterns blindly, and failing to adapt to changing needs or requirements.
  • Complaining about what’s going wrong—but not working to fix it.
    • Assigning blame instead of charting a path forward.
    • Ignoring problems.
    • Seeing the existing culture, technology, and process as permanent.
    • Not pushing yourself and others to grow.

Value #3: Think Like an Owner

It’s easy when you’re part of a bigger team to think of problems as something you don’t have an obligation, permission, or time to solve, and as a result to pass that issue along to the next engineer, tech lead, or worse yet—customer or user. The behavioral goal is not “if you see something, say something,” but rather “if you see something, do something.”

Effective behaviors:

  • Proactively taking ownership of problems and creating solutions.
    • Knowing the backlog and developing your own sense of priority.
    • Being able to work autonomously without explicit daily direction.
    • When things go wrong, thinking "it may not be my fault, but it is my problem,” and addressing alerts and customer issues without being asked.
  • Seeing a job all the way through.
    • As you come up with solutions, ask questions and verify your approach.
    • Sharing what you’re working on and how it’s going on issues—especially if there’s a problem.
    • Addressing code review comments, getting your work merged, deploying and testing your changes, releasing the feature to customers, and validating that there are no issues.
  • Knowing that you are the master of your own growth.
    • Watching what more senior engineers do and emulating their behavior.
    • Continuously and proactively asking for and accepting feedback from your peers and leads, and working on areas of improvement.
    • Building trust, autonomy, and social capital over time, knowing those things must be earned.
    • Thinking long term, setting goals for your own progress and learning.

Ineffective behaviors:

  • Thinking “that’s not my job”.
    • Waiting for your lead to assign you work. Never taking alerts or addressing customer issues and bugs without being asked. Assuming someone else will handle problems.
    • Focusing only on the discrete tasks that are assigned to you instead of developing a holistic view of your team’s work.
    • Thinking that your product’s direction and roadmap comes only from leadership.
  • Dropping the ball.
    • Needing constant check-ins to make sure you’re focused on the right tasks.
    • Starting to code immediately without thinking through or validating your approach. Failing to consistently discuss possible solutions or solicit feedback from your team or peers while working.
    • Not communicating about how your work is going unless someone asks you. Needing someone else to remind you to update issues or share a project’s status.
    • Not letting anyone know when you’re stuck. Wasting time going in circles without asking for help.
    • Not trying to solve a problem on your own before asking others.
    • Not proactively addressing code comments or pushing your code unless someone reminds you. Letting others stumble upon code problems in production.
  • Not caring about the overall mission of the product and team.
    • Not understanding the goals and not engaging leadership to understand them better.
    • Not asking questions or showing curiosity about customers and competitive products. Ignoring the wider context and focusing only on your island of ownership.
  • Believing you are owed career progression. Waiting for wake up calls to push you to grow.
    • Ignoring the behaviors that have helped those more senior to you advance.
    • Not wanting to hear how to improve.
    • Never asking for help. Thinking you should already know the answer to every question or that you should always be able to work things out by yourself.
    • Not planning your work in advance. Not setting goals and reflecting on whether you’ve met those goals.

Value #4: Move Quickly & Iterate

One of the reasons engineers come to work at HubSpot to this day is because we move quickly. We commit code hundreds of times of day to help our customers succeed, so if you’re someone who wants to launch just one big product per year or who wants an instructional manual for daily tasks, we likely aren’t the best fit. 

Effective behaviors:

  • Knowing that no one gets things perfect on the first (or even second) try, but doing what you can to make things better with every iteration.
  • Knowing that complex systems evolve from simple systems. Not designing complex systems from scratch—but starting over from simple systems.
  • Identifying ways to test concepts with customers without building an entire application.
  • Knowing when to let a project go if it’s just not working.
  • Building out something that works and provides value to customers, even if dependent teams are still catching up.

Ineffective behaviors:

  • Trying to create a perfect system, then getting bogged down in complexity and details. Coming up with reasons why your system is special and can’t be built iteratively.
  • Working for weeks without committing code or getting feedback from customers.
  • Getting attached to a project and insisting on seeing it through to completion, even when the tide has shifted from customer feedback or lack of interest.
  • Demanding perfection from other teams, and being reluctant to let other teams iterate on problems for fear that it will make your life harder.

Value #5: Keep it Simple

We want to grow people who infuse simplicity into our product and systems with everything they do. Often the boldest actions in our team are deleting code, choosing not to build something new, and removing steps or processes to help our customers save valuable time. We want to create an environment that values and rewards simplicity for our team and for our customers. 

Effective behaviors:

  • Taking as much pleasure in deleting code as you do in writing it.
  • Solving one problem at a time, instead of trying to solve 100% of use cases.
  • Starting simple, looking for opportunities to deliver 80% of the value with 20% of the solution.
  • Writing code as if someone else will one day read it. Chances are someone will.
  • Implementing things when you actually need them, rather than when you think you might.

Ineffective behaviors:

  • Writing code that’s needlessly complex or difficult to debug.
  • Failing to appreciate the value of consistency; introducing new technologies or libraries for minor benefits.
  • Using technologies or frameworks meant to solve much larger problems when you could have used something simple or well-known.

Value #6: Embrace Organizational Change

At HubSpot, we are constantly refactoring pretty much everything. So rather than being precious about your team, your tech lead, your reporting structure, or your approach, we want folks who live and breathe our company value of adaptability. We look for leaders who don’t just tolerate change, but actively embrace it. 

Effective behaviors:

  • Being excited to take on new challenges as needs and requirements change, even if it means giving up your old work.
  • Welcoming the opportunity to work with new people or see your peers move on.

Ineffective behaviors:

  • Spreading rumors and fear about upcoming organizational changes.

Value #7: Scale Each Other

Our success as a team is predicated on scale, and that means systems that scale, but also people who do too. As a result, documentation becomes even more critical to our success as a company and as a team, as does our commitment to sharing what we know or learned from an approach so others can benefit directly versus having to replicate learnings, mistakes, and failures as we grow. 

Effective behaviors:

  • Acknowledging that you don’t have to be a lead to be a leader.
  • Working to become a partner and peer to your lead and a technical leader on the team.
  • Constantly thinking about how to share what you know to the community at large in blog posts and speaking engagements.
  • Helping your new team members out during onboarding. Looking for opportunities to give feedback to members of your team and the organization.
  • Pitching in to answer questions from other engineers not on your team.
  • Reviewing other team members’ code and pull requests, even if you’re not an expert.
  • Documenting solutions to difficult problems and make them easy to find.
  • Creating automation instead of just resolving things manually.

Ineffective behaviors:

  • Thinking your job is to keep your head down and write as much code as possible.
  • Being too busy to help onboard new team members.
  • Not thinking about the long term value or impact of building the team, and instead focusing only on your own productivity.
  • Not reviewing your team members’ code. Assuming that’s only the lead’s job.

Part of the reason we post these values is to hold all of us accountable to these behaviors and to create a common language for challenging each other to live them. Said differently, these values shouldn’t be something engineering leadership “enforces,” but rather something that everyone on the team feels a responsibility to hold each other accountable for on a daily basis. When I first shared a draft of these behaviors with my team, I got pretty bold and candid pushback on one of my assumptions from one of our tech leads. I view that kind of pushback from peers as very much a feature of the process, not a bug. The goal here is to keep iterating on these values and how they are lived daily, and to create an environment that is psychologically safe enough so that anyone on the team can challenge, discuss, or make suggestions to change them or how they are built into our operating system daily.

Finally, no list of behaviors is ever exhaustive, unconditional, or applicable in every situation. Cultural context and situational context are critical here. But our goal in sharing this is to give our candidates, engineers, customers, partners, and leadership team a clear picture of how we think about success as a team, and the choices, big and small, that drive what we view as high impact behaviors in our organization. 

 

Whitney Sorenson

Written by Whitney Sorenson

Whitney is HubSpot's Chief Architect.

Subscribe for updates

New Call-to-action