A/Bingo 1.0.0 Official Release

Back in August I released A/Bingo, an MIT-licensed OSS Rails A/B testing framework.  I have been using it continuously on Bingo Card Creator, and judging from the support requests I’ve been getting it has gotten some traction in the Rails world.  The 5,000 or so people seeing A/B tests on my site on Valentine’s Day are almost certainly less than 1% of the beneficiaries of the software now. Yay.

As A/Bingo has grown in popularity, I have begun to get requests for features that I did not need urgently for my own development, as well as the usual support requests, patches, and the like.  I want to make your use of the software as pleasant as possible to further evangelize the cause of A/B testing, so here you go:

New features:

A/Bingo now ships with a default dashboard.  Previously, I assumed that everyone would be writing their own dashboard code, so I just included the absolute minimum to show you what you’d need to do to get data out of A/Bingo.  Many people have remarked that they would really appreciate a “works out of the box” solution.  Your wish is my command — you can now enable a default dashboard in about ~30 seconds. It would work totally out of the box, but there are security implications, so I wanted you to have to think for a moment prior to enabling it.

#Create a new controller.  The name is up to you -- this example uses abingo_dashboard_controller.rb
class AbingoDashboardController  :abingo_dashboard

You can customize the dashboard code yourself. Nota bene: it uses your application layout, and has CSS classes applied to most of the elements, so you can style it quickly with CSS if you desire to. By default, it probably looks terrible. If you want to send me a patch to make it pretty, be my guest.

Experiments can now be stopped: Using either the built-in links on the above controller or, if you prefer programmatically scripting things, experiment.end_experiment!(alternative_content), you can now stop an experiment without touching the code.  Stopping an experiment causes all users to get the specified alternative rather than what they would have gotten randomly.  It also ceases stats collection.  Stopping an experiment is irreversible (currently — that might change later).  I tried to make this feature not affect the performance of A/Bingo for larger sites — it makes each test require one extra cache access.  (*cough* Rounding error, hopefully.)

A/Bingo internals are now fairly thoroughly tested: Unit tests are not exactly my cup of tea (“Argh, it works in production, what else do you want from me?!”), but Rails developers look askance at software that does not include them.  So I knuckled down and wrote a test suite.  (Hat tip to Nathaniel Talbott for mentioning A/Bingo in a conference presentation.  The constructive criticism regarding testing drove this change.)

I have not written thorough integration tests for the syntax sugar that you get via the included helper methods, but I’ll fix that eventually.

Named conversions: Previously, all A/Bingo tests required one line to add the test and one line somewhere else to track conversions.  Typically, since businesses have very many tests and fairly few conversion events, this resulted in code like:

#A controller method
def purchase
#Business logic goes here.
  bingo!("new_button_test")
  bingo!("email_copy_test_january")
  bingo!("microcopy_test")
  bingo!("button_colors")
  bingo!("login_button_alignment")
end

That isn’t very DRY at all.

Now, A/Bingo will take an optional parameter :conversion (or :conversion_name) when you’re defining a test, telling it to listen to a particular named conversion. This way, you can reuse the same conversion for as many tests as you want, decreasing the lines of code needed to create most new tests from two to one.

def some_method_with_a_test
  @alternative = ab_test("some_test_name", %w{altA altB}, :conversion => "purchase")
end

def some_other_method_with_a_test
  @foo = ab_test("bar_test", %w{coke water}, :conversion => "purchase")
end

def purchase
  #Business logic goes here!
  bingo!("purchase")  #Calls conversions for both of the above tests.
end

A/Bingo handles tests with spaces in them more gracefully: Although I still don’t recommend doing it, A/Bingo has been improving its handling of test names which have a space in them.  (The reason I don’t recommend it is because some cache stores — particularly memcached — do not support this well.)

Official support for Redis: Assaf Arkin picked Redis for his awesome Vanity project (which also does A/B testing for Rails, among other things), which inspired me to take a look into it.  It appears to be a much, much better alternative for a key/value store than Memcachedb, which is what I use for persistence.  A/Bingo has always accepted any cache store that Rails does, but I want to make it explicitly clear that I run tests against Redis, Memcached, and MemcacheDB. Just add the following to your environment:

#Goes in environment.rb
config.gem  'ezmobius-redis-rb',
  :source => 'http://gems.github.com',
  :lib => false

config.gem  'jodosha-redis-store',
  :source => 'http://gems.github.com',
  :lib => 'redis-store'

#Goes in whatever environment you're using:
require 'redis-store'
Abingo.cache = ActiveSupport::Cache::RedisStore.new

I intend to migration my own deployment to Redis when it becomes reasonably convenient for doing so.

Versioning: Previously I’ve just released patches to the A/Bingo git repository when I got done coding them, but I feel that is suboptimal now that there are substantial deployments which I could potentially break with changes.  So, here’s the skinny: A/Bingo is now, as of this blog post, 1.0.0.  I’ll communicate breaking changes by bumping that number up.  If it goes up by a tenth or more, expect that you need to re-run the migrations and that you will probably lose data on any tests in-progress, so plan ahead for that.  Version increases in that last number should be safe to apply directly.

I do not anticipate breaking the published A/Bingo API (i.e. methods mentioned in the docs) until at least v2.0.0, if ever, so upgrading A/Bingo should almost never cause you to need to update your own code.

How To Contribute

I would like to thank everyone who has submitted bug reports and patches. As usual, I’m always happy to get bug reports or feature requests. If you’d like to contribute code, make it available via git anywhere you please, and then send me an email telling me about it.

How Do I…

If the question isn’t answered in the (copious) documentation, feel free to ask me over email. If your business has particular needs for A/Bingo or you just want to talk A/B testing strategy with somebody who breathes it, I’m available for consulting engagements starting April 1st.

You Should Be Doing A/B Testing

I really can’t stress this enough: A/B testing is an easy, reproducible process that you can use to improve your marketing, website copy, product, user experience, etc. If you haven’t started yet, take A/Bingo, Vanity, or your other framework of choice for a spin. It won’t take you five minutes until you’re getting actionable data which you can use to make money.

Comments Off

Using CrazyEgg on Pages Requiring A Login

Long-time readers of this blog know I’m absolutely goo-goo for CrazyEgg, principally because they keep making me money.  They’re seriously my favorite $19 to pay every month, even when I don’t actually use them, because some day I know I’ll get the itch again and then bam actionable insights into what my customers are doing. Today is an itchy day.

One thing I have never gotten around to is tracking how users click on pages in my web application, behind the login screen.  CrazyEgg can do this but you need a bit of magic to let their screenshot bot grab samples of the page being interacted with — otherwise, they won’t be able to match up the events their Javascript recorded with the form fields on, um, your login screen.

CrazyEgg’s current user-agent string is:

Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.4) Gecko/20091016 (CrazyEgg 2 screenshot agent) Firefox/3.5.4

Then just shortcircuit your login procedure for people with that user agent.  (This may be undesirable if you are very, very security conscious.  I sell bingo cards to 60 year old women.  If you are security conscious, email them and they’ll provide a listing of IPs to whitelist.)

In Rails, doing something on the basis of the user agent is easy but, and I know this might come as a surprise, not covered in the documentation.

def authenticate_user
  if (request.env["HTTP_USER_AGENT"] =~ /CrazyEgg/)
    #Whatever you need to do to let them in as CrazyEgg
  else
    #Actual logic goes here
  end
end

For a quick 30 second solution, I signed up as a trial user for my own service with the email address crazyegg@bingocardcreator.com, and have the analogue to the above method on my site just pretend that anybody with the appropriate User Agent is authenticated as that user.

Comments Off

Dashboard Design For Metrics-savvy Software Companies

I have a confession to make: I’m something of a metrics junkie.  I have lost entire days of my life just staring at Google Analytics reports.  Metrics have always activated that same part of my brain that WoW did: ooh, a page view, ooh, a sale, ooh, if this had purple bars on it I’d pay $15 a month.  So I would flip from email to Analytics to e-junkie (the extremely appropriately named payment processor I use) to Analytics to… and end up accomplishing nothing of real importance.

Because although I’m a metrics junkie, I’m a smart metrics junkie.  And any smart metrics junkie can tell you that if your metrics aren’t giving you actionable insights to make decisions that matter to your business, well, you might as well go play WoW for all the good you’re doing.

That’s why, in one of my periodic bits of investing in the business, I built myself a dashboard.

Goals of the Dashboard

A dashboard is, simply, an easy to digest one-glance view on how your business is doing.  Mine is implemented in Rails and it is the page that greets me if I visit my site (password protected, naturally).  The purpose is threefold:

  1. Minimize the time it takes me to do common repetitive tasks.
  2. Show me information about my business at a glance, so that I don’t feel the need to log into my various other sources of info.
  3. Arrange for easy access to drilling down into important things for me.

Like all of my other software, it is a work in progress.  (Incidentally, some folks have offered to buy it when I have mentioned it previously.  I can’t sell it, since it is tied very tightly to my business needs and data available.  At all of ~200 lines of code, though, you can knock one for yourself out in an afternoon.)

Here’s a screengrab from it:

Some comments on what this shows:

Search box (“The Omnibox”): The Omnibox is my Swiss Army Knife support tool.  Given absolutely anything I know about a customer — from her name to email address to transaction number to a (hopefully unique) phrase she has used in her bingo card — it goes off and fetches her customer record.  This is a real timesaver because many of my customers don’t remember what email address they purchased the software under, told Google to obscure their email address (a misfeature in Checkout, if you ask me), purchased with their husband’s credit card, etc etc.  The Omnibox saves me from having to actually do work to find customer records about 80% of the time.  Search results are the same as…

Customer Entries (Latest First): The vagaries of the bingo business mean that I’m overwhelmingly more likely to get a support incident from you in your first 24 hours of use than at any other time.  Accordingly, as soon as I open the dashboard, the last 10 customers pop straight up so I don’t even have to search for them.  (This also serves as a quick visual health check and lets me see if a customer’s transaction didn’t go through.)  This illustrates a core principle of dashboards: do less work, get more done.  Ten keystrokes saved doesn’t sound like a lot until you’ve done it 200 times.

Customer Support Options:  You’ll note some customers have their names in green.  This means they are using the online version of Bingo Card Creator, rather than (or in addition to) the desktop version.  Previously I just made that green to satisfy my curiosity (it gives instant, accurate visual feedback that 70% of my sales come from the online version), but as I got a feel for customer support needs I decorated their records with a pair of hyperlinks.

“Ghost me”: This is the same link you get if you try the Forgot Password function in the online app — one click logs you in.  I right click it, select Chrome’s Private Browsing option (to avoid overwriting my cookie), and suddenly I’m you.  This lets me see exactly what a customer is seeing, so that I can diagnose problems easier, or in a pinch just do what they need done.

“Email password”: The same as the password recovery functionality on my site — mails them a link to let them in so that they can change their password.

Sales Counter: This is only on the page because otherwise I’d a) log into e-junkie to check and then b) start trying to guesstimate how much money I was going to make this month.  Both are bad habits.  Putting it front and center decreased my logins to e-junkie from several times per day to once a blue moon (only when I need to speak with them, which since they run a very tight ship is “Almost never”).

Edit Bingo Cards: Takes me into the original core of the Bingo Card Creator site: a CMS which makes, you guessed it, bingo cards.  This is where I approve work submitted by freelancers, make minor content edits to it, or create new bingo activities.  Again, instant access on the dashboard saves time.  (There are also a few affordances there, like AJAX approval so that all I have to do is mouseover a new card and click OK to approve it.  Do less work, get more done.)

Downloads Per Month: This shows a graph of how many PDFs have been downloaded from my site, on a monthly basis.  It is a quick one glance indicator of how effective my SEO is, from back when I didn’t have the user stats to look at.  I could probably demote it from the dashboard these days.  This information is public, by the way.

All-time Sales: Graph of sales by month.  I mostly use this to check on market seasonality, year over year increase (70%, ho), and whether I’m on pace to make my revenue goals.  This is also public.

A/B Test Results: If you’ve been around this blog much you probably know that I obsessively test and measure.  When I have a particular A/B test on the front burner of my mind it gets promoted to the top of the dashboard.  At the moment nothing I have running is super-critical so they’ve been placed a click away.  You can see some of my A/B test results here — I’m a big believer in code reuse so a portion of my test results are also used for the documentation for my A/B testing library.

E-junkie: Convenience link to my payment processor, where I used to log into a lot.  This should be demoted from the dashboard.

uISV email: The Google Apps for Domains email account I use.  (uISV stands for “Micro-independent software vendor” — i.e. like “small software company” with a more pretentious acronym.)

Logins Today / This Week: This is my “one glance health check” for the business.  I have a rough idea of what these numbers should be.  If they go down far below that, I have broken the login button and need to fix it immediately.  If they go high above that, it must be Halloween.  If they stay flat I might have broken the login button close to Halloween.

Vanity Stats: I keep these around just to satisfy my primal WoW player urges.  They have no particular relevance to my business, but they’re fun to quote to people.

You might think “conversion rate” is a really important number.  See, conversion rate for a channel or a creative or a landing page is a very important number.  Conversion rate for all of your visitors, on the other hand, is very, very sensitive to traffic mix.  Since customers arriving by AdWords always outconvert customers arriving by organic search in aggregate (which is an artifact of my SEO strategy and not to be worried about), a gyration in conversion rate is generally caused more by a change in prospect mix than a strong reaction to a change in my product.

Things Not Pictured

This dashboard can potentially display a few other types of information.  Thankfully, I don’t have an example to show you today.

Exceptions in payment processing: An exception happening in most places in my code is probably a misbehaving spider or a bug.  An exception happening in the callback for successful payments is a bug.  A very critical bug, because it often means that a customer loses access to the software they paid for.  If that happens, the computer sends me an email, my cell phone gets rung, and this whole page gets hidden under a stacktrace written in blaze orange until I hit the “I dealt with it” button.  (This obvious probably won’t happen if the whole site goes down — mon.itor.us watches that for me.)

Regular exceptions get written to my log files.  That is, candidly speaking, where data goes to die.

Bug of The Day: I have a confession to make: I’m not much of a test driven developer.  It is really, sincerely difficult to anticipate every corner case which could happen with customers trying all possible combinations of words and bingo card options.  This causes a huge portion of the user-visible bugs in BCC, and because the symptom is typically “It looks… ugly?”  (for a value of “ugly” not known at runtime) it is sort of hard to capture ahead of time in the predominant Rails testing frameworks.

That’s why I have a wee little daemon who periodically sanity checks all the print jobs people have run recently, looking for anything I’ve identified as the symptom of the Bug of the Day.  Currently, the Bug of the Day is that under certain circumstances the combination of a very long title and a bingo card with four to six short words in a certain box can cause the box to render across multiple pages, which is not desirable.  This is algorithmically checkable, but only in retrospect.

If the daemon detects that a particular print job caused one of the Bugs of the Day to pop up, it displays that fact in red, along with a link which copies the word list to my personal account so that I can reproduce the behavior and start trying to squash it.

This system also lets me sanity check upgrades to the site.  If I cause a regression in behavior, typically (squashed) Bugs of the Day will typically resurface, and my dashboard lights up like a Christmas tree.

What’s On Your Dashboard?

I love hearing implementation details from other businesses, and this is about as wonky as it gets.  What do you put on your dashboard?  Do you have any suggestions for things I should consider adding to mine?

Comments Off

What My User Survey Taught Me

Some weeks ago I mentioned that I was implementing a user survey in Bingo Card Creator, using Wufoo.  About forty of my customers have now taken the time to give me detailed advice.  I thought I’d share some things I learned.  A few takeaways may be applicable to your business, and at the very least “detailed, actionable advice can be yours if you just ask for it” should convince you to start a survey this week.

Incentivize Any Surveys You Do

I ran two A/B tests in taking the survey.  The first selected whether a user was asked to take it at all.  The second tested what prompt was more effective at inducing people to take it.  Half of participants were invited to to take it for altruistic reasons (“Would you like to take a survey about Bingo Card Creator?  We’d like your feedback so that we can improve the website and software for all of our customers.”)  The other half were incentivized (“Would you like to take a survey about Bingo Card Creator?  If you do, we’ll let you print 5 extra free bingo cards.”)

I gave all users who completed the survey the free cards, regardless of whether they had been promised it or not.

I have never had a more lopsided A/B test.  The response rate of incentivized users so resoundingly crushed the response rate of non-incentivized users right out of the gate that I was scared of a bug.  It ended up being more than a 2X difference in conversion: 2.51% vs 1.17%, which is significant at 95% confidence.

Thus the conclusion: if you want responses, give away free stuff.  (Incidentally, you might think that you’d get lower quality feedback from incentivized users.  I did not get that impression from reading the results, but I can’t reduce that to a simple statistical measure.)

Surveys Don’t Cost You Sales

A major worry I had was that putting the survey prominently on the trial version of my application would cost conversions.  Nope — there was no significant difference in sales given to folks asked to take the survey versus folks not asked to take the survey.  (I actually got very, very marginally more sales from the folks asked — but not statistically significant.)

Opinions Confirmed About My Customers

Prior to instituting the survey I had guessed that my customers were mostly female, older (I was guessing normally distributed around 40), and that they were probably teachers.

  1. I was dead on the money on gender.  85% of participants were ladies — this roughly comports with my experience looking at customer names and doing customer support.
  2. My customers are, indeed, mostly older: fully half of them are over 40.  Another 30% are in their 30s.  About 10% are in their 20s and a little less than 10% are below that.
  3. I now have data to substantiate that most of my users are teachers: 30% of respondents use BCC in elementary schools and another 20% use it in high schools (that number is much higher than I would have expected).  I was mildly surprised with the number of people playing with adult family members (~15%).  All other uses are fairly marginal.  Confirming that most of my users are teachers is going to be very helpful in crafting my marketing messages.  (Though I suppose I have to worry about stumbling into the local optimum: I might be seeing this because I market to teachers well and market to, e.g., parents poorly.)
  4. Two survey takers, as predicted, used the survey free response box to ask customer support questions.  One of them I was able to de-anonimize and fix the issue she had (she had created a new trial account rather than using the old registered account and wondered why it was asking her to purchase).  The other one, sadly, was using an anonymous guest account from an IP I’ve never seen before, so I couldn’t track them to an email address to resolve their issue with the purchase.

Things I Didn’t Know Prior to Asking

  1. A lot of my users are very, very appreciative of Bingo Card Creator.  I mean, I knew it saved them some time and that lots liked it, but I got stories of it saving a lesson plan, brightening the day of a room full of seniors, and teaching a son to read.  A few of the results warrant follow up emails to ask if I can quote them publicly.  (Like, right next to the Buy Now button.)
  2. I am terrible at Quality Assurance.  Well, I knew that.  But, specifically, a particular combination of A/B tests would result in a user getting textual instructions on one screen which conflicted with what was written on the buttons on the next screen.  Thank you for the report, ma’am — bug squashed.
  3. A few customers reported generalized anxiety about using “new programs” and said they wanted more handholding in the instructions.  I beefed up instructions throughout the application.
  4. Surprisingly few of my customers reported problems with ease of use — over 90% rated BCC either “Very easy to use” or “Mostly easy to use”.  I also got a lot of free-form comments praising the daylights out of that — many of my customers compared it favorably to other unpleasantness they had had doing routine computer tasks.
  5. Surprisingly many of my customers self-evaluate as comfortable with computers.  50% were “very comfortable”, and 30% were “mostly comfortable”.  These numbers are, candidly speaking, not what I would have assigned on the basis of reading support requests for three years.  It is possible both the survey and I are right, just looking at different segments of reality: 80% of the customers are good with computers and fairly rarely email me, and 80% of my inbox is caused by the remaining 20%.
  6. Customers respond very strongly to features I consider so core to the program I scarcely mention them — in particular, I  learned twelve different ways to express the thought “Every card is different!” and another eight for “I love that I can customize the word list for the lessons I am teaching that week”  I will be incorporating additional variations of those into my copy.  Repetition never hurt any teacher.

The Number One Complaint My Users Have

Bingo Card Creator isn’t free.  Some variations on the theme:

Make it totally free by having advertisers. Many, many sites that elementary teachers use are kept free by the magic of Google AdWords.  I should know — I’m the guy paying for the ads.  While you can keep the free bubble going by passing around VC dollars to Internet firms to Google to Internet firms to Google to Internet firms to Google to … for a while, eventually, if you’re not getting money from customers, everyone dies.  This was, essentially, the last Internet bubble.  I will continue charging because charging keeps the rest of the ecosystem alive.

Relatedly, the fact that Bingo Card Creator is so easy to use is directly related to the fact that I charge money for it.  I obsess over getting customers (or trial users) through the pages to their beautiful bingo cards, because people who see beautiful bingo cards are very inclined to pay me money.  The sites that I advertise on do not optimize for their user experience because if their website is better than my textual ad, they don’t get paid.  That is why the experience of using them sucks.  (I won’t out anybody who I essentially have a business relationship with, but take a look at the free options in my market some time, or look at pages which compete with mine in the search results.)

Charging also subsidizes the experience of the 97.3% of trial users who don’t actually pay me money.

15 card limit does not allow for a class set in which everyone can have a different card 25 would be more appropriate for teachers.”  I regularly get asked what my business model is — i.e. how I convince people to pay money for my software when I give so much away for free.  This lady nailed it in one sentence.

Incidentally, I don’t feel any ranchor at folks who believe that everything should be free on the Internet.  I just will not accomodate your preferences.  You’re welcome to use my free competitors if they better fit your needs.  (I actually provide folks  with lists, on request.)

Takeaway Lesson

What are you waiting for, go sign up for Wufoo (or whatever — they have a few competitors) and do a survey.  You’ll learn stuff that you can use to make helpful decisions for your business.

Comments Off

Four Open Letters To The Book Industry

Dear Publishers:

Hiya.  You don’t know me, but I’m a pretty good customer of yours.  I buy several thousand dollars of books a year, in almost every genre you sell: fiction, non-fiction, fantasy, sci-fi, classics, mysteries, you name it.  I have bought everything from Gladwell to the most obscure author in your backlists and back again.  I may well be the only heterosexual male in the entire world who spent more on urban fantasy alone than he does on video games, movies, and newspapers combined.  I really love books.

For the last decade or so, I’ve bought many of my books through Amazon.  Amazon knows me.  They know what I like, they send me recommendations via email, and on those rare instances when I have a problem with a book they fix it for me within 24 hours.  I really like Amazon.

That is a new experience for me in a book vendor.  Typically, bookstores are anonymous entities who happen to be in the same airport, mall, or street as I am when the craving strikes.  I have absolutely no loyalty to them.  (I hear that before my time there were neighborhood book stores where you’d go in to get a recommendation from someone who knew your tastes intimately.  I’ve never been in a neighborhood book store.)

Some months ago, I bought a Kindle.  Publishers, if you thought I was a good customer before, you should see me now.  I don’t even have to find an anonymous dealer to get my fix — I just punch a button and bam, new book.  And punch that button I do — about four times as frequently as I did previously.  Amazon now sells me over 90% of the books I buy.

Recently, it has come to my attention that some of you are having a bit of a spat with Amazon, centering over release schedules, pricing issues, and, above all, control.  This sent me walking over to my book shelf to check whether those of you who are having the spat with Amazon actually publish authors I read.  The fact that I didn’t know this off the top of my head, and that this is the first time I’ve thought about individual publishing companies in my entire life, should be a preview of coming attractions for you as regards to which company I am backing in this fight.

Let me be perfectly clear: I have no price sensitivity with regards to books.  I read the books I want to read when I want to read them.  I have never bought or avoided buying a book based on whether it was hardcover or trade paperback. (Incidentally, since we’re all businessmen here, let’s be honest: you want to extract as much money out of me as possible because I am price insensitive, and staggering hardcover and paperback release dates is just a way to accomplish that.  Neither of us really care about the physical format in the slightest.)

It does not matter to me what you charge for the books on my Kindle.  However, I’m hearing things about you windowing Kindle releases — i.e. delaying them so that you can protect your hardcover sales.  You think my likely behavior is to go to the bookstore where no one knows my name and pay extra so that I can have the hardcover on release day.  Words cannot express how mistaken you are.

I will read books on my Kindle.  Whether they are your books or the books of your competitors matters to me not one whit.

Dear Authors:

We’re quite the odd ducks, aren’t we.  You don’t know my name either, despite the fact that we’re on surprisingly intimate terms.  I spend most of my leisure time rattling around in worlds of your creation.

I understand you feel a bit of connection to the people who liberated you from the slush pile, sign your royalty checks, and respond to your emails.  You know their names, after all.

I want to read your books as fast as you can write them, on my Kindle.  If you support me in this, I will stick with you like the plucky heroine to the aloof and semi-abusive vampire lord who turned her.  (P.S. urban fantasy authors: stake his worthless carcass.  Signed, beta males everywhere.)

If, on the other hand, you should support your publishers’ interests over my desire to pay you money, mark me on this: I will buy books from authors willing to sell them to me.  I might get a little depressed over not being able to read my favorites, but if you haven’t noticed, I read a lot faster than you can possibly write and that makes me promiscuous by nature.  Any regret I feel over losing you will be quickly assuaged by epic heroism, vile betrayal, true love, and other themes of investing advice books.

Dear Book Stores:

Good luck with that coffee thing.

Dear Amazon:

Keep being awesome.

Regards,

Patrick McKenzie

(A man of no particular importance, who bought more books in 2009 than 20 average American households.)

Comments Off

Followup Questions for "Strategic SEO for Startups"

Peter Christensen had a few questions for me regarding my last blog post about SEO for startups.  I thought the questions were interesting enough to require a bit more than a comment on his post, so I’m going to answer them in detail here.  The details are very, very specific to my particular business — if you want a high-level strategic overview, I suggest reading that post instead.

In the past you’ve talked about outsourcing your content creation to your “army of freelancers”.  What did that consist of on your end?  My guess is you looked at terms and topics people were searching for (you mentioned “baby shower bingo” once) and then sent a job to your freelancers to come up with 80 or so baby shower words that you feed into your card generator and sample bingo card landing pages.

Periodically, when I have an idea for a new project, I put out a call for freelancers on my blog similar to this (for blog writing on my “sprawling bingo empire”) or this (for creating bingo cards).  (Incidentally, “army” is an overstatement: I think in my business career I’ve used a bit less than a dozen, but don’t have my expenses report in front of me.  One woman  in particular is easily 80%+ of that.  Why mess with something that works?)

The work-flow for those two projects is a bit different, but in general I write up the general outline of what I expect (you can see the most important bits in those posts) and then let my freelancers run with them.  For bingo cards I typically give them discretion to choose their own topics (although I let them see my stats for what previous cards were popular — for example, sorted by genre or popular this week).  For the blog creation project I came up with a list of 14 mini-sites via a one-off SQL query.

The deliverable for bingo cards has changed over the years as I’ve upgraded my CMS.  Currently, there is a back-end one page web form on my site which asks for a title for the card, a subtitle, a brief sentence of description, and then a word list.  Anything submitted there goes into my database and awaits my review, which given that my freelancer is very good at what she does is typically “Oh, good, here’s 30 lists for this month.  Approve All.  Goes off to bank site to mail check.”  Within a few seconds of me hitting approve, the CMS backing my site turns the word list into a PDF file, grabs a screenshot of it, and does a bit of content page generation.

The deliverable for the mini-sites is just pages made in WordPress, extolling the virtues of Valentine’s Day bingo or what have you.

How do you analyze and rank your SEO strategies?  I see your sample card landing pages have an id that they pass to the registration page so you know how the different landing pages are converting.  What other methods do you use to determine which SEO methods are most valuable to you?

The flippant answer is that if I make more money than I expect to then I guess everything is working.  Seriously speaking, though, I do very little backwards facing analysis (“Did that work?”) and concentrate mostly on forward facing analysis (“What opportunities can I exploit now?”), with the exception of when I’m writing a blog post to comment on how something worked.

One of the reasons I’ve cooled on Google Analytics over the years is it doesn’t really lend itself to providing data which lets you make actionable decisions in a reasonable amount of time.  For example, if I look at my stats, I can tell you with arbitrary precision how much more popular baby shower bingo cards are than football bingo cards.  Whee.  That doesn’t tell me anything I can do to improve my business today.  Most of the things which can tell me stuff that will improve my business are the domain-specific analytics functions I’ve created (like the above) or fun little one-off explorations of my database that I do from the Rails console.

For example, I might play around one day and see what the most common 25 words are for customers making bingo cards.  (That was what clued me into baby shower bingo.)  That usually identifies a weak spot in my pre-made card lineup, which I can either tell a freelancer about or just fill myself.

Incidentally, you mention that you think the ID I pass to the registration page is for tracking conversions.  Actually, not so much.  I track conversions with Mixpanel.  The reason that ID gets passed is to provide continuity of experience for new trial users.  I’m actually really proud of this hack: if you show up on my landing page for, I don’t know, tea bingo, and you click “Create Your Own Bingo Cards” and sign up for the free trial, your free trial account gets pre-initialized with my set of tea bingo cards already in it and “personalized” instructions on the dashboard about how you can print bingo cards like the tea bingo cards you were just interested in.

This greatly increases funnel success in A/B tests.  (You are roughly 20% more likely to successfully download a set of customized bingo cards if I give you the “personalized” treatment than you are if I drop you at a blank dashboard and expect you to fight your way through.)

I also do this for my PPC (AdWords) campaigns: if you respond to an ad for Halloween Bingo Cards, then by jove I’m going to everything short of dropping a pumpkin on your desktop.

Best idea here: I don’t think enough software companies unify the marketing and product sides, incidentally.  We tend to treat everybody coming in to the top of the funnel as absolutely the same.  Then we treat everybody who makes it through funnel step N exactly the same.  But we’ve got data that says they are different — why not use the data to enhance their experience and, not incidentally, improve their propensity to buy the product?

For example, if I were in charge of World of Epic Dragonslaying, and I had a PPC

Your Bingo Card landing pages allow you to programatically generate tons of pages from content in your product.  What other tips do you have for getting lots of good SEO content for a low investment of time/money?

I suggest reading the parts of the article about scalable content generation.  I don’t have another magic secret that I use for my own business.  OK, maybe half a secret: data begets data.  For example, I’ve got my 800 or whatever the number is bingo card activities that my freelancers and I cooked up.  I use that in several places: each bingo activity becomes

  • a content page
  • a PPC landing page
  • an activity in the downloadable version of the software
  • an activity in the online version of the software

This gives me usage/popularity data about the same subjects.  I use that for:

  • automated interlinking of content pages  (see left hand sidebar, “Related Activities”)
  • automated decisions of promoted content on the front page
  • my popular activities list
  • widgets across my “sprawling bingo empire” which list popular activities
  • semi-automated decisions on which content to promote to mini-sites

Anyhow, if I should come up with a good second idea to generate content for the website, you’ll likely hear about it here roughly contemporaneously with me implementing it.  Many of my friends have suggested I might be at the point of diminishing returns for BCC.  I think that is likely accurate, and so my very best ideas this year are probably going to be in service of my next software project.  However, given that BCC has always been nights and weekends for me, that doesn’t necessarily mean “maintenance mode” for it will be totally bereft of new ideas.

I hope that answers your questions, Peter.  Thanks for asking.

Comments Off

Strategic SEO for Startups

One way I’ve found to cut down on support requests is to make sure I write publicly about any issue that keeps coming up for my customers.  Other small companies contact me for advice fairly frequently, and that also tends to retread the same issues, so I’m going to blog it in depth once rather than giving fifteen people 30% of my thoughts on the same issue. One common issue is “How do I improve our SEO?”

Strategy as opposed to tactics: SEO has a lot of opportunities for micro-optimizations in it, from rewriting title tags to dynamically interlinking content pages.  They’re all interesting subjects and I’m not going to talk about them.  If you don’t feel comfortable in your meat & potatoes SEO yet, head on over to SEOBook or SEOMoz.  Both are excellent resources.  I’m going to focus on core decisions you make about your business and marketing approaches rather than page-level optimization.

Why Startup SEO Is Different

Essentially every business on the Internet from multi-billion dollar giants like Bank of America down to a one-man software business is dependent on SEO, because Google has become the primary navigation tool for the Internet.  (I suppose I could write “search engines” but I feel no particular need to maintain the polite fiction that there is more than one search engine in the United States.)

SEO for a small business is very different than it is for Bank of America.

Limited budgets: Startups cannot devote huge amounts to advertising, branding campaigns, or link acquisition.  (Paying for links will theoretically draw the wrath of Google to you.  In practice, once you’re above a certain size, you’re immune.  If you’re reading this article, you do not have immunity.)

Low domain strength / trust: Google tends to trust older domains, domains with lots of links, and domains with lots of older links.  All of these are signals of what one might call trust: the longer you’ve been on the Internet and the more people who asserted your quality by linking to you, the less likely you are to be a useless spammer.  However, if you just registered your domain last Tuesday, Google has a priori no reason to trust you over the other billion pages on the Internet.

Cultural aversion to SEO: There is a pernicious myth among startups that SEO is a black art aimed at perverting the purity of the search results.  This is partially because search engine spam is indeed a problem and partially because Google is very good at influencing the culture of technically adept people, and it is in Google’s best interest to make people think that their algorithms are the authoritative voice of God.  (Google, for all its image as an open company with significant OSS contributions yadda yadda yadda guards their index and algorithms with a ferocity that would do Microsoft credit.)

Algorithms have no moral status.  If your engineering team sorts records using an n^2 sorting algorithm, then tells you that they did it because the sorting has always been n^2 and therefore this is the Morally Correct Way To Sort, you need to whack your engineering team over the head and tell them to do better.  Similarly, your SEO strategy is simply the input you provide Google’s black-box algorithm which sorts search results: just because it is ineffective does not mean it is the Morally Correct Way To Sort.

A related worry is that SEO hurts the user experience.  It certainly doesn’t have to — a good deal of SEO is about creating stuff your users want to use, surfacing content in a way that is understandable to them, and not breaking your site’s usability when seen from the primary Internet navigation method (Google).  I wouldn’t advocate black hat methods: the black hatters are better than you are at them, and if you use them you’re in a constant arms race with Google (who has billions of dollars, thousands of sharp engineers, and the peaceful conflict resolution skills of Darth Vader) when as a startup you’re already biting off more than you can chew.

Why Startup SEO Is Better

On the plus side, you do have some advantages as a startup:

Strong Technical Skills: I’m a moderator in charge of programming topics at SEOBook and we get an awful lot of nuts and bolts questions like “How do I edit a title tag?” or “How do I do a 301 redirect in Apache?”  Thankfully, since you presumably have programmers who know what they’re doing, you’ll never need to ask either of those.  In addition, you can program tools and content to improve your marketing, including SEO.  We’ll discuss specifics in a moment.

Link Richness: SEO is, at competitive levels, mostly about link acquisition.  It is very difficult to get a link without paying for it in many sectors of the information economy.  For example, while there is probably a thriving micro-community of online taxidermists, they probably control relatively few links compared to their numbers.  However, if you’re a startup, you probably hang out on Hacker News or similar where the blogs-to-person ratio is 6.3, a new useful bit of OSS can make news in four continents on the first day, and online interaction forms a substantial portion of the personal and professional identities of your peers.

There are pluses and minuses to this: a lot of people overadapt to the fickle preferences of TechCrunch et al.  That reminds me of dodgeball in fourth grade except there are 100,000 kids and it is mathematically possible for all of them to be picked last.  Appealing to your peers can’t be your only marketing strategy.  However, it is helpful for when you’re making a cold start, to help get the link to rankings snowball running.  One business which did this very well is Balsamiq, which sent letters to blogs big and small to get coverage.  Steal Peldi’s approach to writing them: it is aboveboard and works.

Strategic SEO Objectives

Ideally speaking, well prior to launch you should figure out exactly what you hope to get for from SEO.  “Rankings” is not an acceptable answer.  Neither is “visitors”.  I could get your startup ranked for [fried squirrels with wasabi] by the end of the day, but unless you’re selling a book of very eclectic recipes that probably won’t do you much good.

If you’re selling display advertising, coating every search result under the sun might actually work for you.  (Display advertising is, essentially, search advertising’s less talented brother: it is essentially a second bite at the apple for advertisers to get a click when users avoided the AdWords ads on Google.  I have deep, deep doubts about the sustainability of display advertising as a business model.)

If on the other hand you’re trying to get users or sales for your application, you have to balance the needs of your SEO operation with the need to convert users.  For example, your homepage will almost invariably be the strongest page on your site.  It probably has to be conversion-oriented rather than conversation-oriented.  However, outside of the home page, conversion-oriented pages don’t attract links that frequently.  Almost nobody blogs “Hey guys, I saw an awesome sales letter today, check it out” and if they do you probably don’t want their attention anyhow.

So your SEO strategy is likely going to involve a mix: non-commercial offerings designed purely to solicit links/attention, semi-commercial scalable content generation which we’ll talk about in a minute, and sales funnels supported by the rest of your website.

Aiming at a moving target: The first cut of your SEO strategy will be wrong, just like v1.0 of your product will be non-responsive to the needs of your users.  That is OK: after you start you’ll begin collecting insights and data which let you refine it.  You want to get something out the door as soon as possible so that you can begin collecting links, other indicia of trust, and data on what is working for you.  Many startups wait until launch to put a significant amount of content on their websites.  This is almost always a mistake.  If you can’t show the application yet, no problem, talk about the problem domain.  Talk about the needs of your customers.  The “media launch” where Steve Jobs comes down and presents the iCommandments works very well if you have a built-in base of millions of radical fans and a PR budget which could buy Chile.  If you’re reading this, that probably doesn’t apply to you.  Google is going to hate your bones when your website first debuts onto the world stage: start that clock ticking as soon as possible.

There is no Google sandbox: If you’re well read about SEO you’ve probably heard about the “Google sandbox”, where sites languish for months or years prior to ranking.  There is no Google sandbox per se: a site doesn’t magically jump from zero to hero because it is 180 days old.  Google can find sites within minutes of them appearing on the Internet and rank them inside of an hour if Google has sufficient reason to.  The sandbox is the perceived reality, though, because from a cold start it takes a while to build up symbols of trust, such as links from trustworthy domains.  All the more reason to get started early.

SEO Is A Feedback Loop

Sites tend to built self-reinforcing authority: the site at the top of the rankings for teddy bears (almost certainly Wikipedia, I can tell you without looking) is the first people go for teddy bears and the most likely to collect another citation when someone is writing about teddy bears.  That will help that site rank for teddy bears and everything else in the future.  In this sense, winners win in SEO.

What does that mean for you?  Well, if your startup does designer teddy bears, Wikipedia has a built-in advantage over you for ranking for [teddy bears] and that advantage gets stronger with each passing day.  However, all is not lost: by moving further down the long tail of search terms, you too can benefit from self-reinforcing authority.  If you’re the best place on the Internet to go for [kimono teddy bears], your site will get stronger each passing day just by virtue of that.

If you’ve done much conversion optimization this should not be a big surprise to you, but things at the top of a page get clicked much more than things lower on the page, all else being equal.  This is equally true of search results: when AOL released its data, the top result got over 40% of the clicks, the second result 11.9%, etc.  The entire second page, by comparison, got only 10%.  SEO is a winners take most game: for a given search term, the vast majority of the benefits flow to the handful of sites at the top of the first page.

What does this mean to you?  It means focus on search terms you can win.  You will not prevail against the likes of Microsoft, Google, et al for head keywords in most circumstances, unless your product becomes synonymous with the niche.  (A head search term is at the popular end of the search frequency distribution, as opposed to on the long tail.  This is completely relative: [money] is a head term relative to [bingo cards], and [bingo cards] is a head term in the bingo niche relative to [valentines day bingo].

Incidentally, I can’t recommend The Long Tail enough for anyone interested in SEO.  If you’ve been on the Internet the last few years you’re probably sick to death of it and have read the (accurate) criticisms of conclusions about books and music being overstated.  However, no single book will improve your thinking on SEO as much as The Long Tail will.  (In particular, read up on tails within tails.)

For the amount of effort it would take you to rank #12 for the head term of your choice, which will result in marginal traffic even if the head is huge, you could rank in the top three for a huge basket of tail terms.  Additionally, one of the things you’ll notice is that conversion rates for head terms are terrible.  People searching for the terms on the head are either just beginning their research into a topic or are less sophisticated.  Generally, those are not the searchers you want.  Longer, specific queries are more common among people who have done the research and are nearing a purchasing decision.

Here’s an example for you: for the last several years I’ve ranked on the first page for [bingo cards] most of the time.  At the moment I’m probably, oh, eightish or so.  That was worth about 6,300 visits in 2009.  That resulted in three purchases of my software, for a value per visitor of a bit more than a penny.  Wheeeee.

By comparison, [free bingo cards] gets less than a fifth as much traffic, according to Google’s keyword tool.  However, the 1,200 visitors there also bought 3 copies.  (If that you didn’t expect people explicitly looking for free things to convert at five times the rate of undifferentiated searchers, welcome to the Internet.  Nothing makes sense except the data you collect.  Get something out there so today so you can find which 90% of everything you know is wrong.)

Now if we go waaaay down the tail to [geography bingo], we find that despite it having fairly few searchers (I only got about 300 hits visits year from it), it is quite lucrative ($70 CPM).  I could spend my entire life working in bingo and never be #1 for [bingo cards], but for a non-competitive tail term like [geography bingo], I’m #1 by virtue of showing up.

Sadly, a lot of startups of my acquaintance are so focused on the product that they don’t bother showing up for the topics that matter to their customers.  I won’t pick on anybody in particular (sidenote: write “Its OK to mention this conversation publicly” on an email to me and you might get a backlink when I need an illustrative example, like here), but it is very common for startups to launch with less than 1,000 words of text on their website and all the content behind the sign in screen.  That essentially cedes the long tail to your competitors.

Thus, my generic SEO strategy for a startup is a) be the best on the Internet for b) as many topics as you possibly can be that c) matter to your paying customers.

Making SEO Scale

Everything about a startup has to scale ridiculously disproportionately to the time invested in it, because you have too much to do and not enough people to do it with.

Some people say this is why you have to work 80 ~ 100 hour weeks.  If I worked 100 hour weeks, Scholastic Publishing would still be able to afford to devote a thousand man-hours for every one I can, if they chose to.  Your only hope for rising above the din on the Internet is to work smarter than your competitors.  Happily, your small size, technical skill, and agility let you run rings around the other guys.  One way is through scalable content generation.

Content in SEO is sort of a dirty word.  It can mean anything your users can consume: text, video, whatever.  Sadly, when people talk about content they are mostly talking about commoditized garbage, because the quality levels of content produced at scale are generally terrible, as you’re about to see.

There are about four approaches for creating content at Internet scale:

User-generated content.  Strategies centering around user generated content really devolve into two things: one, you hope people will steal hand-crafted content from elsewhere and put it on your site while you look the other way long enough to build traction (hello, Youtube, Scribd, etc) and two, you generate vast amounts of mostly excruciatingly worthless content which happens to match an equally vast amount of search terms.  Then, you sell display advertising against the visits for those searches.  This is essentially the business model for WordPress — give a blog to anybody who asks for one, display AdSense ads to folks who arrive on old posts via Google.  The ads give them the answers the content could not.

I don’t mean to malign user-generated content too much.  Sturgeon’s Law says that 90% of everything is garbage, which implies that 10% is not.  However, it is very difficult to use that 10% that is not garbage to advance your business goals, because it is not conversion-oriented and your advertisers don’t pay premium CPM rates just because the page the user landed on is worthwhile.  (Actually, in practice it tends to work out the other way around: if the page the user lands on is worthwhile, it will likely satisfy their desire, and economic value from that searcher ends.  That means low CTRs to ads and, accordingly, low CPMs.  If on the other hand the page is useless, then they might click on an AdSense link to continue the search.  This is the perverse incentive by which advertisers pay to make the Internet a mass of garbage.)

Mass Semi-Amateur Content Creation: The Demand Media model is capturing quite a bit of attention these days: take an authority domain like eHow, use sophisticated algorithms to generate article ideas for it, pay an army of underemployed freelancers miniscule wages to write uninspired content about the suggested titles, collect hundreds of millions in AdSense revenue.

The quality of Demand Media (et al) content is a cut above Youtube comments, but not by all that much.  I don’t really recommend implementing this model for startups.  First of all, I think Google is going to have to crush it like a bug in the next 12 months, because currently it is a license to print money and is polluting far too much of the search space.  Second, the amount of sophistication it requires is considerable, and while I think that is probably duplicable for a startup (particularly if you used something like TextBroker to automate dealing with the freelancer army) I think you’re better off with your engineering investments in more defensible places.

That being said, study this model and study it well: they’ve got a tight analytics-to-pipeline loop, they’ve got almost everything automated, and their margins are out of this world.  There is no reason you can’t do those things while producing great content by taking advantage of focus and engineering ability that Demand Media cannot devote to every microniche they want to expand into.  DemandMedia can saturate the world in How To questions but will never be able to outpublish me for bingo cards, because they will never detail someone to write a CMS to let their freelance army make those easily.

Talented expert workers: You can have all of your website content created by talented artisans who laboriously polish every bit to perfection.  For example, you could write every page by hand yourself, or hire a team of journalists to do it for you.  Have you seen the financial results for the New York Times recently?  Still want to do this except without the 200 year old megabrand?  Good, moving on.

Scalable Content Creation That Works

So how are you going to create large amounts of content that satisfies needs for your users while still advancing your business needs and not being garbage?  You leverage the unfair advantages that you have because you’re the smallest guy in the room.

Data You Can’t Get Anywhere Else: If you hang out around geeks who can’t get dates, you’ve seen a series of posts by OKCupid on topics such as how your race affects responses in online dating.  This is brilliantly done linkbait: it takes a huge amount of proprietary data (OKCupid response analytics) and exposes it in such a way that it is interesting (“Whoa, the very hottest women really do get hit on less than than you would expect “) , easily consumable (“Whoa, this pretty picture demonstrates that black guys have it hard when dating.”), and easily shareable (“Guys, I found scientific proof of why we need to take our shirts off!”)  If you’re J. Random Dating Affiliate, you can’t possibly duplicate that linkbait.  OKCupid can do it over and over and over again, though: they’ve written the analytics tools, they’ve figured out how to do the research and visualizations, all they need to do is come up with a new hook and bam they’re at the top of the social news sites collecting links again.

If you don’t have interesting data, you should start collecting interesting data.  However, in the meanwhile you can start visualizing or crunching existing data.  This is less defensible — anybody can go to the Census and get a few gigs of various poorly conceived slices to fill their hard drive — but you can add a whole lot of value in less time than you think with some SQL, your graph library of choice, and a well-written executive summary.

One of the few bright points for the New York Times is that they’re capable of doing things like this, for example.  You could have done that.  If you were in the job board industry, you could do something like that every Friday afternoon, by using open source, agile development, and all that jazz.  Pretty soon you’ll be cited as an authority on the subject — because, ahem, someone who publishes repeated analyses of raw data is an authority on the subject (or at least appears to be, which is 90% of what matters on the Internet, for better or worse).

Focus on evergreen content: A lot of people like blogs as content generation engines, and indeed, I think every startup should probably have a blog.  Then people blog on current events.  Bad call!  You see, today’s news is worth reading for about a day — less, in some sectors of the economy.  You’re a hamster on a wheel if you’re trying to keep up with the news — tomorrow, everything you write today is worth markedly less, and a week from now it will be almost totally forgotten.  Instead, pick the concerns of your audience that are roughly static and that will be pretty much the same next week, next month, next decade.  Alternatively, create resources that don’t go stale.

For example, for a bit of extra work that NYT visualization above could use live data, and instead of being a wonderful piece of technology becoming quickly irrelevant to a story from years ago, it could be a hub for the enduring issue of Racial Difference In America.  The NYT is interested in that issue and still will be in 2012.  They don’t have the strategic vision to make that graph with live data, though.  Luckily, your business is not a maladapted dinosaur reacting too little and too late to the changing business landscape.

I like to call this “evergreen content.”  For example, if you have a website selling a service teaching people Japanese, a page on how to make requests in Japanese will be  good for generations.  It is evergreen.  Or エバーグリーン, I suppose.

Agile — Not Just For The Product: Because you have excellent internal analytics (you do, right?) and you track what is working and what isn’t (you do, right?) and you can quickly bring resources to “market” because you’re using highly productive programming environments (you are, right?), you can try ten things, watch eight fail, and then try ten variations on the best two.

For example, suppose you have a mailing list of customers or fans (you do, right?).  Pitch (comparatively) low cost explorations of ideas to them, like blog posts about topics A/B/C/D/E.  Observe which one gets the most play with your existing customers.  Build (more expensive) resources about that topic, like something which requires custom programming.  (Bonus points: credit your customers with the inspiration for building the new thing!  You want a 95% certain way to get a link from Bob Smith’s blog to your new article?  Cite his contribution to it.  Help them help you get the ball rolling with their blogs, Twitter accounts, blah blah.)

Obviously, if one idea works out well for you, going in more depth or breadth on the same theme allows you to possibly re-use code, link sources (“Hey Cindy, this is Patrick from Random Job Startup.  A few months ago you had some great comments  about our unemployment visualization.  We’re putting together something similar and I wanted to ask if you had any more insights…”), marketing tacks that worked, etc.  (A great micro-idea I heard the other day: watch what people tweet about your stuff, use that as the title next time.  This may be the first time I’ve ever heard of an idea to get actual value out of Twitter.)

Pillar Content vs. Bill ‘er Content

As mentioned, you’re going to have to strike a balance between creating content designed to spread and gather links, attention, etc. and content designed to sell your stuff.  They’re not totally disjoint sets, but in practice non-commercial content will form the vast majority of your links.

If you don’t have any great ideas for non-commercial content (“How do we get people talking about our new squeegee brush?  It is a boring subject”), here’s a couple:

Open Source Software: You’re a programmer and you probably use vast amounts of OSS.  It is highly likely that in the process of creating your startup you will write some plumbing which is not your source of competitive advantage, but would solve problems for other people.  Since you already wrote it, why not OSS it?  Spend a few hundred on a nice logo (this is rounding error next to the engineering time you have invested and will greatly increase spread, trust me), write up a decent page on your website with examples and documentation, and send it to folks you think could use it.

I did this for my Rails A/B testing software, which at the time was a sorely underserved niche.  That is probably my best links-to-unit-effort idea ever, and it got links from authoritative sources like the Ruby on Rails official site who may not have been interested to hear about my new and improved Jane Austen bingo cards.  (Some people have no appreciation for the finer things in life — at least according to the rabid Jane Austen fans on the Internet.)

I have one comment on OSS for SEO which may cost me geek cred: does Github pay your salary?  I love them.  They’re wonderful people.  They contribute a lot to OSS.  They are also quite good at marketing their business and do not require your help to do it.  If you’re going to do OSS to get links, get links to your own site.

Blog Your Email: Do you get pre-sales inquiries or support requests?  Take careful note of how your customers ask questions, because they speak a different language than you do.  I describe bingo cards as “unique”, my customers frequently describe them in email as “not the same” or “not alike”, as it “How do I make bingo cards that are not the same?”  Using the same language that your customers use, answer their questions in public.  This can be bill ‘er content, since somebody asking this question likely has a need they’re interested in paying money in to solve (after all, a person just like them has sent you an email about it, knowing that your answer is going to involve “Oh, you do this on our product”).  Thus, while you are answering the question, you can probably work in a plug for your product.

Good SEO Can Make Your Startup

Your startup can succeed at SEO via the sweat of your brow and a bit of focused creativity, without having to spend hundreds of thousands to do so.  In terms of cost efficiency, organic SEO is probably the most efficient distribution method ever created.  Even with very modest amounts of resources, you can have get hundreds of thousands of visits and add thousands of users to your product.  (I do, and I’m certainly not a towering giant conquering the Internet from my local rice field.  You can do better.)

If you take one thing from this article, please, take this: you cannot afford to not have an SEO strategy.  If the idea of being an SEO gets your dander up, get over it drop me a comment and I’ll suggest something you can do that you won’t dislike but will still improve your SEO.

The usual disclaimers: I don’t get compensated for using people as examples.  I do try to write most people who ask for advice (odds are better if you ask good focused questions, let me get a blog post out of it, etc) but I know a few have slipped through the cracks as of late.  I’m by no means the world expert at this — take everything I say with a grain of salt.

Comments Off

Wufoo + Free Incentivization = Cheap, Effective User Surveys

The prototypical customer of Bingo Card Creator is a woman between the ages of 30 to 50 who plays bingo with her classroom. I like to think of her as Martha.  However, unlike most statements I make here about my business, this is far more a guess than it is a fact substantiated by data.

I can substantiate, for example, that in excess of 90% of BCC customers are female.  (A quick Ruby script checking names on credit cards against a dictionary of common American names reports 90%+ are female.)

They generally seem to be on the older side, too.  Sidenote: If you grew up in America you probably have the accurate impression that someone named Ethyl is likely not 18 years old.  You might not know that most names go through ups and downs in popularity.  I’m going to bet that over a few thousand customers I can probably reconstruct the average age just by inspection of first names, but that is an experiment for another day.  The US  Social Security Administration will give you name popularity data, by the by.

However, the bit about Martha being a schoolteacher?  Yeah, that is just a guess.  An educated guess, but still a guess.

Why Not Knowing These Things Matters

Prior to releasing Bingo Card Creator the core customer I had in mind was an elementary schoolteacher, and the software and site was built with that assumption.  I wrote my copy so that I would sound like a sympathetic colleague (as opposed to, say, a twenty-something WoW raid leader, or a Japanese salaryman, either of which would have been equally as true).  I concentrated the lion’s share of my content creation on the needs of schoolteachers.  I even picked designs for the website and software that looked like something a schoolteacher would like, as opposed to the “That button doesn’t have a glossy finish, reflection, and drop shadow yet, but we’ll fix that!” Web 2.0 aesthetic that I prefer.

Roughly contemporaneous with launch I changed a bit of the copy to address both parents and teachers, but parents were a nice bonus audience I could satisfy with the free trial (and get links from) while trying to separate teachers from their money.

That was my customer hypothesis, to use a buzzword much remarked on lately, and 3.5 years later I’m still not really sure if it is accurate.  On the one hand, I have received email from many, many teachers.  On the other hand, sometimes I get empirical evidence that I’ve been myopic: for example, I put Baby Shower bingo on the back burner for years before realizing that the top 25 words used by customers were all baby related.

So should I be making a massive overhaul to my copy to target a wider audience than teachers?  Or should I mostly keep doing what I’m doing?  Well, time to supplement my intuition and non-representative guesstimate based on support requests: I need to run a survey.

HTML Forms: Not Quite As Bad As Visiting An Ill-Tempered Nazi Dentist

I generally work from the hard parts first, and the hard part of doing a customer survey is:

  • figuring out what questions to ask
  • getting customers to actually take it
  • analyzing results
  • writing HTML forms.

I am very, very bad at writing HTML forms.  The input markup I can handle, but making them not look insanely ugly takes me literally days.  (Visual design is not my baliwick and what little talent I have for it gets vaporized when it meets the harsh reality of CSS.)  However, I don’t want to have to book my designer for a day just to get a few multiple choice questions coded up.

Enter Wufoo, one of my favorite SaaS providers.  They do one thing really, really well: create web forms for people who would otherwise need to pay somebody with an expensive degree to do it.  I have a Wufoo account lying around since I bought it for my younger brother, who wanted to survey readers of his superhero writing blog (my family loves niche subjects, what can I say).

It only took me about half an hour to mock up a quick survey.

What I Asked

Since users get less likely to complete forms with length, I kept it fairly short:

  • Gender  (I’m pretty sure I know the answer to this one, but if half my users are men and 90% of my customers are women that would be a very important thing to know.)
  • Age  (<20, 20 ~ 29, …, 60+)  (Here I’m much less certain.  Normally distributed with an average of 40ish, maybe?)
  • Who they expect to play bingo with  (“My children”, “My (adult) family”, “My coworkers”, “My class (elementary)”, etc etc)
  • Whether they feel “comfortable with computers”  (For years I have presumed that the answer to this is a resounding “no”, and it drives development choices.  For example, I can’t offer picture bingo — my #1 requested feature — if users cannot routinely succeed with finding an image file on their machine and cropping it.  If most users report facility with computers, I might consider moving picture bingo off the “To be implemented after Chinese democracy” list.)
  • Whether they find BCC easy to use or not (I prefer data on task success to subjective sentiment, but I can’t afford to ignore sentiment if the sentiment is negative.)
  • “What is your favorite thing about BCC?”  (Free response.  I figure it might tell me something I don’t know, and probably will elicit testimonial-worthy quotes.)
  • “How can we make BCC better?”  (A nice open-ended way to get users to complain without making them feel like they are complaining.)

Clever Survey Integration

There are a couple of ways to ask people to take a survey.

  • Put a discrete link on your site that no one will click.
  • Use a pop-up window, because you spend entirely too much on bandwidth and need to drive some users away.
  • Email your mailing list, offering an interruption that doesn’t improve their day.

I wanted to do something a bit trickier: integrate the survey intelligently into my site, such that users would want to take it.

  • Offer users a freebie just for taking the survey.
  • Let users dismiss the message if they want to.
  • Stop bothering users after they take it.
  • A/B test the effects of the survey on sales.
  • A/B test the effects of the freebie on survey taking.

A note on incentivizing users: Programmers live in a world where data is available in infinite abundance, and hence we often assume that data is valueless.  (If you doubt this, try asking a programmer for opinions on software pricing.  Yes, I am talking to you, Mr. Three Dollars Is Too Much For A Game On My Six Hundred Dollar Phone.)  We sometimes forget that users live in a world of scarcity, where data has definite value.  For example, you and I know that it makes no difference whatsoever to me whether Martha can print out 15 cards or 20 cards during her free trial: the marginal bits are too cheap to even calculate the cost of.  However, Martha definitely does not perceive things that way: 20 cards is 33% more of something she wants, of course that is a good thing!

This means I can give Martha something she wants, very easily, at no marginal cost to me.  That is a good carrot to use in a lot of marketing activities, from incentivizing people to take surveys to incentivizing them to link to you.

Implementation Details

This turned out to be pretty easy to do with Rails, my A/B testing framework, and MemcacheDB.  (I could have persisted survey state in the MySQL database with most of my user-specific data.  However, I really hate having to migrate my user model just to accomodate a feature that I may well rip out in two weeks, so a key/value store makes an excellent choice.  If I no longer care about the data, all I have to do is stop requesting it and bam it is like it never existed in the first place.)

First I adjusted my users’ dashboards (the main page that they are sent to right after logging in) to include an inducement to take the survey.  I set it to ask all paying customers to take the survey.  My reasoning for this was it is free for me and, if they don’t want to, it costs a maximum of one click to dismiss permanently.  However, giving trial users the survey potentially costs money through lost conversions, so I set up an A/B test to see if offering a survey is very expensive.  This could affect my desire to do them in the future.

Additionally, for trial users, I set up an A/B test on the call to action text: half are given altruism as the reason to take the survey, the other half are offered the aforementioned freebie.  (All survey takers will actually be given the freebie whether promised it or not — it is just as easy to implement either way, but I tend to default to being generous to my users unless I have a darn good reason otherwise, and I don’t here.)  I’m doing this mostly for my own curiosity.

Wufoo has a setting where you can redirect folks to a URL after taking the survey.  I set this to an action which performs housekeeping (setting the user’s survey status to “Completed”, tracking results of the A/B test, setting a thank you message, and redirecting to the dashboard).  If the user bails from the survey with the back button rather than completing it, they’ll be right back at the dashboard and nothing will have changed.

I also added a quick link to hide the survey (it sets their survey status to “Declined”, which will surpress the survey call to action forever), on the theory that users should be able to have an uncluttered experience if they wish to.  This could have been done with AJAX and link_to_remote fairly easily, but doing it the old fashioned way worked fine and only took two lines of code, so I did it that way.

Finally, implementing the freebie took a bit of surgery to some validation code.  It wasn’t very difficult at all — I copy/pasted my existing validator, added “has taken the survey” to the :unless clause to disable it, and pasted in a new copy with the higher limit.  I love the way Rails tends to make minor logical tweaks like this easy.

The total change it took to implement this intelligent, incentivized survey (plus two A/B tests) was ~20 lines of code and ~20 lines of HTML for three alternatives in the view.  It was actually quicker to write and test the code than it was to make the survey in Wufoo’s drag and drop interface.  At no time did I have to waste a week nudging CSS files around to get something that wasn’t horrendous.

Incidentally, I think this is a good demonstration of how Rails, crafty application of cheap software, and the related bag of tricks let you be more nimble than you would be if you were e.g. running on enterprise Java.  I’ve implemented surveys for the universities who are clients of my day job, and surveys of roughly comparable complexity typically require planning meetings so that we can add them to the schedule and eventually detail an engineer or two to get them started.  There’s a place for that in the world, don’t get me wrong, but I’m already collecting data.

Pictures of Implementation

Here’s the variant for trial users which offers the incentive for taking the survey:

If I had a bone of artistic ability in my body there would be a box around that with a red X in the top right corner to dismiss in addition to the textual link, but oh well.

A Possibly Controversial Note On User Privacy

Normal users don’t really want privacy.  There, I said it.

Users will say they want privacy, if you phrase the question the right way.  (“Do you want multinational corporations to put data on your machine that will let them track your visits to sites on the Internet?”  “Oh my good heavens, no!  That’s monstrous!”  “That is necessary to implement things you take for granted, like ‘Remember me’ .”  “That’s totally not the same thing!”  “Google gives you personalized search results the same way, and sells ads against what you searched for early this morning.”  “Well I like Google!”) Given the choice between privacy and convenience, they’ll choose convenience every single time, and if you prioritize their privacy over their convenience it is your problem.

I said the usual pieties about the survey being totally anonymous.  This is literally true and yet says less than what you might think it says.  Consistent with my privacy policy (that no one reads because no one cares about privacy), I will make no particular attempt to link users with their answers.  However, I can work backwords from a copy of the survey to personally identifying information (an email address, if they’ve provided it).  And that is a good thing:

The above is a slightly anonymized composite of actual support requests I have gotten over the years.  (I try my level best to satisfy people, but you can’t win every time.)  If that user submits the survey and I can’t identify who he is, I’ve essentially stolen from him, because I promised him a refund any time any time he asks for it and I have not delivered on the promise.  Granted, he didn’t ask for it in a very technically savvy fashion, but I try to make it as easy as possible for my users to succeed at the things they clearly intended to do.  Even if their clear intent is to ask for a refund.

If you think this example is far fetched: Google Checkout will, some time after the transaction has happened, mail your customers to request that they write a review of your product.  Reviews are posted in an electronic Siberia and no notification is sent to the merchant when they happen.  However, because it has a text box and is occuring in the context of a commercial relationship, customers assume you are hanging on their every word.  They’ll use the “review” to communicate time-sensitive information like “Oh by the way I need this shipped to …” or “It has been two weeks and my CD hasn’t arrived.”

My theory for why Google didn’t anticipate this failure mode is that Google assumes you care about your customers about as much as Google cares about its customers, and at Google forwarding customer complaints to Siberia would double the likelihood they were actually read.  (Do I sound bitter?)

Anyhow, the EFF can burn me in effigy if they want to, but given the choice between giving customers ironclad privacy and giving them what their actions demonstrate they actually want, I’ll give them what they actually want.

Analyzing Results

Since I started writing this post it appears that a user has taken the survey.  Take that, planning meeting.

After I have a bit more data, I’ll grab it from Wufoo, segment it by user type (trial user vs. customer, etc), and started asking the data questions to guide the further development and marketing efforts.  If I find anything interesting, I’ll post about it.

Comments Off

Deploying Sinatra On Ubuntu: In Which I Employ A Secretary

As mentioned previously, I really hate getting woken up at 3 AM in the morning.  This happens fairly frequently for me, though, because I live in Japan and about half of the people who call me do not. I have not been effective at getting them to check what time it is here before they call, but I certainly want them to call, and even call me in the middle of the night if it is an emergency.

So I made myself a phone secretary with Twilio, their Ruby gem, and Sinatra (a lightweight Ruby web framework).  I gave my friends and family a US number assigned to me by Twilio. Dialing it causes Twilio’s computer to talk to my server and figure out what I want to do with the call. The server runs a Sinatra app which checks the time in Japan and either forwards the call to the most appropriate phone or gently informs the user that it is 4:30 AM in the morning.

The code for this took 10 minutes. Reasoning my way through a deployment took, hmm, 3 hours or so. I am a programmer not a sysadmin, what can I say. I thought I’d write down what I did so that other folks can save themselves some pain.

Code (You’re probably not too interested in the exact logic, but feel free to use it as a springboard if you want to make a secretary/call forwarding app):

require 'rubygems'
require 'sinatra'
require 'twiliolib'
require 'time'

@@HOME = "81xxxxxxxxxx"  #This is not actually my phone number.
@@CELL = "81xxxxxxxxxxxx"  #Neither is this.

def pretty_time(time)
time.strftime("%H:%M %p")
end

def time_in_japan()
time = Time.now.utc
time_in_japan = time + 9 * 3600
end

def is_weekend?(time)
(time.wday == 0) || (time.wday == 6)
end

def in_range?(t, str)
time = Time.parse("#{Date.today.to_s} #{pretty_time(t)}")
range_bounds = str.split(/, */)
start_time = Time.parse("#{Date.today.to_s} #{range_bounds[0]}")
end_time = Time.parse("#{Date.today.to_s} #{range_bounds[range_bounds.size - 1]}")
(time &gt;= start_time)  &amp;&amp; (time  "45")
@r.append(say)
@r.append(call)
@r.respond
end

def redirect_twilio(url)
@r = Twilio::Response.new
rd = Twilio::Redirect.new("/#{url.sub(/^\/*/, "")}")
@r.append(rd)
@r.respond
end

post '/phone' do
t = time = time_in_japan
if (is_weekend?(time))
if in_range?(time, "2:00 AM, 10:00 AM")
redirect_twilio("wakeup")
else
forward_call(@@CELL)
end
else #Not a weekend.
if in_range?(time, "2:00 AM, 8:30 AM")
redirect_twilio("wakeup")
elsif in_range?(time, "8:30 AM, 6:30 PM")
redirect_twilio("working")
elsif in_range?(time, "6:30 PM, 9:00 PM")
forward_call(@@CELL)
else
forward_call(@@HOME)
end
end
end

post '/wakeup' do
if (params[:Digits].nil? || params[:Digits] == "")
@r = Twilio::Response.new
say = Twilio::Say.new("This is Patrick's computer secretary.  He is asleep right now because it is #{pretty_time(time_in_japan)}.  If this is an emergency, hit any number to wake him up.")
g = Twilio::Gather.new(:numDigits =&gt; 10)
g.append(say)
@r.append(g)
@r.respond
else
forward_call(@@HOME, true)
end
end

post '/working' do
if (params[:Digits].nil? || params[:Digits] == "")
days_left = (Date.parse("2010-04-01") - Date.today).to_i
@r = Twilio::Response.new
say = Twilio::Say.new("This is Patrick's computer secretary.  He is at work as it is #{pretty_time(time_in_japan)}.  Only #{days_left} days left!  If this is an emergency, hit any number call him at work.")
g = Twilio::Gather.new(:numDigits =&gt; 10)
g.append(say)
@r.append(g)
@r.respond
else
forward_call(@@CELL, true)
end
end

get '/' do
'Hello from Sinatra!  What are you doing accessing this server anyway?'
end

This script is a bit ugly but, hey, what do you want in ten minutes. (Memo to self: correct it after leaving my job.)

Sinatra Deployment On Ubuntu

A quick look around the Internet didn’t show any cookbook recipes for deploying Sinatra. I thought I’d write up what I’m using, which uses Apache reverse proxying to Sinatra. (Instructions included for Nginx as well.) It assumes you already have your webserver running and are familiar with basic Ruby usage and the Linux command line.

1) Install the daemons gem. We’re going to daemonize Sinatra so that it runs out of our console and starts and stops without our intervention, much like Apache does.

2) Create an /opt/pids/sinatra directory. (It seemed as good a place as any.) Let a non-privileged user write to that directory, for example by executing “sudo chown www-data /opt/pids/sinatra; sudo chmod 755 /opts/pids/sinatra”. Make a note of what non-privileged user you use. I am just reusing www-data because Apache has conveniently provided him for me and he is guaranteed to not to be able to screw up anything important if he is compromised.

2) Write a quick control script and put it in the same directory as your Sinatra app (called phone_sinatra.rb for the purposes of this demonstration). I threw these in /www/var/phone.example.com/ but you can put them anywhere. Make sure the scripts are readable, but not writable, by www-data. (sudo chmod 755 /www/var/phone.example.com/ will accomplish this: it makes only the owner able to write to it, but any user on the system — including www-data — can read from it.)

require 'rubygems'
require 'daemons'

pwd = Dir.pwd
Daemons.run_proc('phone_sinatra.rb', {:dir_mode =&gt; :normal, :dir =&gt; "/opt/pids/sinatra}) do
Dir.chdir(pwd)
exec "ruby phone_sinatra.rb"
end

3) (Optional) Add in a reverse proxy rule to Apache or Nginx to send requests to the subdomain of your choice to Sinatra instead. I ended up deploying this through Apache, so the rule is pretty quick:


ServerName phone.example.com

ProxyPass / http://phone.example.com:4567/

You could also do this on Nginx and it is similarly trivial.

server {
listen       80;
server_name phone.example.com;
proxy_pass http://phone.example.com:4567/;
}

The main reason I do this is to not have to remember non-standard ports in my URLs. It also simplifies firewall management if you’re into that sort of thing.

4) Add a control script to /etc/init.d/sinatra so that we can start and stop Sinatra just like we do other services, like Apache.

#!/bin/bash
#
# Written by Patrick McKenzie, 2010.
# I release this work unto the public domain.
#
# sinatra      Startup script for Sinatra server.
# description: Starts Sinatra as an unprivileged user.
#

sudo -u www-data ruby /var/www/phone.example.com/control.rb $1
RETVAL=$?

exit $RETVAL

5) Tell Ubuntu to start your daemon when the computer starts up and shut it off when the computer starts down: sudo update-rc.d sinatra defaults

6) Start the service manually for your first and only time: sudo /etc/init.d/sinatra start

There you have it: Sinatra is running the application you wrote, and it will start and stop with your Ubuntu server. If you were doing this for Twilio now you’d check your Twilio account settings to make sure it has the right URL set up for your phone number, and then try calling yourself. Preferably NOT from the phone you try to forward to.

All code in this blog post was written by Patrick McKenzie in early 2010. I release it unto the public domain. Feel free to use it as the basis for your own apps.

Twilio development makes me feel like a kid in a candy store — you can affect the real world through an API, how cool is that? I think next time I have a few hours to kill I’m going to make a similar secretary for my business. I don’t give folks my phone number because a) I live in Japan and b) they don’t pay me enough to do telephone support. However, quoting a telephone number on your website instantly says “There is a real business behind this!”

I think I’ll whip up a computer secretary for the business which handles the most common two support requests (“I didn’t get my Registration Key” and “I lost my password.”), and for anything else takes their message and emails it to me. That sort of thing costs megacorporations bazillions and can be whipped up these days by a single programmer on Saturday morning for under $5 a month in operating costs. Like I said, candy store.

def pretty_time(time)
time.strftime(“%H:%M %p”)
end

def time_in_japan()
time = Time.now.utc
time_in_japan = time + 9 * 3600
end

def is_weekend?(time)
(time.wday == 0) || (time.wday == 6)
end

def in_range?(t, str)
time = Time.parse(“#{Date.today.to_s} #{pretty_time(t)}”)
range_bounds = str.split(/, */)
start_time = Time.parse(“#{Date.today.to_s} #{range_bounds[0]}”)
end_time = Time.parse(“#{Date.today.to_s} #{range_bounds[range_bounds.size – 1]}”)
(time >= start_time)  && (time < end_time)
end

def forward_call(number, surpress_intro = false)
@r = Twilio::Response.new
say = Twilio::Say.new(“#{“This is Patrick’s computer secretary.  ” unless surpress_intro}I’m putting you through.  Wait a few seconds.”)
call = Twilio::Dial.new(number, :timeLimit => “45”)
@r.append(say)
@r.append(call)
@r.respond
end

def redirect_twilio(url)
@r = Twilio::Response.new
rd = Twilio::Redirect.new(“/#{url.sub(/^\/*/, “”)}”)
@r.append(rd)
@r.respond
end

post ‘/phone’ do
t = time = time_in_japan
if (is_weekend?(time))
if in_range?(time, “2:00 AM, 10:00 AM”)
redirect_twilio(“wakeup”)
else
forward_call(@@CELL)
end
else #Not a weekend.
if in_range?(time, “2:00 AM, 8:30 AM”)
redirect_twilio(“wakeup”)
elsif in_range?(time, “8:30 AM, 6:30 PM”)
redirect_twilio(“working”)
elsif in_range?(time, “6:30 PM, 9:00 PM”)
forward_call(@@CELL)
else
forward_call(@@HOME)
end
end
end

post ‘/wakeup’ do
if (params[:Digits].nil? || params[:Digits] == “”)
@r = Twilio::Response.new
say = Twilio::Say.new(“This is Patrick’s computer secretary.  He is asleep right now because it is #{pretty_time(time_in_japan)}.  If this is an emergency, hit any number to wake him up.”)
g = Twilio::Gather.new(:numDigits => 10)
g.append(say)
@r.append(g)
@r.respond
else
forward_call(@@HOME, true)
end
end

post ‘/working’ do
if (params[:Digits].nil? || params[:Digits] == “”)
days_left = (Date.parse(“2010-04-01″) – Date.today).to_i
@r = Twilio::Response.new
say = Twilio::Say.new(“This is Patrick’s computer secretary.  He is at work as it is #{pretty_time(time_in_japan)}.  Only #{days_left} days left!  If this is an emergency, hit any number call him at work.”)
g = Twilio::Gather.new(:numDigits => 10)
g.append(say)
@r.append(g)
@r.respond
else
forward_call(@@CELL, true)
end
end

get ‘/’ do
‘Hello from Sinatra!  What are you doing accessing this server anyway?’
end

Comments Off

The Solo Founder (Startup) Rap

I saw the title Will Single Founders Please Stand Up and got a bit inspired.  Substantive comment continues below the song.  With apologies to Eminem, Weird Al, and fans of quality music everywhere:

Download (or hit icon to play inline): MP3 / Ogg

Won’t The Solo Founders Please Stand Up?

May I have your attention please?
May I have your attention please?
Will all you solo founders please stand up.

I say again, will all you solo founders please stand up.
We're gonna have a problem here.
Y'all act like you've never heard a solo founder before
Jaws all on the floor, slower than the App Store
Can't approve a new idea in a year or four
Like it takes a team of a million monkeys
To make a web 2.0 app.  Oh, sorry -- did
I just imply your Twitter client was easy?
But Paul Graham said...
(spoken)  Well, yeah, but he said "Use Lisp", too.
So that's two things he's wrong on.  Sorry Paul.  Back in character.

Customers love solos.  Ca-ching!
Matz, heard of him?
His left pec once wrote an interpreter while sleeping.
What do you mean you can't market an app
In your spare time.

Yeah, we've probably got a couple cycles in our threads loose
Banging out code in darkened bedrooms
Sometimes want to log on WoW and let loose
But its the business that brings the phat loots.

"You've got to quit your job.
You've got to quit your job."
And if you're lucky get some funding you SOB.
And that's the message we send to part-time slobs.
And expect them to keep banging on MS Bob.

Of course they're gonna blog six days a week for fun.
But that ain't real marketing.  Engineers can't market, can they?
"We're just code monkeys."  Well some of us apes
Can write Java and copy.  Why you gape?
And if we can grok code, AdWords, and email
Then there's no reason we can't do software retail.
EWW!  Oh wait, seventy percent margins ain't fail.

So you solos out there,
Put your hands in the air!

Chorus:

I'm a solo founder, yes, I'm a solo founder,
All you VCs can go eat clam chowder.
So won't the solo founders please stand up, please stand up, please stand up.

Repeats.

DHH got to cuss in his keynotes to get attention,
Well I don't, but I guess it works for him
(By the way thanks for Rails.)
Half of you Redditors don't buy software,
"But if I don't, who does?"
About half the population.  300 million in the nation.
Try selling to women -- you'll be swimmin' in it.
Sometimes a profit beats an exit.

Shoot, I help your kid's teacher play bingo
If that don't prove there's a niche for everyone
I don't know when you gonna believe.

"Yeah, that's real cutting edge, hehe."
Yeah some of us ain't downloading MP3s.
My customers can't even spell PHP.
So what?  Their money's green as your ping stats
Better your wallet than your disk FAT.

And there's a million of us just like me
Who code like me, who sell stuff just like me,
Who write like me, blog, talk, and act like me,
It ain't the next best thing, the real deal's me!

Chorus.

I'm like a lecture to listen to, cause I'm only giving you,
Things to joke about on IRC in your chatroom.
The only difference is I've got a mailing list.
With 2,000 people paying to be on it.
It's called "Customers" -- what a concept.
I'm not the only one on the forum yakking
About making apps, the overflow's stacking,
And I'm building stuff but it ain't rocket science,
Every single one of y'all could try it.
You could be working at Burger King,
Laying out the router rings,
Or in the cubicle banging, Screaming "That ain't null!"

With your collar down and your temper up,
So won't you single founders please stand up
And put three fingers on your hand up?
And be proud to be out of your mind and in control.
And one more time,
Loud as you can,
How does it go?

Chorus x2

Haha,
Guess there's a single founder in all of us.
Let's all stand up.

Actual discussion:

OK, now that my burning urge to karaoke is out of the way: there are a lot of business models out there, and many of them can work.  You can probably even make money with a Twitter client written in Lisp.  I wouldn’t want to have to do it but, then again, I don’t have to, just like you don’t have to wake up in the morning and help little old ladies get their bingo cards in large print.  And that’s perfectly fine.

If it wasn’t totally obvious, tongue was planted firmly in cheek while writing the above, and when given the choice between saying what I really think and making lame attempts at humor, the humor may have won out.  For example, you might on listening be under the impression I have not quit my day job, which is not accurate as of last Monday. (I’m still kind of in shock — and still have work to go to in the morning. See you on a more permanent basis in a few months.)

I don’t claim to be anything particularly special as a businessman and, as you can see, I have few musical skills to speak of.  But if you can’t laugh at yourself then who can you laugh at?

The above song and lyrics are copyright Patrick McKenzie 2010 and released under the Creative Commons By Attribution license.  Go nuts.  It was recorded with assistance from Audacity.

Comments Off