Alex Dzwonchyk

Leading a technical project the easy way

In thinking about what makes for successful technical leadership of any kind of product implementation, I realized that I am somewhat opinionated on this topic! Due that opinion-having, and since I’ve received positive feedback from colleagues and managers in the past about my approach to this, I wanted to synthesize my thoughts on the matter into one post.

The biggest success factor, that recurs in the below points again and again, is a pretty simple and obvious one: communication.

Communicating early and often, in writing and in publicly accessible places, keeps everyone with a stake in the project on the same page, manages expectations, and also allows you as the project lead to handle any blockers or problems that occur in the most efficient and effective way (and with the least amount of stress).

So you’re tasked with being the technical lead on a team that will be implementing a new feature - what steps should you take to maximize your chances of shipping the right thing, on time, with the minimal amount of fuss for all the people you work with, including yourself?

Anyway here are my thoughts, broken down by project phase:

Before writing an RFC

Before anything else, sync with product & design to talk through and fully understand the problem we are solving and what weʼre trying to build. Maybe this sounds obvious but resist the temptation to just start building with whatever you’ve been handed - chances are there are ambiguities and decisions that haven’t actually been made yet!

Now is the best time to push back on anything that doesn’t make sense in the solution card, or that you donʼt understand, and raise any technical feasibility concerns that have occurred to you.

The biggest thing to come away with is full alignment between engineering and product as to what exactly will be delivered at the end of this project, as well as what is not in scope for this project.

Next, talk to the subject matter expert(s) on the area of the codebase youʼll be working on (assuming this isn’t yourself). If any technical feasibility concerns have arisen based on the feature + the code that will implement it, raise these with product and engineering leadership now to resolve them (cut or add scope, etc.)

Once you understand the problem and the scope, spike enough to create a minimum viable prototype that validates the intended implementation. Focus on the unknowns and the new things that would need to be added to the code, with the goal of uncovering any risks and resolving any ambiguities about how complex something may actually be to fully implement.

While writing the RFC

Note: an RFC refers to a Request for Feedback doc, created to allow other engineers and stakeholders to weigh in on a proposed implementation for a product feature. Not all companies use these in the same way but I think the advice here still holds no matter what format is actually used.

On of the most effective things you can do here is to draw diagrams of things wherever possible, whether itʼs to illustrate user flows, show conditional logic, or larger system architecture. Diagrams make it much easier to communicate ideas about how systems work, and can also make things more accessible to non-engineering audiences.

Include references to the spiking work you did, to provide examples of the intended work items you lay out.

Tag people specifically where you need feedback or clarifications from them.

Respond to all feedback in comment threads in the RFC for visibility.

After RFC approval, planning + estimating the work

Note: currently a fan of Linear, so I’m using that to represent wherever the actual work will be tracked as issues or tickets. Applies to whatever you use, even ::shudder:: Jira.

Add each of the actual work milestones scoped in the RFC as issues in Linear, continuing to include as much context like diagrams and references to the spike branch/code examples from similar things as possible. Those references and context are super helpful to whatever engineer ultimately picks up that specific ticket to work on, and having them in the actual issue/ticket prevents having to dig for the same info in multiple places.

Gather the engineering team that will be working on the project and review the RFC again together at a high level, to see if there are any questions at this point.

Then go through each Linear issue, make sure everyone feels aligned on what the acceptance criteria are, and estimate it together using pointing poker or similar (I like using https://www.pointingpoker.com). When in doubt or when there is disagreement on the effort required, err on the side of conservative estimates/more points! This maxim holds true whether you are using “points” to represent time or complexity, as they both shake out to the same relative idea of “effort” anyway.

Compile the points from Linear, as well as information about the engineering teamʼs capacity, and use that to create a rough estimate of the number of sprints/cycles needed to complete the project work.

Use the estimate to create a target date for the development work to be completed, and add at least half a cycle (maybe more, depending on the project scope) to conduct QA and fix bugs found in QA. Discuss the dev complete and QA complete estimates with product owner(s) to align on a release date, and always pad it with more time than you think think you will need!

It’s always better to deliver a project ahead of schedule, rather than have to tell marketing they can’t start their campaign because engineering is running over on time, so always, always be conservative with estimates.

While doing the actual work

Create a slack channel scoped just to this project, and add the engineers, designers, and product who need to know whatʼs going on, as well as your manager and the domain architect/staff engineer(s). This does two things:

  1. it easily gives anyone who needs it real time visibility into everything happening on the project, eliminating the need for extra updates, docs, reports, etc, and
  2. it puts all the context in one place already for when you need help getting unblocked.

Prefer tagging engineers with questions directly in the channel and having discussions in threads from those comments over direct messaging people, as this provides maximum visibility for all. Plus, this makes it easy for engineers to catch up on conversations asynchronously when they have time instead of needing to be pulled out of deep work they may be doing by direct messages.

Provide detailed project updates in the channel periodically on whatever cadence is logical. This approach avoids clogging up other team stand-up threads, or other more general channels, and you can simply tag product owners or anyone else with questions directly in the project scoped channel in the channel if you need their input on anything.

While delegating the actual work

Consider ways to assign out the work so that

  1. the largest, most complex pieces are worked on and completed first and
  2. engineers are able to choose which pieces of work they want to work on and own

1), which is just a reframing of the idea of doing the big rocks first, helps limit the risk of running into blockers late in the project that cause delays, while 2) can give all the engineers involved the best opportunities to do work they enjoy, or work in an area they want to get more experience in.

During QA

Create a QA doc in your collaborative document platform of choice (I’ve used Notion a lot for this) with full instructions for replicating all the cases you need on a review app, or other kind of deployed test environment that can be accessed without running locally, and with clear explanations that would make sense to someone with very little previous context.

Every since my time assisting the test engineers on a major internal migration at PayPal, I have been a huge fan of using a tabular format for this kind of document. A table just makes it very easy to keep track of things when there are columns for status, assignee, pass/fail/pending, and notes attached to each test case. Compared to a free form document with bullet points or something I can’t see any comparison.

Have QA testers leave feedback directly in the doc, along with updating the status of particular cases, so you can review it on an ongoing or daily basis, create linear issues for things that need to be fixed, and prioritize / assign them out as needed.

Continue to update the project slack channel with specifics about any major issues or blockers, and whatʼs being fixed.

After release

Monitor the support channels yourself to get an early read on any feedback coming in directly from users, as it can often be faster than waiting for a support engineer or someone else to escalate bugs.

Sometimes I’ve seen an email come in from a user, realized they had found a bug, and spun up a hotfix ready to release before the official ticket was even filed by support. This is far less stressful than getting that support ticket and 5 identical ones attached 5 minutes after you go on a lunch break.

When you’re fixing bugs

Congrats on the release btw! Now it’s just time to fix the bugs you also released.

When fixing bugs, one of the highest value things to do along with any fixes is to add tests that would have been broken by the bug had they existed and are now passing after the fix. Maybe even do some TDD and write the failing test first here since you know it’s a real bug. Shipping tests like this just helps ensure that the same bug wonʼt start happening again in the future due to a regression.

← Writing