How to easily pull avatars from multiple services

Sleeqmale Sleeqfemale
Sleeq's defaults from Rob Walker's gallery of unset avatars

I love Gravatar, the service that lets me associate my email address with a portrait or avatar that services across the web can then use to represent me when I sign on to their site. The trouble is, not enough other sites use it, so I have to keep uploading an image to every service I use, and not enough of my friends are on it, so I can't easily pull images for them. This all makes it really hard to create visualizations of my social network based on email, since I can't get pictures for most of the addresses.

To solve this, I took Shannon Whitley's awesome SPIURL project that provides permanent and easy URLs for Twitter handles, and created a new service that gives you a simple way to pull avatars images from Twitter, Facebook, Digg and Gravatar, and associate them with an email address.

You can try it for yourself at http://overtar.appspot.com, which has the full documentation. Its goal is to try really hard to find an avatar for a user by looking on multiple services, allow you to specify a custom image if none is found, and then cache the result. It uses Gravatar images if they're available, but if they're not it doesn't authenticate that the person setting an image owns the email address, so it's not a replacement, more a light-weight complement. I have the option to filter out unverified images, but my goal was to make it easy for my application to associate an image with an address.

Here's some examples of it in action:
<img src="http://overtar.appspot.com/petewarden"/>
Searches Twitter, Digg and Facebook for a public picture

<img src="http://overtar.appspot.com/pete%40petewarden.com/>
Returns the cached image for pete@petewarden.com

<img src="http://overtar.appspot.com/petewarden%40facebook"/>
The Facebook public profile picture for the user 'petewarden'

http://overtar.appspot.com/petewarden%40mac.com/set/http%3a%2f%2fpetewarden.com%2fportraitbw.png
Sets the cached image for petewarden@mac.com

A lot of people use the same username across multiple services. Instead of offering your user a blank avatar when they sign up, why not take a guess and pull the portrait for the same username on other services as a default? That's what Overtar is here to help with.

What’s your message?

Messageinabottle2
Photo by plusW

"If I had more time, I would have written you a shorter letter"

I've had a tough time taking all the swirling possibilities, plans and dreams of what Mailana can be and boiling it down to a succinct message. This might sound like an academic exercise, but creating a two-sentence explanation of your company creates a foundation beneath everything else you build. The brevity removes any gaps for fudging, vagueness or hand-waving, and forces you to focus laser-like on the core value of what you're doing.

Luckily I've had some intensive help from the master of messages, David Mandell. Here's one of his secret weapons, a simple template where you fill in the blanks:

For _____________ (target market)
XYZ is a ___________________ (elevator pitch)
as opposed to ______________ (competitors/current situation).
XYZ _______________ (tag line)

Try it for yourself, it's deceptively hard! I'm still working on mine, but here's where I'm at:

For people trying to build their networks, Mailana is a way of sharing valuable and real relationships with their close friends, as opposed to conventional networking tools like LinkedIn that don't distinguish between acquaintances and strong relationships. Mailana gets you to "You guys should talk".

As another example, here's what I'd do for Craigslist:

For people who want to trade second-hand goods locally, Craigslist is a free and convenient service matching buyers and sellers, as opposed to expensive and inconvenient alternatives like classified ads or ebay. Craigslist is helping people help each other.

Hmm, I really like that "helping people help each other" tag line, I wonder if it's too general to steal for Mailana?

You can’t fail if you don’t try! (Or why I left the UK)

Grumpy
Photo by Zitona

An article today and a talk last night reminded me why trying to get new stuff done (being an entrepreneur if you want to get fancy) was so damn hard in Britain. The article is from The Guardian on the death of the internet startup scene in the UK. Reading the body it's hard to escape how much the author is enjoying being negative. He doesn't seem sad or angry that the London ecosystem is apparently having so much trouble, more gleeful that he can point it all out. He's a poster child for:

#1 Negativity – When I would talk about my crazy plans for awesome software back home, there'd always be some smirking bugger like Paul jumping in with a million reasons they would never work. I'm sure plenty of people over here think I'm crazy when I talk about what I'm doing, but they've been brought up to be constructive. At the least they'll keep quiet, and some of my most valuable feedback has come from skeptics who really think about what they don't agree with and articulate things they'd like to see improved.

Then I read through the article's comments, and found one that embodies:

#2 Denial – "And why do we want to be the same as the US Web 2.0 start-ups ?!?! … Oddly enough over here we
like to think we have some sense and want to invest in things that can
be seen to work, at least in theory
." How's that working out for you? Sure dodged a bullet with Microsoft (who's going to use dinky micro-computers?), Amazon (buying books online?! ha!), Google (who's going to pay for search?). Thanks to those sort of lucky escapes Britain has no major players in the software or internet industries. Considering how much raw development talent there is, this is a massive failure, and it's impossible to claim that this 'sensible' approach to technology investing works.

I think these two both actually come from a deeper cause, and Paul Berberian gave an amazing talk on it last night:

#3 Fear of Failure
– In Britain, failing in business is a Scarlet Letter, a stain that won't rub off. This is especially dumb in the technology world. Pretty much every founder is setting off to climb Everest naked, hoping to pick up clothing and equipment along the way. The odds of making it to the summit are against you, but the value from the ones who do succeed more than makes up for it. It's impossible to tell in advance who will succeed, so you want as many credible teams trying as you can get.

Paul had already done one of my favorite all-time blog posts on the failure of his last startup, and he spent an hour talking in-depth about what went wrong. He owned the failure, accepted responsibility for it, but the underlying theme was failure sucks but instructs. Back in the UK there were lots of people trying to make sure I didn't screw up, and incidentally preventing me from trying some weird ideas that just might work. Here in the US I'm free to fail, which means I'm free to try and learn, and maybe succeed with something out of left-field too. That's why I love it here, I can get things done!

ps, if you want to see the craziest promo video for a startup ever, check out this one for Zenie

Only Connect

Economicsbloggers

A friend is researching how prominent journalists and bloggers are connected to each other and particular topics. He's having to manually scan through their sites, and Google for pairs of names to spot connections. As you can imagine, with even a few dozen people the number of searches you need to cover all the possible pairs becomes enormous!

Using the magic of Yahoo's BOSS search API, the excellent YBoss library and my Flash graph visualizer I created a tool to automate part of the process:
http://web.mailana.com/labs/onlyconnect/

Enter some people's names, and some topic keywords, and it will start building a graph of how they're connected. If you click on any two terms in the graph you'll see the search results that include both of them.

I don't think this will take over from text search results anytime soon ("It left me with a feeling of motion sickness and confusion" as Marshall Kirkpatrick said when I showed it to him), but it's a good way to dig into how a group of people are connected. Here's an example exploring the connections between economics bloggers:
http://bit.ly/Z1CG7

Customer Optimization

Happycustomer
Photo by Todd Baker

There's a lot of skills that are really hard to develop because they go against our instincts. The most familiar one to engineers is optimizing code, but I've realized that building a great user experience has the same problem.

When a newbie programmer has a program that's executing too slowly, she'll stare at the code, spot some ugly-looking loops or function calls and start re-writing. Hours or days later, she'll try the rewritten program and it will run at the exact same speed as before.

This happens because we're really, really bad at deducing why a program is slow from just inspecting the code and theorizing in our heads. One of the most important lessons programmers learn is to always, always profile before making any changes aimed at improving performance, and then perform controlled experiments measuring what changes work. You will be surprised, every time, guaranteed.

I've been wrestling with the Customer Development philosophy, and it only truly clicked was when I realized it was just about applying the principles behind effective code optimization to your interactions with users.

When a newbie entrepreneur has a service that nobody's using, he'll stare at the website, spot some missing features or ugly design and start coding. Hours or days later, he'll launch the rewritten site and still no one will use it.

This happens because we're really, really bad at deducing why people don't love a service from just inspecting the website and theorizing in our heads. One of the most important lessons we should learn is to always, always talk to current and potential users to see what they think before making any changes, and then perform controlled experiments measuring what changes work. I am surprised, every time!

This mental mapping makes sense of a lot of issues I've struggled with. I was uncomfortable when Dave McClure recently proposed that you should start off with an AdWords campaign before doing any coding, to figure out what people want. That seemed like a good corrective to founders' tendency to geek out and build without understanding their customer's needs, but taken literally would have ruled out a lot of innovative companies. What would Twitter's landing page and search terms have been?

Thinking about it as profiling cleared up my confusion. Your company has a mission, a reason for existence, an itch you have to scratch. You can run AdWords campaigns to test the best ways of reaching those goals, without letting go of your reason for existence. It's the same as using profiling to guide changes to your program while making sure it still produces the right output.

I think that was always implicit in Dave and Eric's advice (IMVU didn't turn itself into a warez site just because a lot of people were searching for pirated software on Google), but thinking it through helped me realize that measurement doesn't have to kill the passion.

Why I love America

Wavinghi
Photo by Nulla

I recently ran across part of an essay by Henry Farlie, an English-born journalist in America. On previous Independence Days I've tried to articulate why I love America, but he says it so much better than I ever could:

I had been in the country about eight years, and was living in Houston,
when a Texas friend asked me one evening: "Why do you like living in
America? I don't mean why you find it interesting–why you want to
write about it–but why you like living here so much." After only a
moment's reflection, I replied, "It's the first time I've felt free."
One spring day, shortly after my arrival in America, I was walking down
the long, broad street of a suburb, with its sweeping front lawns (all
that space), its tall trees (all that sky), and its clumps of azaleas
(all that color). The only other person on the street was a small boy
on a tricycle. As I passed him, he said, "Hi!"–just like that. No
four-year-old boy had ever addressed me without an introduction before.
Yet here was this one, with his cheerful "Hi!" Recovering from the 
culture shock, I tried to look down stonily at his flaxen head, but
instead, involuntarily, I found myself saying in return: "Well–hi!" He
pedaled off, apparently satisfied. He had begun my Americanization.

"Hi!" As I often say–for Americans do not realize it–the word is a
democracy. (I come from a country where one can tell someone's class by
how they say "Hallo!" or "Hello!" or "Hullo," or whether they say it at
all.) But anyone can say "Hi!" Anyone does. Shortly after my encounter
with the boy, I called on the then Suffragan Bishop of Washington. Did
he greet me as the Archbishop of Canterbury would have done? No. He
said, "Hi, Henry!" I put it down to an aberration, an excess of
Episcopalian latitudinarianism. But what about my first meeting with
Lyndon B. Johnson, the President of the United States, the Emperor of
the Free World, before whom, like a Burgher of Calais, a halter round 
my neck, I would have sunk to my knees, pleading for a loan for my
country? He held out the largest hand in Christendom, and said, "Hi,
Henry!"

Happy 4th of July!

Speed up your PHP with XHProf

Rocketlaunch2

I'll admit it, I'm doing performance-intensive code in PHP. I started my career writing demos in hand-coded assembler, but the need for development speed has pushed me towards using a scripting language. Part of making fast progress is reducing dependencies, which has meant sticking with PHP for the whole system, even for back-end analysis where another language might be more expected.

That's left me desperate to get more information on where the time is going when things slow down. My first weapon of choice is a simple pair of timing functions that I wrap around code to tell how long a whole block is taking. That's quick and easy, (and I've included my code below) but it doesn't give you any information about which parts of it are taking all the time.

For that you need a profiler, and if you do a search for php profiling, almost every result talks about XDebug. Unfortunately, as a profiler, it's a great debugger. You need to edit php.ini and restart the server, or pass in a URL input, you can only profile an entire script rather than just portions, and once you have generated the file you need to transfer them to one of several klunky desktop applications to explore the results.

After abandoning XDebug as too unwieldy, I spent some time searching for other solutions. I finally came across XHProf, and I'm loving it. It was developed as an internal tool for Facebook and open-sourced in March, and you can tell it's been written by people who actually use it. It took a little bit of fiddling to install it, I couldn't get it going through PECL and ended up downloading the source and manually compiling. It was a dream to use after that. It let me trigger the profling programatically around the code I cared about, and then browse the results through a web interface.

There's a couple of caveats, it's missing a few advanced features I'm used to from advanced desktop profilers like detailed information on the full call stack for functions rather than the immediate parents and timing for individual lines of code rather than functions, but in practice it's got all the features I need to diagnose performance problems. I was able to speed up my IMAP email importing dramatically, largely by removing the use of a global variable in an inner loop, it turned out to be far faster to pass the object as a function argument! That's the sort of problem that would have taken me far longer to find without XHProf.

Here's the primitive timing functions I mentioned at the start:

$g_start_time = 0;
$g_end_time = 0;

function pete_start_timer()
{
    global $g_start_time;
    list($usec, $sec) = explode(' ',microtime());
    $g_start_time = ((float)$usec + (float)$sec);
}

function pete_end_timer($dolog=true)
{
    global $g_start_time;
    global $g_end_time;
    list($usec, $sec) = explode(' ',microtime());
    $g_end_time = ((float)$usec + (float)$sec);
    $duration = ($g_end_time – $g_start_time);

    if ($dolog)
    {
        $durationstring = 'pete_timer: %01.4f sec';
        error_log(sprintf($durationstring, $duration));
    }
   
    return $duration;
}

Sewers and startups

Sewer
Photo by Elsie Esq.

I had a chance to chat with Matt Mullenweg yesterday, and he focused on something I've been struggling with; building to last. It also got me thinking about plumbing.

Joseph Bazalgette is one of my engineering heros. He built London's first sewers in the 19th century, and started by estimating how large they'd need to be to cope with the current population. He then said "Well, we're only going to be doing this once and there's always the unforeseen" and doubled the diameter! Thanks to his foresight and the beautiful workmanship of the bricklayers, those same sewers are still serving Londoners today, despite a population many times larger.

The biggest enemy of early-stage startups is time. We can't afford premature scalation, because before we've finished building a system robust enough to handle millions of active users we'll have run out of money. That means we end up accumulating technical debt as we struggle to get customers and revenue with the least possible amount of code.

The danger is we end up succesful, but so deeply mired in technical debt that we spend all our time paying interest rather than making meaningful progress with the product (see the last decade of Windows). As Vernor Vinge evokes so well, there's a good chance some of our code will be in the lower layers of the stack essentially forever. It's a deep engineering sin to inflict shoddy sewers on future generations.

Matt's key insight was "When you're in the red, time is working against you. Once you're profitable, time is on your side". Getting to even Ramen profitability changes everything, and gives you the ability to build for the long term.

When I joined Apple back in 2003, the central build farm for all projects had both PowerPC and x86 Darwin boxes, and our code had to compile on both. Steve was playing a long game, years before the Intel switch he was obviously planning for it, (though I only caught the significance in retrospect).

Looking at WordPress, you can see the same combination of long-term planning sustained by profitability. A lot of focus in the startup world is on exits, but I'll be ecstatic if I'm still helping build Mailana in 20 years time. Seeing Matt's dedication to building something to last gave me hope, especially as he gave practical steps to get there.