If you spend just a few minutes on Hacker News, you’ll come across Patrick McKenzie in one way or another (I’m convinced that he must comment on every single HN post). He lives in Japan and recently left his cushy full-time job to focus on Bingo Card Creator — something he created as a side gig four years ago. Patrick’s always sharing tactical tips on HN but I wanted to know more about how BCC actually worked. If you’ve built something on the side and you’re trying to extract more money out of it, keep reading — this one’s for you.
Elementary schoolteachers like playing bingo as a review activity, because it scales to any number of students, is fun while remaining educational, and proceeds at a predictable pace. However, every student needs a unique bingo card to play. Making cards by hand takes a while, buying them costs a lot of money. Bingo Card Creator makes bingo cards quickly and cheaply for schoolteachers, and other folks who are interested in playing custom bingo games.
There are two versions of the software. One is the original downloadable Java application. The other version is a web application, written in Rails. They’re sold as a set, for $30 (plus $5 if you want a CD). This is a one-off purchase.
While working at my ex-ex-day job, at a prefectural technology incubator, an English teacher connected to us asked whether I knew of a good way to make bingo cards. I told her to Google it. She said that she did and couldn’t find anything useful. One thing lead to another and, well, here we are. (Here’s the full story.)
When I created BCC, I was 24 years old and had graduated from a “Java school” and then spent a few years with 90%+ of my development experience being fat client Java applications. You know the line about how if all you have is a hammer, everything looks like a nail? Bingo cards, yep, totally a nail. In retrospect, web applications are much, much, much, much better from the developer’s perspective (if you’re interested, my thoughts on desktop vs web apps). However, at the time I could not make web applications.
Some time after releasing BCC, I switched jobs to a company which make Big Enterprise Java Web Applications, and concurrently taught myself how to use Rails. (Incidentally, teach yourself to use Rails if you work on *any* MVC architecture: it will greatly clarify your thinking about MVC in general. I became a much better Java programmer through my exposure to Rails.) I started expanding the website for my product, first creating content at scale highlighting the usage of the product, then creating a custom CMS to make it easier for freelancers to create content, and eventually integrated web-enabled features on the downloadable application and launched a web application.
As for why BCC is a one-time purchase: back in 2006 I had the traditional developer’s skepticism of many effective ways to make money. One of these is recurring charges. I also thought my customers were used to recurring charges in their industry and hated them, so a one-off purchase would be a point of differentiation. Certainly, some customers do genuinely hate recurring charges, but I will certainly have them as a core feature of any software I produce in the future. The business benefits are just incredible.
I have approximately 3,000 paying customers for my software. You know what my revenue was for today? *Nothing*, because we’re in the dog days of summer, and sales slow to a crawl until school gets back in session. If there were any recurring component to the revenue from BCC, that would essentially smooth out performance over the very seasonal calendar, and also continue to reward me for previous hard work.
I’m currently using a Dell Studio notebook, which I bought two months ago to celebrate going full-time. Most importantly for my business, it has a SSD drive (128 GB of lifechanging speed — buy one today if you don’t have one) and a copy of VMWare Workstation, which lets me switch seemlessly between Windows and Ubuntu running in a VM. I prefer Windows as a client OS, and love Windows Seven. (And I just lost any chance of speaking at a Rails conference in the forseeable future.) These days, most of my development is done in Ubuntu, because I use too many server-side things which are hard to fake on Windows.
I use NetBeans for Rails development and Eclipse for Java development. My preferred browser is Chrome, and I keep Firefox around for superior add-on (Firebug, YSlow, ShowHTTPHeaders, etc) support and IE around for testing, though I prefer IE to Firefox. (Darn, I am burning the bridges today.)
I use an 812SH Sharp phone, which is a Japanese featurephone. My main use of my phone is to send text messages to friends and receive phone calls, although it also has a (crippled) browser which is sufficient to operate my site’s admin interface. I take my Kindle everywhere I go, and use its built-in browser for light browsing, such as checking email or reading Hacker News.
You can see my whole workspace in the attached photo. The $1 notebook is from Muji, probably the best designed of a series of $1 notebooks I have owned. I use it for project management, technical documentation, and todo lists. I also use my blog as a public repository of “What was I thinking when I did that?!”, and it has saved my bacon more than once.
I use Gmail personally and Google Apps for my business-related email. My email workflow is very simple, owing to many years of running this business on a part-time basis: I check it when I wake up and bfeore I go to sleep, and immediately answer any emails from customers, and address emails from non-customers (for example, startups asking for advice) as time allows. The time difference between Japan and the US means that most customers get emails within 5 ~ 9 hours of their email. I tell my customers that I generally aim at answering all questions within one business day, and I meet that goal in excess of 99% of the time.
I use a variety of web services to handle various aspects of my business. Many of them will be discussed below.
At any given time I have approximately three or four VPSes at Slicehost. All use Ubuntu. The largest one, currently 1.5 GB, is for Bingo Card Creator. I run all of my PHP-using sites, such as my blog and mini-sites, on a separate 512 MB VPS. These are physically separate because I trust WordPress about as far as I can throw it, and also because Apache has a habit of taking down memory-constrained VPSes when hit by large amounts of traffic, and if that took down my site as collateral damage many people would be annoyed with me. I also have another VPS for Appointment Reminder, currently at 512 MB while in development.
Bingo Card Creator is a Rails application, running behind Nginx (the best webserver ever) proxying to four Mongrels. This is largely because that was the best practice back in 2007 when I created it, and I’ve had no impetus to change. In addition, there are two DelayedJob workers running constantly — these primarily do PDF (bingo cards) and image creation (live previews of bingo cards for display via AJAX), and secondarily handle talking to external APIs such as Mixpanel.
Most of my customer data is in MySQL. I also use Redis, primarily for non-permanent persistent data such as A/B test participation, and Memcached as a generic scratchpad and cache.
BCC has a fairly sophisticated monitoring setup, because I hate downtime with a burning passion. The processes are monitored by god and Scout. Should anything untoward happen, Scout sends me an email, and Google sends emails matching certain subjects (implying critical issues, such as the site being totally unavailable or the DelayedJob queue going out of control) directly to my cell phone. My cell phone has a custom ringtone for receipt of those emails: Ride of the Valkyries. I chose it because it is intensely disturbing to me, would certainly wake me up, and yet would not unduly embarass me if it were to ring in public.
I take payments via Paypal and Google Checkout. Both are wrapped for me by e-junkie, a payment processor who offers a custom cart (which I no longer use, but which is a great first option for folks who can’t program their own) and which handles Registration Key delivery, accounting, and wraps callbacks in a consistent API. I originally used them when this was all beyond my capabilities, since I couldn’t do web programming. As time has progressed, I’ve gradually brought many of their functions (such as accounting / customer records / search) in-house.
One other thing e-junkie handles is API calls to SwiftCD for customers who order CDs. It happens totally transparently for me: if the customer requests a CD, I don’t have to do anything. SwiftCD burns an image I’ve uploaded, mails it directly to the customer, and invoices me at the end of the month.
I handle all customer support by myself, using email. (I have made two phone calls related to Bingo Card Creator in four years. Customers frequently request that I call them. I have no desire to do so, because $30 a sale is not enough for me to walk technically disinclined customers through a Java installation at 4:30 AM in the morning. Most are quite happy when I resolve their issue over email and tell them that, as I’m in Japan, it would be inconvenient for them to have to call me. Since the vast majority of my customers have never made an international phone call, that explanation works for them much better than “Basically, it makes little economic sense for me to speak to you about this.”)
I am a metrics junkie. At present, I use Mixpanel for funnel tracking, Google Analytics for basic web statistics, Clicky as a backup to Google Analytics, and CrazyEgg. CrazyEgg lets you know where people are clicking on your website. It has repeatedly made me thousands of dollars by showing obvious visible evidence of suboptimal page design. I highly recommend everyone use it.
I use A/Bingo, OSS Rails software which I wrote, to do A/B testing.
I am a heavy user of Google AdWords, mostly on the content network. You know all those pages Mahalo / About.com / Demand Media / etc have which satisfy every query a Kansas schoolmarm could possibly ask? If one is about bingo, you’ll probably find my ads on it. AdWords is my #2 source of customers after organic search. It is responsible for approximately half of my sales and 1/5 of my profits. (I do a bit of work these days to measure this in a more systemic manner than AdWords will by default. For example, if you Google [math bingo cards] and arrive at my math page via the organic listings, then sign up to my trial, and later Google [bingocardcreator.com] and click the AdWords link, Google will score that as a conversion for AdWords. I only score conversions for AdWords if the customer found me through AdWords prior to signing up for their trial, regardless of how they use Google as navigation after that.)
I have published a variety of stats but I don’t watch metrics on a daily basis because I don’t make metrics-based decisions on a daily basis, and absent making decisions watching metrics is only as productive as playing WoW. When I have to make decisions about upcoming development priorities or marketing decisions (such as what keywords to look at), I look at my keyword data (Analytics), previous popularity for word lists on my site (homegrown), and A/B tests. A/B tests are sort of the holy grail of metrics, because they are *designed* to result in data that tells you something which you can use as the basis for a decision.
Pop quiz: Analytics said your conversion rate went down. What do you do? Answer: nothing, because you have no clue why. Maybe you spend a few hours digging into stats and trying to retrofit an explanation onto the data, which is probably just deceiving yourself. Pretend that instead you A/B tested blue buttons versus green buttons. Blue buttons won. What do you do? Exactly, you use the blue buttons. A/B tests are actionable by design. That is why I’m so enamored with them, and why I *had* to create a better way for Rails developers to use them.
A/B tests also have a very nice property for time-constrained businessmen: you code them and then let them run while you do other things, then check them. Coding and checking is fast, and letting them run doesn’t block progress (or participation with your family, the day job, or what have you).
One metric I do watch is sales, particularly YOY change in sales (this tells me whether the business is growing when adjusted for seasonal distortions) and “predicted sales this year”, which is partially a vanity metric (that is my score at the game of business, and I love playing games) and partially lets me make consequential decisions such as “How much do I get paid?” and “Can I afford to leave my day job?”
The image on the right is what you see if you log into my website as me. At the top left you’ll see quick links to common tasks, from using my bingo card CMS to linking to my version of various stats. (They’re typically similar to the publicly available versions, with more detail. For example, I can show data more granularly because I don’t have to worry about private customer data leaking.)
On the left side you’ll see a few stats I use as a quick business health check, like login counts for this week. Invitation Stats shows the status of a project I tried, where I created Dropbox-inspired double-sided incentives for inviting your friends to join the service. As you can see, it has not been a resounding success.
Sources of sales shows a quick overview of who is sending me customers that convert lately. (“nil” is #1 largely because I wasn’t tracking this until recently.)
Vanity Stats is on the dashboard purely because it brings a smile to my face. I used to be a teacher, and even in my best year I rather doubt that I contributed to 600,000 lessons.
The main pane of the dashboard is search results, which I use for customer support. By default it shows the last ten customers, because people are overwhelmingly likely to ask for support their first day with the product. It is optimized to my most common problems: “What is my Registration Key?”, “What is my password?”, and “I’m seeing something funky. What is up?” (Clicking on “Ghost me” logs me in as them, which often lets me diagnose the issue instantly. I love web applications.)
You’ll also note the quick&dirty sales projections. These are intentionally not that sophisticated: if I sold $100 on the first day and there are 30 days this month, then it will project $3k in sales for the month. Currently it is showing $4k in projections for a June, which I would be flabbergasted if that came to pass, but after a week or so it typically converges on a fairly accurate number for most months without a major holiday.
I also have a physical dashboard in my room which displays some other metrics, mostly for personal motivation.
I’m going to back up a step, because the vast majority of my sales start in the free trial, either the web app or the downloadable version.
In the downloadable version, the customer probably just hit a trial limitation. They’ll be shown a message much like this one:
If they click Yes, the program will generate a random ID within the Java application, and open their default browser to a particular page using that ID as a query parameter. Rails will stuff that ID in the session, then show them the purchasing page. The shopping cart on the purchasing page contains a link to e-junkie, including a parameter e-junkie will pass back if they receive a transaction notification from Google or Paypal corresponding to that link.
Let’s pretend that the customer clicks purchase. They’re transparently redirected through e-junkie to the payment process they selected in my shopping cart (Paypal or Google Checkout). They fill out their payment details, and I get money deposited in my account.
Paypal or Google Checkout then pings e-junkie with a very large, complicated API containing all the details of the transaction. e-junkie turns around and pings my server with the details of the transaction, twice. Once in requesting the Registration Key for the customer, and once to register the fact of the sale.
As soon as my server receives word of the sale, I look at the session ID e-junkie gave me, and determine what session it belongs to. Then, I check to see if they had that random ID passed by the Java application. If yes, I write a key in memcached recording the correspondence between their random ID and their Registration Key.
While this was going on, their copy of Bingo Card Creator has been relentlessly polling the server: “Has she bought it yet? Has she bought it yet? Has she bought it yet?” It does this by passing the same random ID to a web service running on the server. If the transaction has been consumated, BCC will learn the Registration Key, and then automatically upgrade itself to the registered version. This removes a *major* source of customer support complaints, since Registration Key management is a hard concept for many shareware customers to grasp. From the customer’s perspective, she just got done putting her details into Paypal, and by the time she closes the browser (after ignoring the instructions) and goes back to Bingo Card Creator, it already says “Thanks for your purchase!” That little psychic saves me hours every month in support email.
The process is quite similar for the online application. (You’ll notice that this test account has participated in the Refer a Friend program a few times and has a quote of 20 cards, rather than the 15 cards that most folks start out with. That referral program has not been a success.)
If you purchase while signed into the online application, the link to e-junkie contains an identifier for your account. I look it up when I receive the purchase confirmation, and transparently upgrade the account to the registered version. There is a manual way for customers to upgrade accounts, too, for those who use it at home but purchase at school from a machine I’ve never seen before, and for similar cases. The vast majority of customers get instant, automatic gratification though.
In addition to handling the registration, my site also creates bookkeeping entries (in my home-grown bookkeeping software — there was a remarkable dearth of stuff which would produce publicly visible sales reports) and entries in my customer records so that I can conveniently look them up for support purposes. Prior to developing these systems, I used the ones at e-junkie. They were perfectly adequate, but that is one more login to have to do to accomplish any customer support task.
The time IE 6/7 users couldn’t sign up, lasting for the busiest month of the year, has got to be up there.
There are many, many things that I’ve done which were suboptimal in retrospect, but I don’t necessarily consider them mistakes. Doing a desktop application was suboptimal, but I couldn’t have delivered a web application at the time. I am currently on my third “second” product, having done a bit of work on numbers one and two and then discovered that they were unlikely to be successful. I have a list of failed A/B tests too long to fit into this already overlong interview.
I have consistently underestimated how far this program would eventually go. For example, prior to leaving my ex-ex-job (which was a cushy 40 hours per week endeavor with little professional growth) to become a salaryman (which taught me a lot of things at the expense of 2.5 years of my life), I was offered the opportunity to recontract for two years. I declined, feeling that I was going to better things as a salaryman. At the time, I considered it beyond fantasy to go full-time just on BCC. Knowing what I know now, could I have used much longer nights and weekends to grow the business, develop another product, and go full time a bit earlier with less work-related stress? Probably. But I don’t really regret being a salaryman — it makes for a great story to complain about.
DO IT. LAUNCH IT. GET IT OUT THE DOOR. I don’t care if you think you can’t code. You can learn. I don’t care if you think you can’t market. You can learn. I don’t care if you think there is no market for your product. You can grow, expand, and pivot. (And besides, what are you working on which is more niche than bingo cards for elementary schoolteachers, anyhow?)
Running a business is the best possible training for running a business. So stop making excuses — believe me, I was a champion at it — and start running a business. By all means, read blogs, talk to people, scheme and dream… but then go get your hands dirty.
In the entire history of the world, there has never been a better time to start a business than right now. You can run a multinational software business with thousands of customers. It isn’t rocket science. A confluence of things — OSS, scalable distribution like organic SEO, AdWords, Facebook and friends, powerful APIs like Paypal or Twilio that let you hook into massive enterprise power without leaving your kitchen — is making it even easier with each passing day. So start learning now. Every day you’re working, you’ll be building the knowledge, tools, connections, SEO juice, capital, and audience to make an even better go of things tomorrow.
Prior to running a business I ran a WoW guild. It was rather substantially more work and more drama than running a business, for dramatically worse loot.
If you haven’t started a business yet, you’re saying that everything in your life right now is more important to you than having a business. Ask your heart of hearts: is that really true? If you’re booked solid with your children, then yes, absolutely put your children first. But if you *say* you’re booked solid with your children and yet you still find time to watch television and play online poker, then it is time to have a frank discussion about your true priorities in life.
Jeebus, is there anything else I can add to this? Patrick’s kicking some serious ass and, this is the best part, is openly sharing the details of how he does it.
Yeah, I think you need those s...
Absolutely agreed. After havi...
That's the problem, it shouldn...
Agree 100%, but it seems that ...
Congratulations and all the be...