Archive by Author

A Beautiful Twist On A Boring Old Thing

There are a few apps that I typically recommend people run away from, largely because the market for them is flooded.  Backup apps.  Photo organizers.  Product management web apps (which is overrun largely because Basecamp is amazing and the code to it practically writes itself in Rails, since Rails is after all “Basecamp, minus the domain expertise”).

The trouble with getting into an uber-crowded market, in a niche which is essentially a commodity service, is making yourself heard above the din.  So instead of being Generic Photo Organizer #1278, maybe you could be World’s Best Photo Organizer For Wedding Photographers.  This allows you to carve out a little niche which is addressable (i.e. you have some way of reaching them, for example when they Google [photo organizer wedding photographs]) and which will leap at the chance to pay you money.

I saw a beautiful example of this, which was just released this week: ProjectThingy.  It is *yawn* project management software.  But it is project management software which you can embed in your own website, and I’m convinced that makes all the difference in the world to a certain population of technically disinclined SMEs.  

The author (Chris Ritke of 49things.com) also has a stable of other embeddable applications.  One of them is UploadThingy, also swimming in a crowded, crowded market (crikey, I think at least four of those have come through the Business of Software boards alone), against competitors with great PR like DropSend and a few startups with millions in VC funding.  

I predict he goes on to make a mint with that selling point.  And indeed, the UploadThingy already has 100 paying customers, which is probably somewhere in the vicinity of $3,000 a month in revenue (I worked from DropSend’s published statistics about plan uptake rates and projected it to 100 total customers).   A (very) nice sideline for the moment and with two sister-apps just launched he should be raking it in by the end of the year.

Bingo Card Creator Year 2008 In Review

Well, it is that time of the year again: home for Christmas, jetlagged like crazy, and up at 2:00 AM after passing out for 11 hours.  Sounds like a great time to compile end of the year stats!  These will change a bit in the next 10 days or so, but not all that much, so they’re roughly representative.

In A Nutshell: 2008 was a very, very good year.

My goal had been to sell $20,000 worth of BCC, after having sold $10,600 last year.  

Sales:

Total Sales: 815

Refunds: 24  (~2.9%)

Sales Net of Refunds: $20,707.40

Customers requesting CDs: 205 (24.9%)

Customers using Paypal: 373 (46%, remainder Google Checkout)

Expenses (Approximate):

AdWords: $5,850

Freelancer (Bingo Cards): $1,000

SwiftCD: $1,050 

Paypal: $400

Domain Names: $500  (Kind of went hog wild, eh.)

Hosting: $500

CrazyEgg: $240

Software: $200

Clicky: $90

e-junkie: $60

Total: ~$10,000

Profit: ~$10,700

 

Various Other Fun Metrics:

Unique Visitors (to main site): 285,000 

Page Views (main site & ChristmasBingoCards.com) : 1,000,000

Trial Downloads: ~57,000

(Implied minimum conversion rate: ~1.4%)

Confirmed Installations: 12,700

(Implied maximum conversion rate: ~6.4%)

Number of people who sat down at their computer one day and said “You know, I really need to play some Cheese bingo”: 52

Number of people who played Christmas bingo (plus an unknown number who evaded tracking when I borked it): 5,652

Commentary:

What went spectacularly right: In my writeups of last year’s results (blog and BoS forum) I had mentioned that I had high hopes for incorporating the bingo cards into my site design, to catch people looking for specific niche activities and funnel them into downloading BCC and then eventually making me money.  This has been a smashing success, and has greatly improved my SEO efforts.  The $1,100 paid to a freelancer might stick out in the expenses — I assure you, it is like paying for straw so you can spin it into gold.  And the loom is 95% automatic, whee.  I’d make such a poor wicked fairy, I make so much on the alchemy I can afford to do it without needing anyone’s firstborns.

The other thing that has helped me out was continued improvement in Google AdWords, largely due to Conversion Optimizer — I don’t get to keep nearly as much of the sales I get from it ($5,850 — Google, I want a nice Christmas gift from you guys)

What went wrong: I had much higher hopes for ChristmasBingoCards.com than eventually ended up getting realized (see here).  

I also regret that I have not proceeded much on the project I started at the 30 Day Sprint this summer — despite paying Slicehost quite a bit to keep a 512 MB slice sitting largely idle (yay, SVN repository) and my designer $500 for the design, I have done almost nothing with it since the summer.  I blame a combination of personal issues during the summer and work issues for the rest of the year — nothing sucks it out of you like getting out of work at 10 PM and then facing a 2 hour commute.  Hopefully I’ll be able to do a bit of work on it over the break, when not enjoying family and friend festivities.  After all, as nice as BCC is I have dreams of eventually going full-time and while BCC provides a quite nice foundation for that I think the next project will be the one that pushes me over the top.

Other Random Trivia:

  • My chapter in Blog Blazers was published.  I really like how it came out, and “My son, the published author” cooings have made my free copies great Christmas gifts.
  • I now hang out on Aaron Wall’s SEOBook forums quite a bit, as a moderator.  SEO is one of my favorite parts of this job — great intellectual challenge, combining a bit of engineering, a lot of marketing, and heaping helpings of pure magic.
  • As of next year, BCC will be providing part-time incomes for about five people (three freelance writers and my designer, plus me).

Goals for next year:

  • $30,000 in sales for BCC
  • $20,000 in profits for BCC
  • Release a second product
  • Go full-time (we’ll see where life takes me)

Learning From (A Specific Example Of) Failure

Images are thumbnails, click to see the larger versions.

Background info: I sell software called Bingo Card Creator which makes educational bingo cards, largely for teachers.  Much of my marketing revolves around receiving attention for things I give away for free on my website which interest people who are good fits for my product.

This blog usually chronicles my successful efforts to promote my software more than my failures — I typically stop those in mid-stream and promptly forget about them.  But, in the interest of keeping myself humble, my Great Big Idea For December (“set up a mini-site for a seasonal Christmas promotion, go viral, win”) has been a qualified failure as of this posting.  I thought I’d write it up as a post-mortem so that other folks wouldn’t have to repeat my mistakes.

If You Fail To Plan, Plan To Fail

I spent what is, to me, quite a bit of money to set up the Christmas Bingo Cards mini-site.  My goal was…  well, I’m not entirely sure what my goal was, which is one early indication that the plan may have a few flaws in it.  The vague idea was something along the lines of “Every year there are tens of thousands of parents looking for free Christmas bingo cards to play with their kids.  I sell a program which makes bingo cards, which parents overwhelmingly do not buy because it is more expensive than their alternatives, but which teachers buy plenty of.  Why, if I could just use the non-paying parents as a marketing resource to reach the paying teachers, I would make a lot of money.”

This might sound a little quixotic but its just a simple variation on most of my marketing: I give away something that is good for many purposes and almost perfect for your purposes and then charge some portion of the population for the removal of the word “almost”.  Free bingo cards, free articles, free trial of software, whatever — its all the same to me.

But when you get down to the nitty-gritty of “How do I turn attention into marketing?”, what you are really asking is “How do I get links for this?”  It is the Internet, after all.  It is relatively easy for me to get links to teaching resources on my website — teachers have classroom web pages, teachers see things they want to share with colleagues or parents, teachers link to them, Google sees link, Google decides I’m a useful contributor to the Internet, I smile.  However, parents don’t have quite the same incentive structure.  

If you’re a busy mom trying to find a family activity for this Christmas, and you find it, you’re happy!  You’ll tell your kids and your husband.  But you don’t necessarily immediately think “Oh, I should really tell the Smiths about this, too.”  And, of course, you have better ways to communicate with your children and husband than through your blog.  Hopefully.  Which means a net total of no publicly-visible recognition, which the type I can most easily springboard off of.

Additionally, in a bit of an “Uh oh, spaghettios” tactical error, I gave out the cards as PDFs.  For those of you who are not familiar with running a website for non-technical people, let me teach you something: PDFs aren’t for whitepapers, they are for flypapers.  If a non-technical user enters a PDF, they overwhelmingly do not exit.  This is especially true if seeing/printing the PDF achieves their immediate goal: OK, I have what I came to the website for, I’m done!  Great news for them, bad news for me.

My first draft of the website required two clicks to reach the PDFs instead of one (for an obscure WordPress-related reason that you don’t care about).  This is terrible behavior from a user-experience perspective as the first click just brings you to a no-value page with a comment form.  And the comment form got FILLED with comments from people thanking me, presumably while they were busy downloading the PDF.  When I replaced that with the user-utility-maximizing “click here and it opens up directly in your browser” workflow, user interaction with the site plummeted.  (I still have comments on my main page, and I got them, but at a rate about 1/20th of the rate I was getting before.)

So if you can’t get people to do the extra work to leave a comment expressing thanks, the extra quantum of work to blog about you is a bit of a stretch.

Time-Sensitive Promotions and SEO Don’t Mix Well

Here’s another issue — I launched this site on roughly November 25th, and I know (based on prior year’s results) that user interest in what it offers peaks at December 15th and then declines rapidly.  It is absolutely critical, then, that if the site is to rank in the search engines it rank by December 1st and continue ranking for 3 weeks, after which it is markedly less critical.  I know a bit about SEO so I should have seen this coming: that timetable is FAR too aggressive, as most sites will take months to rank, unless they go viral.  And, as we’ve discussed, the combination of users and site design was a pretty good antibiotic.  

Here’s what actually happens: Google happened to rank a page on my main site fairly decently for the related search terms.  I thought I shouldn’t compete with my own promotion, and 301 redirected that page to my new domain, additionally switching internal links on my site over.  I am pretty sure that, eventually, that will work out pretty well.  However, it tends to cause rankings to bounce around for a while, and I really didn’t have “a while” to wait.

As you can see, traffic starts out fairly low (due to residual marginal rankings from the 301ed page) and then crashes, as Google spends some time deciding what to do with me.  Bad time to crash, dude.

Google Dominates All Search

It used to be that Google overwhelmingly dominated search among the technically literate, but Microsoft and Yahoo had significant share among people who think that the little E icon is synonymous with “the Internet”.  Those days have passed.  I have top-three rankings on both other search engines for the terms of most interest to me, and they send in an absolute trickle relative to Google: top organic rankings on MSN and Live simultaneously can’t do as well as top paid rankings on Google, even on search terms which play to their strengths.  (Paid search typically gets the snot beaten out of it by organic rankings.)

On This Wisdom Of Paying To Give Things Away…

I had a bit of a chicken and egg problem — how to get people to the site, and hopefully link to it (and thus fix its rankings) when it was not ranking well?  Many Internet businesses have the chicken and egg problem.  I used some appropriate countermeasures, like nepotistically linking from my other properties, but that didn’t do it, so then I decided “Well, if I just spend a little money advertising it, I’ll get a paid traffic to free snowball”.

This could, potentially, have worked in theory.  It was a crashing failure in my case.  It was even more of a crashing failure because I did it so darn well.

You want to know the recipe for a high click-through rate on an AdWords ad?  (I have edited the image to make what the user sees clearer.  Nobody reads on the Internet, remember, they scan.)

1)  Headline of ad promises exactly what they’re searching for.

2)  Strong call to action which gets them to what they want.

3)   Domain name which screams I’ve got what you want.

Blam!  11% click through rate to a paid listing.  (That is pretty darn high — usually I’m lucky to get 2%.)  Which means Google gives me the top spot (since I’m making them the most money per impression), and I get to have the maximum opportunity to give my money away for nothing.

*sigh* Doh.

AdWords Is Still A Good Deal

The nice thing about paid search advertising is that it captures user intent like nothing else does.  When someone searches for “christmas bingo cards” and then clicks on a link to christmasbingocards.com, you know what they are looking for?  Christmas bingo cards.  Sounds obvious, right?  That blazingly, achingly clear intent is present in no other search mediums.  This is why display advertising is such a bad proposition for most advertisers (except big brands who want to burn money because their advertising agencies say that it is tradition to burn money if you’re a big brand, and that they will manage the burn for only 10 cents of every dollar).

But anyhow — if you pay eight cents for a click on that search term (like I was — obscenely low but that is what happens when you have a high CTR on a term of fairly low general commercial utility), you get something for your 8 cents.  That isn’t generically true of Internet advertising.

Enter Stumbleupon

 So in the “try to make it go viral” brainstorming phase, recognizing my core customers are not quite the type that dig blogs (to say nothing of Digging blogs), I though I would try to reach out to the more technically inclined folks.  I started an advertising campaign on Stumbleupon, targetting Stumbleupon members who were 25 through 99, female, and interested in activities for kids.  (I picked these because they are essentially my target market.)  So I largely got in front of the right people, but not necessarily at the right time.

That was pretty effective for a while at getting Thumbs Up, which is a stumbler’s seal of approval.  But most of them are only on a website for 2 seconds or less, and the hoped-for stumbled-it-to-blogged-about-it transition did not quite happen.  *sigh*  So instead of paying 8 cents for someone who was intensely interested in what I had to offer (and spent an average of 2+ minutes on the site), I paid 5 cents for 2 seconds of attention from someone who was merely interested in browsing through a few dozen sites to flit around and, perhaps, see something to capture their fancy for as much as 10 seconds.  Sadly, but probably predictably, a few thousand stumblers did not translate into a single link.  (The thumbs up did translate into getting many free stumblers in addition to the paid ones, but then you’re back at square one: paying nothing for traffic of no value is still not a good deal.)

Stumbleupon: channel surfing for the Internet… or ADHD with an API?  I’m not quite sure.  What I’m quite sure about is that I won’t make the mistake of paying for advertising there again.  I should mention that some people I respect have had success with it, for example Dharmesh Shaw (as seen in comment here and post here).  So I guess I feel like it the way I know a lot of people feel about AdWords: works for other people, did not quite work for me, might be because I botched the implementation or might be because my market is a poor fit, not interested in spending further money/time to narrow that down though.

Directory Listings

On the advice of Aaron Wall, who generally recommends jump-starting SEO campaigns with a few paid directory listings from high quality directories, I bought a pair of listings.  I could have done more but didn’t quite have enough confidence in the project to warrant it…  funny how things look cheap when you’re buying them in 8 cent increments but expensive when you’re buying them in $40 increments, even when the 8 cent promotion method is ultimately more costly.  Incidentally, I’m not unhappy with the directory’s performance — I consider it sort of a cost of doing business (like the domain name) and am reasonably sure I will eventually get #1 for my target terms, just outside of the time frame I needed.

Final Tally

I give out financial numbers so I’m not, in principle, ashamed to mention this, but crikey is it embarassing:

Domain name: $240

Transfer of domain to GoDaddy: $7

Server: free at the margin (had one already)

Google AdWords: $140

StumbleUpon: $130

Directory Listings: $80  

Total: $600

And what did I get for my six hundred bucks?  Well, about $50 in marginal sales and almost no link loving from my customers.  So that’s the bad news.  I got half a dozen emails thanking me, about 50 comments to the same effect, and did help a couple thousand people with their Christmas planning… so I’ve got that going for me, as Bill Murray might say.  (I can’t remember what movie, sorry.)

That doesn’t include my time setting up the mini-site, which was fairly substantial.  I was able to leverage OSS and existing resources to cut down the time substantially but ultimately I’m not a very visual person and tweaking CSS templates and content, which were both required, ended up being huge time-sucks.  Memo to self: next time, use freelancers, they’re cheaper than I am.  (I actually have one lined up.)

What I’m Doing Differently Next Time

I’ve already registered the exact match domains for most of the other bingo card sets that are high value to me, and I plan on iterating on this experiment until I get it right or am convinced that it doesn’t work.  What I will do differently:

1)  Start earlier for time-sensitive promotions.  1 week lead time means you need a lot of advertising to get over the hump, and advertising costs money.

2)  Make the content more easily shareable.  I have a few concepts on what to try… we’ll see what works.

3)  Move the focus off of “download this PDF and cease interaction with my site”.  I’ll probably need to bulk up the sites a little more.

4)  Give away a little less.  Typically, on my main site, I give away 8 bingo cards for any set (on the theory that parents will rarely need more than that) and make people download my free trial for 15 (one step closer to conversion) and pay money for as many as they want.  This market-segmentation-by-demonstrated-need works very well for me.  This time, I gave away 32, which I chose to be high enough for almost anyone’s uses, including my core customers.  (Not entirely sure what I was thinking there, I have to admit.  That decision got made at about 2:30 AM and it sounded like a good idea at the time?)

5)  Cut unproductive advertising expenses.  Sorry, Stumble.

6)  Leverage my main site more.  I ended up sending a lot of people from my well-monetized main site (where I have spent 2.5 years learning to convert visitors) to my poorly-monetized promotional site (where I have no experience and was, indeed, almost passively hostile to making money).  Next time, I’m going to give myself enough time to think through the funnel on both sides and try to push value in the right fashions (attention is valuable among poor prospects, trial downloads and sales are valuable among good prospects, channel them accordingly).  

Conclusion

Well, that hurt like the Dickens.  I feel better for having written it up, though — that gives me more confidence that I at least learned something for my six hundred bucks.  Hopefully you all did, too.  

This is probably going to push me close to my first monthly loss for the business ever (December is a very slow time of the year for me traditionally).  We’ll see.  Ahh well, there is always next year.

Programmer's Charity Drive (And How You Can Help)

About two weeks ago Andy Brice got in touch with me about throwing some blogging support behind a programmer-focused charity drive he started this year. I thought, hey, why stop at blogging — it would probably work better with a dedicated website, some linkbait, a little Flickr integration, and the like.  So we put our heads together and came up with something — not bad for two guys who have never met and live about 9 time zones away from each other, eh?

(You know, in the annals of offshoring, this may well be the first time somebody from the UK “hired” an American in Japan on the behalf of “clients” in India.)

Programmer T-shirts is now open for business charity.  I’ve also posted a fairly substantial essay on how both open source software and the principles animating it can be helpful to charity, which will hopefully be a hit with the Slashdot set.  That essay includes tips at the bottom on how you can help out, both monetarily and by giving generously of your time and/or attention, the non-monetary alternate currencies of the Internet.  

Merry Christmas!

Help Debug The World

Andy Brice, man of many talents, is putting together a Christmas drive to make t-shirts for programmers and donate the proceeds to charity. Sounds like a swell idea — particularly the donating to charity bit, as my office will let me wear a T-shirt the day after I get elected Prime Minister of Japan.

Who Benefits:

Jaipur Foot: A charitable foundation which provides support to the disabled and needy in India, including by providing low-cost prosthetics.  

Sightsavers: A charitable foundation which provides surgery and other medical care to people at risk of losing their eyesight due to mostly easily treatable conditions.

What You Can Do To Help Out:

1)  Buy a T-shirt, naturally.  I like “Be Nice: I have a blog” personally.  

2)  Help spread the word about Andy’s charitable drive.

3)  Donate to the charities directly (links are available on their websites, mentioned above).

What I’ll Do To Help You Help Out:

Take a picture of yourself wearing one of Andy’s T-shirts.  Alternatively, if you just straight out donated, take a picture holding a sign with a funny programming joke.  (Or something which would approximate funny if programmers had a sense of humor.  I suggest “I’m in your world debugging your illnesses!”)  

Inform me of the photo in some manner — comment, trackback, email, skywrite your TinyURL over central Japan, whatever.  For every person who does so by Christmas, I’ll chip in $30 direct to the charities.  (We’ll set a sensible limit for the matching grant at, say, the first ten folks who take me up on it.)

Because We Wouldn’t Be Programmers Without An API Call:

 

Lets Play Move The Needle

What It Lacks In Subtlety It Makes Up For In Lack Of Subtlety!

Free Christmas Bingo Cards

Every year around Christmas time, I get literally thousands of requests for Christmas bingo cards.  I decided to do something a little special this Christmas and throw up a website about them — so if you want your Christmas bingo game, you can go there now.  

If you aren’t a small businessman, there is likely nothing else of interest in this blog post.  I suggest clicking on the above link to get your bingo cards.

If you’re a microISV, keep reading: this is an experiment.  For the last several months I have been particpating on Aaron Wall’s SEObook community forums, and he preaches the gospel of Exact Match Domain names as a tool for ranking sites quickly in Google and the like, even allowing them to cut past other older sites that have scads of links.  I have actually seen one of my competitors dip his toes into doing this, too — after I talked here many times about a particular keyword he registered keyword.org and now ranks #3.  Spiffy for him.

I get scads of traffic for all seasonal related bingo cards — if you remember my graph of different categories on my website, Holidays accounts for almost a quarter of cards downloaded by visitors.  The top few holidays account for the lion’s share of that — Halloween, in particular, is the reason October is invariably the best month of the year for me.   

So I decided, hmm, why not try an experiment this year and see if I could drive rankings for just a few head terms instead of doing my usual rank-for-everything-under-the-sun strategy (Crustaceans bingo, ho!)  That could involve getting a few dozen links to my site, but it is fairly difficult (though by no means impossible) to get people to link directly to a commercial site.  Instead, I thought, I’d make a mostly non-commercial mini-site focused like a freaking laser on giving people exactly what they wanted, and making it as easy to link to as humanly possible.

Step #1: Identify my keywords.  I already know them, in this case — the next big holiday which gives me suitable time to get ready is Christmas.  The #1 keyword is Christmas bingo cards.  I can look at my website logs and find 15 variations of that to play with.

Step #2: Buy the exact match domain.  Somebody had actually registered [Christmas bingo cards] before.  Oh well.  He was amenable for selling at the quite reasonable price of $149 — then I paid another $8 to move it to Godaddy, my registrar of choice.  (Is this reasonable?  Well, consider that I spend 25 cents to drive one download of Bingo Card Creator, or roughly $15 per sale, when I’m paying on AdWords.  I’ll spend more on AdWords this week alone than the domain cost me, and as of next week its like that money was never spent… but the domain stays up for years.

Step #3: Install WordPress.  You really can’t beat WordPress for making attractive, small sites with a minimum of time investment.  They don’t even have to necessarily look like blogs, if you choose your template well.

Step #4: Find an attractive template.  This is honestly one of the most important steps.  You’re creating a site to be the One Canonical Source On The Internet for your little subniche — it should look the part.  An attractive site makes it very easy for it to collect links from your customers saying “Hey, Ethyl, I just saw the best site on the Internet for Christmas bingo cards.  You should check it out.”  You can either outsource this to your favorite designer or use an OSS template.  Happily Smashing Magazine (a blog devoted to, hmm, beautiful things?) covered an absolutely outstanding Christmas wordpress theme last year.  It took me maybe 5 minutes with Stylizer to smooth some rough edges.  (Needs another 5 minutes for the sidebar in IE.)

Step #5: Supplement with pretty graphics.  Stock photography and stock icons make everything better.

Step #6: Write the content.  I wrote several blog posts and pages about the subject, in my usual voice.  This took more time than everything else put together, and it isn’t done yet — I eventually hope to have perhaps 5 or 10 pages on the site when it is ready.  Tips: You probably want to use WordPress to replace the front page with a Page rather than a listing of your most recent posts.  You also probably want to remove much of the blog-specific cruft, as the site will probably not be receiving year round regular updates so why lead people to expect that?  

Exactly what the content says is up to you.  I didn’t try to sell very hard at all — many of the folks who find this site are going to be parents, and parents don’t typically buy Bingo Card Creator.  But parents are quite capable of leaving links.  (Teachers, on the other hand, may decide to actually purchase BCC.)  Plus, because the site looks like the #1 destination on the Internet for christmas bingo cards (look at the design!  look at the domain name!  look at the Zen-like purity of purpose!), it should probably pick them up from authoritative sites as well.

Step #7: Make it scale.  If it works… why stop at one mini-site?

Do You Debug Your Website?

I can’t say that the bug this post is about is my worst bug ever.  Or even my most embarassing bug ever.  But it is certainly my most costly bug ever.  But first, a picture.  You can click it to see the full-sized version.

The above graph shows two years and change of monthly visitor counts to my business.  There are a bunch of milestones I could have put up there — the new versions of my software, the key events in my market’s annual cycle, the redesign of my website, the time I quadrupled my advertising budget.  And they all pale in comparison to squashing one stupid little bug.

What Could Possibly Have Done That?

Well, like many bugs, the impact of this one rose in direct proportion to how clever you are.  My business website runs on a custom-designed CSS which cranks out free printable bingo cards.  The home page, shopping cart, main level navigation, all of these things are valuable towers which sit on a gigantic foundation of free content.  That content attracts me links, traffic, and searchers.  The bright idea to make the production of this content scale is probably the single biggest thing I’ve ever done to grow my business.

And scale it does.  I pay a terrifically talented freelancer to write the actual word lists that become the bingo cards, and provide a little bit of color commentary.  I feed her input into the CMS, and *bam* web page, downloadable PDF, and GIF are created.  Now multiply this times a couple hundred, for very little additional work on my part.

The Best Laid Plans of Mice and Men

One design decision I made when building this automated marketing machine was to give it a time-based element: one bingo card got featured a day.  Originally this was largely because I had the site separate from my main site and wanted to call it Daily Bingo Cards.  I figured, hey, if a new card pops up to the “front” page every day then it will always be fresh, and that makes it stickier for folks.  (And, as it turns out, I do have a handful of folks who a year later are still loading the page several times a week to see what is new.)

However, I had (totally unfounded) performance worries about Rails when I wrote this application.  I thought hitting the database for every pageview was needlessly taxing on my server (bzz, I only get a few thousand a day, why the heck would the server complain?)  So I decided to turn on caching.

Caching is a wonderful tool.  You can use it to solve just about any performance problem.  It solves it by replacing the problem with a cache expiration problem.  (No performance problem?  Oh, you get to deal with cache expiration anyway, don’t worry.)

How Hard Can It Be?

Now, if you want to refresh your content on your website once a day, and you’re not really particular when you do it, caching should be dead easy: purge the cache once a day.  Which I did.  Sort of.

You see, Rails stores cached pages in the same directory your static HTML is being served out of, as static HTML.  Your web server treats the cached pages as it would any other web page if they exist, and just slurps them right out of the directory and spits them out at whoever is requesting that page.  This is blazingly, bugs-in-your-teeth fast.

And to clear the cache?  Simple — delete the HTML file and it is like it never existed.  Your web server, seeing no file matching the user’s request, will fallback to calling Rails to see what to do with the request, and after Rails does its magic there might be a new HTML file deposited into that directory.

And how to delete a file once a day?  Stick task in chrontab… done.

Your Testing Protocol Leaves Something To Be Desired

Now normally a line which is, roughly speaking, the complexity of rm -rf /some/file/name/goes/here is pretty hard to screw up.  But knowing well my pechant for screwups I tested those lines before I wrote them into the crontab.  As root (do you see where this is going?)  And they worked swimmingly.

Of course, when I wrote them into the crontab, I did not set them to execute as Root.  No, I set them to execute as the user that I thought would be dropping the files — clearly the web server, right?  (WRONG.  The web server proxies requests to Rails, but Rails operates under another user to write the cached html.  I knew that on an intellectual level, but it did not occur to me one fateful evening when writing that cron file.)

Compounding Errors

So, as a result, large portions of my website were not getting refreshed when I thought they were.  As a result, instead of a dynamic bingo card publishing empire, with constantly refreshed content that was added to, content on the website was fixed at first generation and then went stale.

Had it stayed stale, I would have eventually figured things out.  But no — I was developing the site, occasionally, and every time I deployed a new version of it, one of the deployment steps had the side effect of nuking the cache directory.  And since the only reason I would be trolling on my own bingo cards pages was to see that my changes were taking effect, I never saw the bug.  

Meanwhile, between bursts of development activity, the page would look like an unattended ghost town for weeks or months at a time.

Diagnosing The Error, or, Reality Bites Your Hindquarters

Periodically I check what bingo cards my users find most appealing, both for curiosity’s sake and to guide development of new content.  Typically this is largely seasonal in nature — in November, for example, I can tell you without looking that bingo cards for Thanksgiving are going to have a total lock on the most popular crown.  But sometimes I’ll notice other patterns — a church sends my site out in their weekly flier and Bible Bingo gets popular for a week, some school has a unit on Chaucer and suddenly I see a surge in searches about the Canterbury Tales, and the like.

And then sometimes you see things that can’t be explained.  Insects being on the top 10 list for two months.  But you ignore it — maybe some people like bugs.  Cat Breeds for two weeks?  Maybe some people like cats.  But the one that finally clued me in was The Moon.  Because either NASA camp was playing Moon bingo every single day in July or something was up.

The Game Is Afoot

So I checked the database to see what card was scheduled for that day, because the card that gets top billing should typically be at or near the top of the most popular list.  And the database dutifully reported: none.  Which is impossible — had I run out of cards?  I thought I would still have about 100 in reserver.  I checked the database and saw, hmm, closer to 200.  Meaning either I was off on my mental count or about 100 had not been assigned.

One quick Ruby script later, iterating through all the days in summer, and I realized that only 6 days in summer had seen a new card assigned.  The error log showed nothing out of the ordinary for the other days.  As a matter of fact, it showed… nothing for them.  It was like the website wasn’t getting generated at all… or if it was, it was being served 100% out of cache.

Shoot.

Five minutes later I found and fixed the bug.  I was so mad I nearly posted a note about it here, but figured no one would care.  Had I known at the time how bad the impact was, I would have had apoplexy.

Fast Forward Three Months

If you know what happened, this seems like a pretty teeny bug conceptually.  Google sure didn’t see it that way — this bug made a live, growing website look largely dead to the world, and Google accordingly sent most of their searchers to get their bingo cards elsewhere.  (Ever wondered if Google values “fresh” web content?  This is my most convincing experience that says the answer is YES, although there are a couple of reasons why the pages are better with the daily updates happening which go a bit deeper than “they smell fresh that way”, which are out of the scope of this post.)  After the website was restored to vibrant life, Google opened the long-tail floodgates.

And the difference?  I’ve more than doubled most types of traffic, both search related and otherwise.  (Funny, while no user thought this was important enough to email about — and would you email if a favorite website went dead for a while during the summer?  — many sure thought it important enough when it was fixed to take notice.)  There are a few confounding factors in there (increased advertising budget, seasonal fluctuations, etc) but nothing accomodates for anything like the huge run-up you see in the graph.  My sales graph also shows a bit of a bump, to put it mildly.

Word to the wise

1)  Test your website with the same diligence you test your application.  Or, in my case, improved diligence.

2)  Pay attention to your website.  Even the boring bits.  Especially the boring bits that make you money.

3)  Never send a commited Windows programmer to do a Unix sysadmin’s job.

Can My Customers Use Paypal Without An Account?

Yes.  This fact isn’t very well documented and I’ve seen folks who have sold $100,000+ with Paypal tell you it is impossible.  However, not only is it possible, it is actually exceptionally easy for customers.

Briefly, a prospective customer arrives at the start of the Paypal Express (fancy term for “Paypal hosts the checkout flow”) funnel by either clicking on checkout in your shopping cart or clicking on a buy it now link.  That page is presented differently based on whether the customer currently has a cookie with Paypal or not.  

If the customer is cookied:

They are told to log in to their Paypal account.  Here’s an example (I have used my own site’s shopping cart, so you’ll see my payment email address and the name of my product in both screenshots):

If the customer is not cookied:

They get a split screen.  One half of the screen presents a checkout workflow which they can enter immediately.  The other half presents a sign in/sign up with Paypal dialog.

Why Paypal does things this way:

In a word, because it makes them money.  You have to understand that Paypal’s primary source of revenue is interchange fees.  And their primary expense?  Also interchange fees.  When somebody pays $24.95 for a copy of Bingo Card Creator, Paypal makes $1.02.  And if that person paid through a credit card, Paypal now owes about 70 cents, give or take, to the credit card company.  

If, however, that customer had a Paypal balance and paid through Paypal, completing the transaction is free to them — all they have to do is a database update on their own records.  Ca-ching, tripled their profit!  Or, if the person has no Paypal balance but has linked their checking account to their Paypal account, Paypal can do an ACH debit on the checking account for much, much less than 70 cents.  Again, more profit.  

Then there is also the matter that conversions are much higher when all you need to do is convince people to signin and click “Purchase” rather than filling out a dozen fields in a form.  However, for those folks who are holdouts about getting a Paypal account, requiring them to get one costs conversions and thus costs Paypal money.  This is why they continue to prominently offer the “guest” checkout to people who do not have a Paypal account yet.

What this means for you:

Have no fear — Paypal’s check out experience is optimized to make them money, but as a side effect that means it is also optimized to make you money, by automatically presenting all prospective customers with a purchasing option which is appropriate for them.

Book Recommendation For Budding Bloggers

Almost a year and a half ago, Stephane Grenier approached me about contributing a chapter to a book he was editing, at the time entitled Interview The Pros.  The general gist was collecting the thoughts of several dozen successful bloggers in interview format.  I was honored to be included (it still amazes me that I could credibly be included in a list of names including Seth Godin and Jeff Atwood), dashed out a chapter, and forgot about the project for 18 months.

Then on Tuesday the mailman stopped by my little apartment in central Japan and dropped off a package.  Five promotional copies for me — whee!  It turns out the book has been retitled Blog Blazers, an act I think Stephane owes somebody a beer for.  (The importance of titles is a major recurring theme in the book.)

I promptly updated ye olde resume to include “published author”, gave a copy to a friend of mine who was starting a business, and set about to reading it.

Structure 

The basic style of each of the 40 chapters is a question/answer session with the interviewee.  The questions are identical.  Representative sample:

  • What makes a blog successful?
  • How long does it take to be a successful blogger?
  • What is your biggest tip on writing a successful blog post?
  • What are your main methods of marketing your blog?
  • How do you monetize your blog?

The sheer diversity of answers to these is amazing — the book includes everyone from folks whose blogging generates a full-time income from AdSense, software consultants who are looking for professional contacts, an online weightloss diary, some guy with an interesting fascination with shoes (who wrote the funniest chapter, by far), and one computer programmer who should probably listen to his own advice more:

Speaking of timescales in blogging — recognize that you will be blogging until you stop blogging.  That sounds simple, but many peopole start out with a burst of post-every-day fever, which they cannot sustain over the long haul.  Pick a pace which is predictable and sustainable.

In my defense, it sounded a lot more credible when I wrote it.

My chapter focuses mainly on blogging as a small business and practical tips you can use to achieve success that way.  (A few of the other chapters are a bit more inspirational in nature, although most of them have some actionable advice.)

In Which I Disagree With My Marketing Idol

Example from my chapter:

I personally can’t stand the “Top Ten Ways To Write A Blog Post” type articles, as aside from being boring and aesthetically unpleasant they turn your blog into a commodity provider of lists.  Instead, absorb the lessons that style of writing provides which continuing to have unique positioning for your blog.  The important lessons are “titles which promise immediate benefits are a good idea” and “judicious use of formatting such as bullet points, bold text, and pictures can turn a scanning surfer into an engaged, active reader.”

Seth Godin’s take on the issue:

Use lists.

Write short, pithy posts.

That is one of many, many disagreements the authors have with each other, and I find them fascinating.  (A few other points of contention: the importance of monetization, the ideal post length, and the importance of SEO.  You’ll find many well-argued solutions to all of these in several chapters… and the right answer in my chapter, naturally.)

Single Best Advice From Me: 

I recommend… that you get familiar with two groups of websites in your niche: the folks who have achieved something close to what you want to achieve, and the folks who are on the path to success but just a wee bit farther than you are.  The first give you examples to emulate and objectives to strive for, and the second should become your new best friends, because a) they’re not too busy yet that they have millions of admirers and b) their support can really kick start your blog and help you both get closer to your goals.

For the other 200-odd pages of advice, you’ll have to buy the book.  At $16.95 I’d honestly say it was a steal, even if I had no connection to it whatsoever, because the value a blog can drive for a small business is immense.  (See my chapter, and several others, for elaboration.)

You’ve got two options for getting it.  One is to buy it directly from the Blog Blazers‘ site (where there is an e-book option).  I’m going to encourage you to sidestep them and purchase from Amazon instead.  My big reasoning for that is that publishing is a winners-win game, and purchases through Amazon increase the book’s Amazon rank, which results in more prominent placement on the site and also results in indirect marketing opportunities (“buy Blog Blazers, currently #1234 on Amazon”).  (At time of posting they only have two copies left.  Small order to start out with = book languishes in obscurity.  Break the cycle — buy a book today ;) )

As usual, I don’t have any monetary interest in the book or in your purchase of the book.  (i.e. those are not affiliate links)  I contributed to the book because Steph asked me to, and it was a pleasure to contribute a small bit to something which will hopefully provide value to people.  If you’re one of those uISVs scratching your head thinking “So I’ve heard them say 432 times ‘Blogging helps for marketing’ but I don’t consider myself an expert at this yet”, read the book.  I guarantee you you’ll learn something.

P.S.  Seth Godin is one of the world’s best living theorists about marketing.  I am not Seth Godin.  You are not Seth Godin.  Please, for all that is holy, don’t write list posts.

P.P.S. uISVs will recognize more than a few names: Ian Landsman, Bob Walsh, and Andy Brice all contributed chapters.

P.P.P.S Remind me to get the contact details of whomever did the cover design if I ever publish anything.

 

Cover of Blog Blazers book, depicting man with BB on chest standing atop world.

Cover of Blog Blazers book, depicting man with BB on chest standing atop world.

Rails Fails To Update Serialized Columns On Save

One of the problems I hit earlier today, which literally cost 2.5 hours to resolve, was that I have a Rails model which uses a serialized column in it.  The column contains a hash of options for the object.  Fairly simple stuff.

As it turns out, after overwriting one of the parameters in the hash and saving it, the object in the database would be out of sync with the ActiveRecord object still in memory (even though save returned true), which lead to hilarity the next time someone grabbed the object from the DB and got partially out-of-date data.  (Inconsistent out-of-date data.  Failure.)

As it turns out, the issue is a new feature Rails 2.1 — partial updates of database records.  Rails keeps a list of which attributes are “dirty” and only updates those when you call ActiveRecord#save.  Unfortunately, touching the contents of a hash does not mark it as dirty.

I was absolutely clueless how this was happening (I stupidly upgraded to 2.1 on a whim, thinking that I hadn’t written any significant code yet so incompatibilities wouldn’t bother me — true enough, the only incompatibility was with my mental model of how ActiveRecord worked), but I successfully diagnosed the why — a dirty bit wasn’t getting set for the serialized object.  OK, no problem, the same thing happens at the day job with our Java system — which means I can use the same hacky solution to the problem.

def before_save

  options_hash_clone = options.clone  #shallow copy of options hash

  options = {} # sets dirty bit for options hash

  options = options_hash_clone # restores options hash to original content, ensuring save updates it in DB

end

which will, indeed, set the dirty bit. 

As it turns out, there is a cleaner way to do this if partial updates aren’t a requirement for your model:

#there are a number of places you could put this — the model class itself strikes me as decent

ModelNameGoesHere.partial_updates = false

A big thanks to this post for putting me on the scent of the problem.  Seems I missed quite a bit of discussion on Google about it since I was not hitting the right keywords apparently.  The fact that this is on by default appears to be one of those opinionated software practices where “opinionated” means “it is our opinion that you should be as familiar with the change log as the core team before you install a new production release”.  (Sorry if I sound bitter.  2.5 hours.)