Slava Akhmechet

I am a cofounder of RethinkDB — an open-source distributed database designed to help developers and operations teams work with unstructured data to build real-time applications.

Github issue etiquette

02 Apr 2013

Github’s issue tracker is a simple and convenient way to manage a project’s internal development process. However, its simplicity can cause unintended consequences. The moment your project gets popular, other people will be using it too. Having people outside of the development team use the same tracker requires special care you might be unprepared for. (Of course this is true about other open issue trackers too).

Here’s an example issue from RethinkDB where I made a user unhappy. I talked to everyone internally, determined that there is nothing left to be done, and closed the issue. The thought that others might be using it as an indicator for when an external project fixes their issue didn’t even occur to me.

After a few missteps like this, we evolved issue etiquette guidelines so we can be more helpful to people using the tracker. In the process I found the exact same guidelines extremely helpful to me as a project manager, so I decided to write them down:

This list of simple Etiquette Guidelines (EGs) can go a very long way to keep users happy.

EG0. Acknowledge receipt

It isn’t always possible to start working on an issue immediately, and that’s ok. But it’s very frustrating to submit an issue and get no response from the team for days. Give a simple receipt acknowledgment to alleviate this frustration:

@xyz, thanks for letting us know about this bug. This is @wmrowan’s and @mlucy’s domain, I’ll ask one of them to take a look. I’ll get back to you when we start looking at it — we should be able to get to it in a day or two.

EG1. Notify when you start work

Once you start working on the issue, give the user a quick note that you’re looking into it. It’s helpful for the user to know when you start working on their issue, and it’s very useful to be able to talk to the person who’s working on it directly:

I’m looking into this issue. I’ll get back to you when I have a little more info, should take an hour or so.

EG2. Summarize the state of the issue

Once you’ve looked into the issue, give the user a summary of the state of affairs. Here’s an example of a really good summary:

I’ve started looking into this. It looks like the server is crashing because the random number generator is broken. The random number generator that we use uses the keyboard to generate entropy, but the RandomNoKeyboardException indicates that you seem to be running on a server with no active keyboard. I’m now working on switching the random number generator to the one that uses page fault count for entropy, which will alleviate this problem. It should take me about two days to implement and test this.

A good issue summary will include all of the following information:

  1. The latest understanding of exactly what’s going on
  2. Evidence to support your claim
  3. List of what needs to be done to fix the issue
  4. Implementation plan for getting it done
  5. Immediate next steps with an ETA
  6. Overall ETA for the issue

Make the issue summary explicit, so everyone understands what’s going on. Since readers won’t have the context you do, it’s usually best to err on the side of more content.

EG3. Give periodic status updates

Sometimes development takes longer than expected, and sometimes the ETA is far enough into the future to make the user anxious. In both cases, it’s immensely helpful to give periodic status updates every few days:

I’ve plugged in the new random number generator based on page fault counts and it’s working well. Here is what still needs to get done:
* The new random number generator breaks one of the unit tests. I need to fix it.
* After that, we need to test on a server without a keyboard.
I’m now working on the unit tests and will hand this issue to @coffeemug to do the server testing when I’m done. Unless we run into unexpected issues, we should be able to get the fix to you in the next two days. I’ll keep you posted on our progress.

A good status update will include all of the following information:

  1. What’s already been done
  2. What remains to be done and a plan on how to do it
  3. A list of known roadblocks and a plan on how to solve them
  4. What you’re working on next and its ETA
  5. Overall ETA for closing the issue

Most people reading the update won’t have all the context you do, so make sure you give enough information for everyone to understand what you mean. It’s your responsibility to be comprehensible.

EG3-a. Inform everyone if you slip

Occasionally you’ll promise to get an issue done by Friday, but won’t be able to make the date. It’s not the end of the world — software development estimates are notoriously hard. But keep in mind that people are waiting on your issue. It’s very frustrating for the user (or the project manager) to check the issue on Friday, and find no additional information. It’s even worse when they ping you and find out that you didn’t make it. Be courteous — tell them you’ll slip (in advance, if you can):

It looks like I won’t be making the Friday ETA. Getting the page fault count from the kernel turned out to be a little more complicated than I expected. It’s done now, but I’d like a few more additional days for testing. I should be able to get this out by Tuesday. Apologies for inconvenience!

EG3-b. Inform everyone if you’re on track

Even if you’re making your dates, it’s still very helpful to tell everyone so they don’t have to wonder. People get antsy as you get close to the promised date, and a short sentence or two can really help them not worry. It also helps you be mindful of the deadlines and ETAs:

Just an FYI, we’re still on track for Friday. I’ll add more details in the next status update shortly.

EG4. Keep internal communication explicit

In practice, many issues involve offline collaboration with members of the development team. It’s efficient, but can be very confusing for everyone else. It’s often unclear what was decided, who has to do what, and who’s in control. It’s good practice to summarize everything on the tracker:

I spoke with @srh and he was a little concerned the new random number generator might break something. He promised to write an integration test — I’ll check back with him to make sure the test is written and passes before we close this.

EG5. Make responsibility handoffs clear

Few things are more frustrating than ambiguity over who’s responsible for fixing a problem. Keep this ambiguity to a minimum, and make sure to carefully hand off and pick up responsibility. Here’s a good example of how to hand off responsibility:

Ok, the new random number generator is finished, and all unit tests pass. I’ve talked to @coffeemug — he’ll test it on a server with no keyboard. This issue is now in his court.

And here’s a good example of how to pick it up:

I’m on this. As @wmrowan said, it should take me about a day to get this tested. I’ll keep you posted on my progress.

EG6. Notify on development completion

When you’re done with the issue, it’s helpful to give as much information about it as possible:

I’ve changed the random number generator to use page faults so it can work on keyboardless servers. Commit 23ab45, internal code review 189 by @jdoliner. Will be available in the 1.4 release in the next few days.

EG7. Notify on fix availability

Finally, when the fix becomes publicly available, inform everyone and tell them how to get it:

This is now available in the 1.4 release — see Just download the new version of the server and reinstall. Thanks for helping us get this fixed!

EG8. Always use friendly tone

Many open source projects consider it ok to be abrasive on the tracker. I think it’s never ok. If someone commenting on the issue frustrates you, most of the time it’s because they need a little additional guidance. Even when it’s not the case, kindness and firmness are not mutually exclusive.

Here’s an example of a comment that has poor tone:

Your proposal to switch from virtual functions to templates is stupid — it won’t speed anything up because cached vtable lookups are very fast, and adding templates will only increase the code size and blow the instruction cache. Not to mention that it will make our lives worse because it’ll increase the compilation time. The right decision here is to stick with virtual tables.

Here’s this same example, rewritten with friendlier tone. The content is exactly the same, but the rewritten comment makes everyone happier:

I really think the proposal to switch from virtual functions to templates is a bad idea. It’s unlikely to speed anything up because cached vtable lookups are very fast, and adding templates will almost certainly increase the code size and blow the instruction cache. Also, an additional downside of using templates is that it will make development harder because it will increase the build times. I really think we should stick with virtual tables.

You have an enormous power over other people’s emotions. Use it wisely. Keep debate collaborative, be kind to others, and welcome criticism. It makes for a better product and a happier community.

EG9. Watch grammar and legibility

Use proper grammar and punctuation. Break up sentences into readable chunks. Give enough information so people understand what you’re talking about, but not so much as to inundate them. Use bulleted lists if you have to. Writing well takes a little bit more time, but there is one person writing a comment, and many people reading it. Be mindful of their time. This might even come in handy when you go back to read your own issue a few months later.

EG10. Talk to users on their terms

When you do something every day it’s easy to forget that most people don’t have the perspective you do. Talk to users in terms of the concepts they are most familiar with. For example, if you want to ask a user to provide a core dump, say explicitly what commands you want them to run and what to do with the file once they’re done.

When an issue is fixed, or if there’s a workaround, give a clear path to action:

Please run query X instead of query Y until you can upgrade to RethinkDB v1.4.3.

Use primitives the user knows: