The Road to FogBugz 4.0: Part IV

A ridiculously small portion of the energy it takes to make a commercial software product actually goes into the writing of lines of code. I would estimate that out of every 100 calories expended by the Fog Creek team:

25 calories are spent on customer service
55 calories are spent on debugging, beta testing, and minor tweaks
8 calories are spent on marketing, including the Fog Creek website
5 calories are spent reading college kids’ resumes and interviewing said college kids
5 calories are spent on code that never ships, such as the online demo and the online store

Leaving just:

2 calories spent on actually writing new lines of code that ship to a customer.

This, I think, helps explain why so many software companies started by programmers fail: programmers are really good at writing news line of code, they might be good at debugging, but nobody ever taught them how to do marketing or customer service, and they are probably horrible at graphic design.

Before a consumer will buy your software product, they’ll evaluate all kinds of things to decide if it’s a real product that will meet their needs:

  • They’ll evaluate the quality of your website.
  • They’ll look for discussion groups to see if people are actually using the product, and if the people who have problems are getting prompt resolutions.
  • They’ll look to see if there is a third-party support infrastructure, like books.
  • They’ll evaluate your reputation.
  • They’ll search the web to see if you have positive buzz.
  • They’ll see how long you’ve been around, and they’ll try to evaluate whether you’re profitable and successful and likely to stay around to continue supporting the product.
  • Oh, and if they have a few minutes left over, they might actually look at your product itself to see if it works.

And that explains why people buy overpriced but useless shelfware that costs $millions and doesn’t really work. They rationalize that if they install it, they’ll be shielded from criticism and other mercurial notes of anger.

Anyway, before we could launch FogBugz, even after the final shipping bits were perfect and ready to go, we had a list of things we wanted to have ready to make the product experience complete. For FogBugz 4.0 the big things were:

  1. Professional-quality graphic design in the user interface
  2. An online demo that included every feature of the product
  3. An online movie that introduced the product for couch potatoes
  4. A great marketing website
  5. Getting at least one book about FogBugz into bookstores
  6. Making a real physical product available on CD-ROM

Graphic Design

Human emotions can be really, really superficial. In particular people ridiculously overvalue aesthetics and beauty when evaluating products. It’s one of the reasons iPods, and, for that matter, Keanu Reeves, are so successful. If you have a product that is functional but not beautiful you have a really, really, really, really, really, really, really, really, really, really big handicap to overcome against the product that is beautiful but maybe not so functional.

Given the importance of this I spent days looking at portfolios of web designers. I happened upon CSS Zen Garden, which was new at the time, the effort of Vancouver-based graphic designer Dave Shea who wanted to prove that CSS did not imply ugly boxy design. In those days there were only a few designs available on Zen Garden and a lot of them were done by Dave himself, but they were all stunning. (Here’s one I particularly liked).

So we hired Dave to do a redesign of FogBugz.



OK, now all the programmers in the audience are saying, “what? I don’t get it?!” I know. I don’t either. But the new user interface looks and feels, well, 5% more “quality,” whatever the heck that means, and it’s all very nebulous and vague but I can tell ya everyone has been saying it’s the cat’s pajamas, so I’m happy.

Online Demo

The online demo speaks for itself, but we had to do a lot of work to make it possible to host hundreds or thousands of instances of FogBugz in one directory.

In particular we were afraid that one spark of good publicity would result in hundreds or thousands of people setting up new trial accounts simultaneously, which would whack the poor servers and result in a lot of potential customers thinking FogBugz was slow simply because they were trying it on an overloaded server. So we changed the trial signup procedure to include a throttle that, under peak load, allows us to slow down the creation of new trials. Occasionally, it may mean that a potential customer has to wait a few hours to try out the software, but it’s better than everybody having a bad experience.

The Online Movie

One product I just can’t stop singing the praises of is Camtasia Studio, by the folks at TechSmith in Okemos, Michigan. It lets you “film” your computer screen, all in software of course, then edit the film, add narration, then squeeze it down to a very compact flash movie you can put on the web. This is a beautiful piece of software. It does exactly what you need, works the first time, and comes with great documentation you’ll never need.

I used Camtasia Studio to record an introduction to FogBugz 4.0 in movie form. The whole project took me about one day. If I had to make another movie, it would only take a couple of hours, as I learned many tricks along the way. For example the first recordings I made sounded terrible. Our offices are in New York City and a lot of street noise drifts up to us here on the 18th floor. It’s not enough to notice during the day but when you’re trying to record something, the muted sirens in the background are shockingly unprofessional! To make things worse, we have hardwood floors throughout the office and don’t have those yucky acoustic tiles on the ceiling, so the office is acoustically live in a way which made the movie sound like I was in a big abandoned warehouse, down by the river, waiting for Kojak to arrive with a lollypop.

I gathered up all the rugs and pillows I could find at Fog Creek and moved them all into my office. With a big rug on the floor and giant sofa pillows lining every wall, the sound quality was vastly improved. In fact my office was so pleasant with all the sound-absorbing stuff that I realized it’s not enough to have quiet offices; you want to have acoustically dead offices as well. For our next office space I think I’ll specify thick carpeting for the private offices, even if it’s not as cool as wood floors. We’re seriously considering hiring Aviva Stanoff to come up with some kind of framed pillow arty thing to put on the walls to deaden the sound even more.

The Website

Our websiteUm, yeah. We threw this together at the last minute. We did manage to find a few good-looking FogBugz customers to give us testimonials so we could replace the crappy stock photography with pictures of actual humans, and Dmitri found a great old picture of some craftsmen making violins. I spent a lot of time putting together a screenshot tour because a lot of people look for the screenshots first when they’re learning about a new product.

FogBugz, The Book

Different people learn different ways. I always want to dive in and start using a product, but some people prefer learning about a product in a classroom, and others prefer to read a book. I’ve even heard people say they won’t use any development tool until there’s a genuine book about it in bookstores. A real book from a real publishing house is one of those things that makes a product “feel” real.

I had been incredibly impressed by Mike Gunderloy’s classic book Coder to Developer, about all the things that a full-fledged software developer needs to do above and beyond the basic work of writing lines of code, and Mike has been working with FogBugz since version 1.0, so I persuaded him to write a book, which Apress published.

Painless Project Management with FogBugzThe reason I like Mike’s book so much is that it’s not just a rehash of the online documentation, which is pretty detailed to begin with, and it’s not just a big wasted list of steps for filling out dialog boxes. Instead Mike’s book focuses on how to manage software projects using FogBugz effectively, so it adds a lot of useful material. In fact I liked the book so much I ordered a thousand copies, which we’re selling along with FogBugz. Probably 20% of new FogBugz customers buy a copy or two of the book, and it’s also good to have around as a handout for potential large customers.

(By the way, if you’re a Mike Gunderloy fan like me, you’ll be delighted to see that he has recently relaunched his website Larkware as a daily source of news about programming technologies.)

FogBugz, The CD-ROM

One of the nicest things about selling software is that there is no physical product, but I’m kind of old fashioned, and whenever I buy software online, if there’s an option to receive a physical disk, I usually take it, just so I can have something physical up on the shelf that I can find if I ever need to reinstall the software. I can’t tell why but somehow having the option of a physical product makes the software feel more tangible and therefore worth more money. It’s a great mystery to me why this is the case but I’m sure anthopologists would not be surprised.

Since we already decided to sell physical products, i.e., the book, we needed to get set up for shipping physical products anyway, which meant inventory, postage meters, UPS accounts, and all that stuff, so I figured, against my better judgement, that it couldn’t hurt to make CD-ROMs available as well.

Primera Bravo II Disk Publisher ThingamabobThe FogBugz CD-ROM is entirely manufactured at Fog Creek, using a robotic combination CD-ROM recorder/inkjet printer which records and prints the CD-ROM without human intervention. We put them in DVD boxes, which are a little bit classier than CD-ROM Jewel Boxes. So far it looks like we’re shipping two or three a week to customers who opt to pay an extra ten bucks for physical media. It’s hard to tell if it’s worth it. Somehow I think that having a real packaged product makes FogBugz “seem” more real even if almost nobody orders it, but again, maybe that’s just me being old fashioned.

Tomorrow, the aftermath!

The Road to FogBugz 4.0: Part III

One day in the summer of 2003, after my friend Uday had finally told me for about the 17th time that he would have bought FogBugz but they didn’t have any Windows servers to run it on, I decided to figure out a plan for getting a Unix version. We had looked into Chilisoft, an implementation of ASP and VBScript that runs on Unix, but we didn’t like that idea much because at the time it cost something like $1000 per server and that wouldn’t be acceptable to our customers, who could have bought a whole ‘nother Windows server for not much more than that.

One morning walking to work I thought, gosh, it would be cool to have a summer intern, and I could tell the intern to write an ASP compiler that generated PHP as its output. Then we could produce a Unix version of FogBugz from our source code automatically, and as we added new features to the ASP version, they would magically show up in the PHP version without any more work.

Lo and behold that day this kid named Jimmy calls up the office. He’s just back from Junior year in Italy and he needed a summer job. When I gave him one of my (unpublished!) interview questions (don’t look for it online, you won’t find it) he answered it in exactly the same way as I had answered the same question when Brian MacDonald asked it to me for an internship at Microsoft back in 1990. All the same false starts, the same initially-wrong answer, and eventually, the ideal answer, Jimmy was sounding like a clone of me.

Against my better judgment, knowing myself, we hired him for the summer, and thus was born the Fog Creek Summer Internship program.

Jimmy didn’t know PHP, or ASP, or Java, really, but we thought Java was a good implementation language for an ASP to PHP compiler, so he dealt. Within a few weeks we had something up and running. By the end of the summer it was pretty decent, running FogBugz like a champ, although after Jimmy went back to school, getting all the tiny details right took Michael another couple of months.

I keep calling this thing an ASP to PHP compiler, which leads many people to email me saying “don’t you mean translator?

Let me explain.

In computer science jargon a translator IS a compiler. It’s exactly the same thing. Those are synonyms.

In common usage, people think of a compiler as generating machine code, but it doesn’t have to. Java and .NET compilers generate bytecode, for example. And Stroustrup‘s first C++ compiler, called Cfront, actually generated C code because C was portable and this made it possible to run C++ on any system that had a C compiler. When you’re inventing a new language it’s a waste of time generating machine language output for every architecture when you can just generate nice messy C code and let cc generate the machine language and do all the back end and optimization stuff. Cfront was terribly confusing to a lot of people because it was often referred to as a “preprocessor,” so people got the feeling that C++ was just a clever set of macros that use the old-school C preprocessor cpp to generate C code. Nothing could have been farther from the truth. There’s no way you could use the simplistic C preprocessor to convert C++ to C. Cfront was a complete, genuine compiler, with all the classic parts of a compiler: a lexer, a parser, an abstract syntax tree, etc., but instead of outputting machine language which would only work on one CPU, it output terrifying, yet perfectly portable, C code.

And that’s what our ASP to PHP compiler, Thistle, does. It’s a complete compiler, not a bunch of glorified regexps, which lexes and parses a VBScript/ASP program, creates an abstract syntax tree in memory, and then generates an “executable program” which happens to be in PHP. So I’ve been calling Thistle a “compiler” sort of to make a point, but mostly because I’m a pedantic windbag who can’t resist the opportunity to teach a little lesson to the younguns who think that a compiler has to generate machine code.

Windbagginess aside, I always get a few questions about Thistle, so I’ll answer the common ones here:

Q. Why didn’t you use asp2php?

The quality of the “translation” produced by asp2php is nowhere near good enough to produce production quality code. On samples we fed it, almost every generated line contained an error. There are some really subtle tricks to VBScript and PHP which asp2php seems to completely punt on.

(OK, you really have to know? In VBScript you can assign an array to a variable one minute, and one minute later assign an object with a default method taking one integer argument to the same variable, so the expression a(1) would translate as $a[1] in the first case and $a->$default(1) in the second case, and it’s the same expression, and this fundamental problem was completely punted on by the designers of asp2php, probably justifiably so. In a moment I’ll tell you how we solved it.)

Furthermore, we had a hard-and-fast requirement that the generated PHP code had to work without further tweaks. That’s because the ASP code is a living thing which changes all the time, and we constantly regenerate the PHP code automatically. If there were any manual tweaks required to get the output of Thistle to work it would dramatically increase the headache of getting a PHP build. So we implemented all kinds of conditional compilation tricks, and since we controlled the compiler, we could build in all kinds of intelligence to make sure that the generated code was exactly what we wanted.

Q. Why don’t you commercialize this great Thistle thing if it’s so great?

Thistle is a compiler that only has to compile one program: FogBugz. That means it doesn’t need to include any logic for any features that FogBugz doesn’t use. There are lots of library functions we don’t have to translate because we never call them. And there are conventions in our code that we always adhere to that allow the compiler to take big shortcuts. That means Thistle would not work so well for anyone else off-the-shelf.

Remember the problem of how to translate a(1), which could mean “look up the 2nd element of array a” or “call the default method of the object a passing the argument 1″ depending on what type a contains at runtime? This really matters, because we use arrays, and because we use the built-in class RecordSet all over the place, doing things like rs(1) which is short for rs.Item(1).Value, and since VBScript is latebound there is no way to know what code to generate in PHP until runtime, and that’s too late! The only correct thing to do in PHP would be to generate code that checks the type of a, and decides, at runtime, whether to do an array lookup or a method call. This is messy and slow and would suck big rocks in the kinds of tight loops where you tend to be using arrays.

How did we fix it? Well, thanks to Hungarian notation, so callously dissed by developers who do would not recognize a superb coding convention if it walked up to them on the Shanghai Maglev train and shook their pants leg, every recordset at Fog Creek starts with the letters “rs”. And Thistle looks for the rs and say, “ah, this is a recordset, you’re not looking for an array value, you’re calling the default method,” and generates fast code. Based on your age you will either call this an evil hack (if you’re young) or an elegant hack (if you’re old); in either case it’s a huge optimization made possible by the fact that Thistle only has one program to compile. Outside of Fog Creek it wouldn’t work. All hail Hungarian notation!

One more reason we don’t commercialize it: it’s a competitive advantage to us allowing us to create server-side applications that run on Windows OR Unix (or Mac or Solaris or Linux) with a single source tree. But that’s secondary.

Q. Are you serious about Hungarian notation?

Yes, it’s standard at Fog Creek. We try to use something called Apps Hungarian notation, as invented by Simonyi, not the grotesque bastard Systems Hungarian notation, misinterpreted by Petzold and the entire Windows team. You can still read the original paper.

In Apps Hungarian you still have the prefixes, but they are supposed to add semantic information, not merely repeat the type of a variable. So for example when you have a buffer size, the variable should be named “cb”, which means “count of bytes”. Whenever you’re writing C++ code that needs to deal with all kinds of strings, it’s really nice to be able to look at the variable name, and if it’s a psz, you know, oh, look, it’s a pointer to a null-terminated string, but no memory is allocated! Or if it starts with rgch, you know it’s an array of characters, with memory allocated, or rgwch, you know it’s an array of Unicode (wide) chars, or if it starts with ix you know it’s an index to something (or a primary key in SQL), etc. etc. It’s really nice when you’re manipulating unicode that cch means “count of chars” while cb means “count of bytes” since a char is not a byte, and if you ever got confused, the variable name sorts you out. And it’s really nice when you don’t remember if you have a pointer to a string or a pointer to a pointer to a string and the “p” or “pp” at the beginning sorts you out, too. Anyway, Hungarian is widely and correctly reviled by people who don’t see the point of putting dw in front of all your longs, although even that was useful in its day, but using “c” for a count or “ix” for an index is quite helpful.

In SQL tables we use very light Hungarian to indicate the type of fields: s for strings, dt for date/time, c for a count, ix for a key, n for a number that is not a count of something or a key of some sort. The most useful aspect of this is that if a table is named Bug then you can be certain its primary key is ixBug, so whenever you’re looking at SQL anywhere in the database if you see ixBug you know it’s a foreign key pointing to the Bug table without bothering to look it up. And now without even thinking if you see this snippet of SQL: “join Bar on Foo.ixBar = Bar.ixBar” you know exactly what’s going on, and if you see “join Bar on Foo.ixFred = Bar.ixBar” then you know it’s probably wrong code because with a little bit of practice the mismatched ixFred/ixBar just jumps out at you.

I’m especially driven crazy by people who keep blabbing on their blogs that Hungarian makes code “less” readable. Yes, it’s less readable if you don’t know the convention, but it takes about 10 minutes to learn the convention and all the important prefixes, and people who whine about Hungarian making code “less” readable have obviously never done this. If you know what the prefixes mean Hungarian makes code more readable because every variable gives you a little bit of free, extra useful information you don’t have to go look up.

Q. How did you handle all the runtime libraries ASP provides?

We reimplemented them — either in VBScript, which gets translated to PHP, or directly in PHP. In most cases there is a very close PHP equivalent so the reimplementation is one line.

Q. What about COM objects?

That was the most work. For our own COM objects we wrote portable C++ code and we compiled that to .so’s for Unix. For one of the major third-party COM objects that we use, we reimplemented it completely in PHP using a built-in PHP library. For the built-ins like Server, Response, Request, Recordset, etc. we created our own classes which usually just call underlying PHP functionality. And our implementation of Server.CreateObject knows all the tricks and just implements a giant select statement that constructs the right kind of object so we don’t need an equivalent of COM class factories.

Q. Was it worth it?

Probably. FogBugz for Unix is about 10% of our sales. The effort to create it was probably 20% above the effort to create FogBugz for Windows alone. A lot of our customers are happier that we run on Unix even if they’re using the Windows version, because they know they could switch servers at any time. And finally we have a certain amount of confidence that if Microsoft ever decided to stop making VBScript/ASP work on their server OS, it would be a very simple matter to change Thistle to generate the new flavor of the week … be it Ruby.Net, Eiffel, C#, or this Language.

Tune in again tomorrow, when I’ll talk about all the other stuff we did for FogBugz 4.0 to make it a complete product, not just a computer program.

The Road to FogBugz 4.0: Part II

A long time ago I wrote an article called What is the Work of Dogs in this Country? about the benefits of eating your own dogfood, a quaint expression in the software industry that means “using your own product.”

We’re totally devoted to the idea of using our own software as much as possible… all my writing is done inside CityDesk (a very unstable developer build, at that, which drives everyone completely crazy), all our development is planned and tracked in FogBugz, of course, and even our customer service operation is entirely supported and tracked with FogBugz, which is why when you email us you always get a reply.

Well, almost always.

About a year ago, I noticed that people were emailing us, sometimes, and not getting responses.

This was not good.

I dug up their messages in FogBugz.

RESOLVED: SPAM, it said. Someone handling the customer service queue had decided that the email was spam and closed it without responding.

When I looked closer, it was usually because the subject line sounded kinda spammy or was blank, but sometimes it was just the proverbial Operator Error.

In the meantime I had been using SpamBayes for my own personal email. This is probably the best implementation of what is probably the best spam filtering algorithm out there: Bayesian filtering, invented by Paul Graham and first published in August 2002 in his seminal article A Plan for Spam. Bayesian filtering learns from experience. When it makes a mistake trying to classify an email as spam or non-spam, you correct it, and it looks for clues in that message so it can do a better job at classification in the future.

And I thought, gosh, here I am paying a college graduate to go through email and decide whether or not it’s spam, and he’s flagging 1% of email incorrectly, when there’s this algorithm called Bayesian filtering which in my experience has far fewer false positives (something like 0.01% false positives). So while everybody is worried about how spam filters might inadvertently delete the proverbial crucial email from a customer, in practice, in the presence of lots of spam, human beings are far more likely to delete a real email than a well-implemented Bayesian filter.

The other thing about the Bayesian algorithm, by the way, is that it has to be implemented in the email client, not the server, because it needs to be taught about what one particular person’s legitimate email looks like. For example when we get email at Fog Creek, the word “FogBugz” in the body of the email is strong evidence that the email is not spam while the word “mortgage” in the body of the email is strong evidence that the email is spam. However if you’re a real estate agent or bank, the word mortgage probably occurs all the time in legitimate email. So basically Bayesian filtering is not going to work unless it knows what messages you deleted as spam and which suspicious messages you recovered. The Ipswitch guys who make a mail server tried to implement Bayesian filtering on the server, because that’s what they have, and frankly that system just doesn’t work.

Since spam filtering needs to be done on the client, and FogBugz is an email client, we decided that spam filtering needs to be done in FogBugz.

Ben KamensNow, all that probability stuff is too hard for me, so we asked Summer Intern Ben Kamens to figure it out. In a matter of weeks he had a beautiful, speedy implementation of Bayesian filtering up and running in FogBugz.

Bayesian filtering is really just a specialization of a long established AI algorithm for sorting documents based on training, and we thought, gosh, why not generalize the algorithm so that in addition to sorting incoming email into “spam,” “suspect,” and “ham,” it also sorted all the ham into piles, for example, “sales,” “tech support,” and “job applications”?

Ben spent a few more weeks studying this and came up with the idea of using a tournament algorithm. He’s a college athlete. They think of the world in terms of tournaments. It worked quite well. With 24 hours of training I had it sorting my own inbox into personal email, Fog Creek email, Joel on Software email, Joel on Software translator coordination email, Subversion checkin comments, bug notifications, and sales reports. Frankly it did an astonishingly good job with 100% accuracy on the obvious emails, like the checkin comments that all had the same structure, and well over 90% accuracy on the hard ones, like telling personal email from Joel on Software reader mail.

I was tempted to try and get it to sort email into messages from Republicans vs. messages from Democrats, but that was pushing my luck.

By the way, the paper Ben wrote at the end of the summer describing his algorithm is here (PDF). This paper is the ultimate rebuttal to those grumpy people who email me, barely able to conceal their disgust, saying, “why do you need to hire such smart people to work on bug tracking software?”

The cool thing about the implementation in FogBugz is that if the sorter makes a mistake, it’s OK. You just correct it and get on with your life, and it learns from its mistake. But in the meantime it saves you 95% of the work directing incoming email to the right people.


We got one other good idea for FogBugz 4.0 from dogfooding it.

As long as FogBugz has had the ability to receive mail, all customer service email sent to Fog Creek goes into our own FogBugz database where anyone can answer it.

Over time I’ve come to notice the occasional customer who thought we were being rude to him in an email message. On closer examination, we weren’t being rude, but the email we sent seemed rude, and it was usually because it was incredibly terse and to-the-point. We decided that instead of sending emails like:

Yep, this is fixed in the latest version.

… we should be sending emails like:

Hi! Thanks for writing to us. I think I know what you’re talking about, and it’s definitely a bug in our product. The good news is: it’s fixed! You can download the latest version by logging onto our online store at with your order ID number and email address, and that should solve this problem once and for all. If you don’t have your order ID number just let me know and I’ll be happy to look it up for you, or call us here at the Fog Creek office at 866-FOG-CREEK.

Please let me know if there’s any other way I can be of assistance!

All the best,

(signature of a real human being)

It’s sort of like translating from English to Japanese. I have never been to Japan but my father, a linguist, once told me the story of the train station in Tokyo, where the announcements were made in Japanese and English. You would hear four or five minutes of nonstop Japanese and then the English translation would be “The train to Osaka is on platform 4.” It seems that in Japanese there is simply no way to say something that simple without cosseting it heavily in a bunch of formal etiquette-stuff. And it turns out the same thing applies to email messages, even in English. The moral of the story is that given two email messages with the same semantic content, the terse one is more likely to come across sounding rude. But given the amount of email correspondence we have to deal with here, we don’t have time to be Emerson on every customer support email.

Thus was born the idea of snippets: canned bits ‘n’ pieces of email that you could insert into an outgoing reply with a few keystrokes. The theory is that you define a snippet like “Please let me know if there’s any other way I can be of assistance” and then assign it to a short code like “2”. Now while your composing your reply, you just hit 2 and then press the backquote key ` and (ding!) it is instantly replaced with the long text it represents right in front of your eyes. It’s really cool and it saves a ton of time and allows us to produce the verbose email replies that are less likely to be misinterpreted. We have built up an extensive library of snippets for all kinds of “faqs” and common parts of email messages.

In tomorrow’s installment of The Road to FogBugz, a look at Thistle, our proprietary ASP to PHP compiler/translator.


We use FogBugz extensively internally to handle company email, and the process of using FogBugz ourselves (“eating our own dogfood”) motivated us to add Bayesian spam filtering, and a “snippets” feature to make it easy to enter common phrases and even entire messages in replies to frequently-asked questions.

In today’s installment of The Road to FogBugz 4.0, a look at two new features that came out of dogfooding.

The Road to FogBugz 4.0: Part I

The Old Office.It started with a phone call from a customer, back in the old office.

Most of our customers, thankfully, understand that the idea here at Fog Creek is to make shrinkwrapped, off-the-shelf software that you buy for a low price and it already does what you need, and if it doesn’t, well, we’d like to hear about that, but for $99 you’re not getting a customized version of the software, sorry.

Some of our customers still think we’re one of those big enterprise software companies where you call them up, negotiate with a salesperson for three months, and, on the last day of the fiscal quarter, force the salesperson to promise a long list of new features in exchange for a half-million dollar contract.

That’s nice, but we don’t have salespeople and we’re not one of those vendors. Our customers are happy that our price point is low but not all of them quite understand the implications. They ask us to fly out to their headquarters to give a demo of the software to their development team. They send us long spreadsheets with lists of features and ask us to check off the features we support. They even send us RFPs (shudder). RFP stands for “Request for Proposal.” It’s a request by a large company for a custom proposal from a small company. The small company works on the 200 page laser-printed proposal like mad for three weeks and Fedexes it in great expense and at the last minute, where it gets put in the trash because the large company has their favorite vendor who takes them on a helicopter to Atlantic City on junkets involving blackjack and strippers, and who is going to get the contract no matter what, but someone in purchasing for some unexplained reason, maybe he’s bucking for a promotion is insisting that the proposal be opened up to “competitive bidding” and the small company has been chosen as a victim to write up a proposal that has no chance of being accepted just to make the process look a little bit less corrupt, and if you’re a small company, I would recommend that you don’t fall for it and don’t spend any time responding to RFPs unless it’s already understood that you’re going to get the contract.


The good thing about such customers is that they give us useful feedback about what features we should be adding to FogBugz. One of our mantras here at Fog Creek is “Listen to your customers, not your competitors.” So when we get calls from potential big customers we listen.

Back then, early in the planning stages of FogBugz 4.0, the call was from a large not-for-profit organization. They were considering using so many copies of FogBugz that they needed a way for department managers to see their own departments’ cases in one place, even when each department managed multiple projects.

Departments Summary in FogBugz 4.0The short term solution would have been for us to add a table of departments and make a report based on departments. But we’re an off-the-shelf company, and when we do something, we want to do it in a general way that’s useful to a lot of customers. So we took a little bit more time and designed a more general feature and solved a large class of customer problems with one feature. In addition to customers who wanted things sorted out by department, we had customers who were typical consulting shops and wanted to sort things out by client. Most of these customers wanted privacy features so their clients could access FogBugz without seeing any other clients’ bugs. And many of our customers were small shops with ten or twenty users who couldn’t care less about departments, clients, or privacy features, so whatever we did needed to be implemented in a way that would have zero impact on customers who didn’t care. The last thing we need is for FogBugz to become big and unwieldy because it has a lot of features and fields you don’t care about.

So, OK, it took a little bit of time to deliver this feature to this particular customer. From that phone call to the time we delivered an alpha release to the customer with the new feature about twelve months elapsed. That’s more because we’re still oriented around big major releases every year and a half. I justified the reason for this schedule in the article Picking a Ship Date.

Many of the other features in FogBugz 4.0, which we finally shipped on February 22, were based on customer feedback, too. We kept hearing customers asking how to attach screenshots to a bug. “Oh, it’s easy,” we said. “Alt+Print Screen, run paintbrush, paste, save as a file somewhere, run your browser, go to the FogBugz homepage, hit “New Case,” describe the case, click the file browse button, and find the file you just created.” What could be easier?

Maybe it could be a bit easier.

FogBugz 4.0 Screenshot Tool.Finally I thought “how hard could it be to make a little taskbar lint icon thingy that grabs a screenshot and makes a bug out of it?” Not so hard.

I got the Windows version done in The Proverbial Weekend (defined as one weekend to get it working, two weeks to fix bugs, another week to rewrite it to workaround new bugs introduced by a patch to Internet Explorer). Daniel Berlinger knocked out the Macintosh version in REALbasic in a couple of weeks. And now entering a bug that you see on screen is a matter of two clicks.

It’s great.

I’ve found that about 30% of the bugs I enter can be completely described with a screenshot. Here’s a complete bug report I entered on Monday:

The red rectangle comes from a highlight tool built into the screenshot program. The “wha?” I typed was probably overkill. If I had been willing to live with an untitled bug this entire bug report could have been entered with four clicks and a drag (that sounds like a good name for a band: “Four Clicks and a Drag.” Or the Fog Creek development team, now that I think of it.)

The thing is, as far as I know, not that I pay close attention, none of our competitors has this feature.

If one of our competitors think this is cool, they can copy us, but it’ll take them a while, especially if they read my site and bought my line about only shipping every 18 months.

No amount of listening to our competitors would have motivated us to do a screenshot feature. Our customers didn’t think to ask for it, but we did notice that they kept asking for ways to attach screenshots, so that’s what we did.

Come back tomorrow for Part II, in which I talk about dog food.


This week, I’m going to be running a five-part behind-the-scenes look at the development of FogBugz 4.0. Each morning I’ll post a new installment.

FogBugz 4.0

Today, in The Road To FogBugz 4.0 Part I, I’ll talk about a couple of major features we added after listening to customer feedback, and why our mantra is to listen to our customers and ignore our competitors.



Until now we’ve been hiring rarely and quietly, but lately our sales are so strong we can’t quite keep up.

My old theory of hiring was to post a job listing on Monster or Craigslist and then sort through the massive pile of unqualified applicants in hopes of finding the needle in the haystack.

That hasn’t worked so well. In the future I’m going to try putting up semi-permanent job listings for all the kinds of people we might hire on the Fog Creek website and see if that gets us a slower trickle of more qualified job applicants.

Filmmaker Wanted

We are looking for a talented filmmaker, student or experienced, to make a documentary about the software development process this summer. If you think you’re interested, read on for more details!