Category Archives: Projects

Microservices and websites

You build a startup quickly, scale the tech as far as it goes. You’ve got one codebase, and one scary-as-hell deploy. You’re known for failure at least as well as you’re known for your product.

So you break up your service into microservices. Each can be deployed independently. Each can be owned by a team who understands the whole of the thing, and so the changes therein. Responsibility and accountability are delegated to those teams.

It’s a proven pattern. And very successful.

At Twitter, we run dozens of microservices. We have macaw-users, serving the user information apis. We have macaw-tweets, serving tweets. We have macaw-timelines, serving timelines. It all makes a lot of sense. The tweets service can roll out a deploy, observe issues with their endpoints, roll back and fix – all without bothering the other services.

This is an ideal way to scale an api.

Your mobile apps can use this api. Maybe with JSON, or something more efficient. If an endpoint fails now, a single team is paged and the service recovers. Users might see a momentary error with some actions. The mobile app teams needn’t even know; they worry about their own code deploys, not the reliability of their apis. 

A website is a different animal. One web page is the combined output from many of your apis, many of those services. And for speed of delivery, you are rendering those web pages on the server.

For server-side rendered web pages, the output of your apis is combined inside your own datacenters. This is happening on your own servers. 

The microservice model starts to fail. If a service you depend upon is experiencing issues, your web pages are seeing that issue and throwing error pages themselves. Your service may fall below SLA before theirs does. Suddenly, you’re a single point of failure, and so primary oncall for all microservices. Farewell sleep. 

It gets worse. Since your service is inside the DC, you use a more efficient api layer with compile-time dependencies. When you compile your project, you need to build every other service. Of course your build system has caching, but what does that matter when every backend change forces a recompile on you?

It gets worse. The other services start to focus on mobile. They build business logic into the json formatter. It’s not as crazy as it sounds – of course they use shared objects for json. And checks at the edge are the simplest. But now you’re missing them on web. And, oh, resources are tight. Build it yourself or miss out.

It gets worse. Your integration test suite needs fixture data in code. But the mobile clients just depend on manual QA and json fixtures. Effective integration testing falls away, and deploys gets even more scary.

Development grinds to a halt. 

This is where we were. Let me tell you where we went, how we made things better. 

We shipped a PWA. A progressive web app. The app is entirely rendered in JavaScript in the browser. We use the same apis as the mobile clients. We’re a mobile client. 

We can write just one language: JavaScript.

We can write, deploy, test and be oncall for our own app, and stop worrying about others. 

We can use the new api formats and features as soon as they’re ready.

We did it. 

Or did we?

Another route we could have taken is to rethink this from the perspective of the user. To the user it doesn’t matter whether an api call failed in the client or the server. A failure is catchable and can be well handled. We had an SLA on the server because we could easily measure it. Should that be different on the client where we can’t? There’s no doubt in my mind that our service could have been coded more defensively, mitigating the vast majority of pages and alerts. 

So why did we not?

Partly because our service isn’t built on a robust web framework. It’s a migration of our ruby-on-rails system to Scala. This was necessary for the complexity of a migration while operating at scale. The framework is optimised towards api development, which again makes sense, as most services are apis. It’s logical that our graphs, monitoring and alerts are also configured this way. APIs are not websites.

What’s more, it’s because websites are built with static assets (JavaScript, CSS) that don’t split well against service-based concerns. So our website could not be fragmented into micro web services without some mismatch in the asset versions delivered by the various services as they deploy.

And finally it’s because web engineers have a tricky enough job writing good quality modular scalable robust crossbrowser user experiences. We should be allowed our focus and not have to worry about the intricacies of server code in a foreign language.

Try hiring a CSS developer with Scala skills. I’m sure Google has some. Good luck. 

So we went PWA and we’re not going back. Was it necessary? Maybe, maybe not. Was it worth it? Hell yes.

I shall sleep well tonight.


The first time my mother-in-law came to stay with us, she was sleeping on the floor.

It was awful. Not just on the floor, but on the living room floor. We were living in a small one-bedroom flat in San Francisco, we hadn’t been there long, and the move had cost us most of our meagre savings. She’d lie there and watch me eat dinner.

It’s hard to move away from your family. San Francisco is about six thousand miles from my home. I have all kinds of family back home: parents, brothers, aunts, uncles, cousins. My wife has far fewer. I don’t know if that makes it easier for her, or harder. Anyway, we don’t see people often. It’s a little sad.

Kids just make the problem worse. We can’t just nip home for the holidays now. We need four plane tickets. We need car seats, luggage, and a week to cope with jet lag. Tantrums are frequent. Vomit is inevitable.

We’ve been home three times. Three times in eight years.

Luckily, we get visitors far more often. My brothers have been really good about visiting. My parents too. And of course, my mother-in-law.

The thing is, nobody is going to visit just for dinner. Nobody flies six thousand miles to just watch the kids while I pop out for a beer help yourself to whatever’s in the fridge thanks love. No.

They need to stay for a few weeks. Just to make it worthwhile. And a few weeks in a hotel is kind of pricey. Even in an AirBnB. It’s more than the cost of the flight.

So she’s lying on the floor, watching me eat my dinner. For weeks.

It’s not just that. You see, I’m pretty sure she’s a vampire.

No, really.

It’s not just that she calls people “darlingk”. She once went to a playground and announced, in her thick Polish accent, “Look at aall the lovvely cheeldren!”, and I swear she licked her lips. She never seems to eat anything but ice cream, which suggests that food isn’t her main source of nutrition. She’s at least a thousand years old. She never seems to sleep. And when she goes outside in the daytime her eyes glow red and she begins to disintegrate.

Ok, I made that last one up.

It’s really intense having family over to stay for a long period. It’s also really intense going to stay with them. You go from the occasional monthly phone call with nothing to say, to good morning good afternoon good evening good night. IN YOUR FACE, TWENTY FOUR SEVEN. Ugh, it’s unbearable.

I even get frustrated with my mum, and she’s the nicest and least offensive person on the planet.

Anyway so we got this new place with a granny flat. We didn’t mean to. It’s just a place that had a beautiful backyard. And the granny flat became a playroom for the kids, and an office for dad (me), and yes we realise those two concepts don’t colocate brilliantly, but our schedules mostly don’t match and it’s fine.

But for this past visit, we’ve made it a granny flat. It’s granny’s flat. Sometimes (ok, every day) we send the kids up there to play with granny in her playroom. I set her up a sofa and television. It’s like she’s living next door, it’s not like she’s IN MY FACE, watching me eat. She visits us every day too.

And it’s been brilliant. She’s been brilliant. She can come to stay any time.

(Not any time of course, visas don’t actually work that way, which is either a shame or probably a good thing, because you don’t want to push it do you?)

Any time though. Welcome, Granny.

The last great-grandparent

When Jack was born, he had five great-grandparents. That’s five more than I had. But by the time Max was born, only one was still with us. And now, he too has passed away.

Hamish was probably my favourite. He was a sailor, a conscientious objector, a dancer and a fool.

He taught me to sail, a beautiful little sailboat called Sally Brown on the river Deben. By the time he passed it onto us, it was probably the only sailboat without an engine left on the river.

He was teetotal, and wouldn’t even enter the pub.

He didn’t fight in the war, and suffered for it. I would love to have learned more about this time and this choice. The most I heard was “why should I go and kill some foreign johnny I don’t have any disagreement with?” He worked as a manual labourer. He reckoned he could carry a ton of grain.

He did ten long-arm pull-ups each morning until his doctor told him that wasn’t normal for a 75 year old, and that he should probably stop.

He was a fool, a dancer dressed in scraps of many colours in a Morris dancing troupe. I never saw him fool, but I’ve seen a tape. As a tall man, he gave it dignity.

He was the second cousin of Hugh Laurie.

He was a printer, producing flyers and cards on his cast iron manual printing press hidden in his garage. Granny would draw the pictures and cut the lino.

They were married for more than 60years.

As I remember him, he was retired with Granny in Waldringfield, where we keep the boats. They didn’t have a television. They didn’t eat out. They lived by the wind and tide, the Archers, their friends, and that story Hamish would tell about eating turkey stock instead of apple sauce in his porridge.

I miss summers on the boats. The boats are all still there, even little Percy, but we’ve moved away.


Ok, it’s the end of the year. I’ve got a cold. I hate having colds – they attack me particularly badly, and I get all gross and covered in tissues and snot, and all I want to do is sit around and eat ice-cream and… Hang on. … Ok. Ice cream. Better.

So, 2016. One of those years when lots of things happen. We started the year in London. I spent a couple of days back at my old university in Warwick on a management course. I came back to work all charged up and ready to fix everything. Didn’t manage to fix everything of course. Some things are more complicated than that. But we made progress.

In happy news, the brewery opened and Randy is successfully producing excellent beers. It makes me very happy to have invested in a real tangible company, making high quality product. The brewery has become my local establishment, for my rare evenings off.

We had another baby! We make very good babies. This proves that the first was not a fluke. They are not easy to make or maintain, but are a great investment.

One thing Twitter did this year was change their leave policy. Now, both parents can take 20 weeks paid leave in the first year. That’s been absolutely incredible. Not only has it helped maintain my wife’s sanity through the early months, it has helped my five-year-old feel like he’s not been usurped. This time is probably the most time I will ever have with my family. It has been amazing, and I’m very thankful to Twitter for their support. In November, I clocked 6 years with them. Best place I’ve ever worked.

Britain voted to leave Europe. That was something of a surprise, but also kindof understandable. It doesn’t mean the country is full of racists, it just means the politicians have failed to connect with the electorate. Most Brits don’t vote for their European representative (MEP), nor have any idea who they are or what they do. When votes became inconvenient (see Lisbon treaty), the politicians simply avoided them. It is no surprise to me that voters felt disenfranchised. I hope they figure something out that works better.

America voted to elect Trump. That was something of a surprise. It doesn’t mean the country is full of racists, it just means these politicians have failed to connect with the electorate too. There’s an anti-establishment vibe. I’m not as pessimistic about this one as other people are, because a) I felt the way you feel now about Bush winning in 2004 and the world didn’t end then (ok, hundreds of thousands of people died, but the world didn’t end); and b) I don’t think Trump (whose opinions are unknown and variable) is as bad as many republicans (whose opinions are known and repugnant). We literally have no idea how this will go.

I talk about this stuff occasionally on Twitter or this blog and never really make my positions clear. I’m happy to correct bullshit from either side (tbh lies about Trump are as annoying as lies about Clinton), and maybe that causes confusion, so here are my stances: Democrat(US)/Labour(UK) but not as far as the communist hippy crowd. I believe in universal healthcare, but I’m not opinionated about implementation. I support LGBTQ rights. I support diversity in all its forms, and acknowledge that I need to do more. I want more women in tech. I’m against bullying, online and offline. I think immigration is a complex issue without simple solutions, but I think employers looking for H1Bs should be required to provide US scholarships. I support public transport, but I love my truck too. I believe there are no gods. I’m pro-choice in the first two trimesters. I prefer Chrome to Safari, but I’m not entirely sure why. I’m enjoying craft beers, and bored with wine. I like vegetables, because they’re what my food eats. I think Snowden should be exonerated, and I think Manning should only be released due to mistreatment before trial. I think gun control is a good idea when the laws make sense. I don’t understand term limits for the presidency, because hey, why not choose the best person for the job?

Ok, I think that’s enough.

Oh, we bought a house. I love it. It’s old and knobbly and makes no sense, just like us. It’s perfect. We have deer and turkeys and squirrels and trees and grass.

We went to Tahoe for Christmas. The drive was terrible and we all got the flu. So, yeah, Merry Christmas.

I ran a half-marathon! But I hadn’t done any training at all, and it pissed it down all the way, and there was a big hill so I had to walk a bit, well a lot really. It wasn’t much fun.

I have been going to the gym a bit. Hopefully I’ll keep this going into the new year as I go back to work. It’s been good to stretch out.

Last year I got wisdom teeth done. This year, gum grafts. They’re really not fun. They tear a strip of gum off the top of your mouth and stitch it onto your teeth. Bleah. And there will be more of that to look forward to next year.

I watched the entirety of Friends. I’m not sure if this is a worthy accomplishment, but when you’re feeding the baby for 30mins every 2 or 3 hours, you need something to watch. I also developed a thrombotic hemorrhoid by sitting on my arse all day, which was not fun.

And I think that’s the year.

Next year, get back to work. Do something awesome.

2015: This year I have …

Every year I scribble down a list of things I’ve done in the past 12 months.See previous years: 2014, 2013, 2012, 2011, 2010, 2009 and 2008.

This year, I ran a marathon (kind of – there was a lot of walking involved), we holidayed in Hawaii (twice) at the Disney Aulani, we flew home for the first London family Christmas since 2009, and we met my new niece.

At work, I’ve been really busy, with between 15 and 30 reports. We made some really strong hires, shipped some great new code and features, and finally killed the monorail. We had some tough times too, from which I’ve learned a lot.

As an effort to be a better manager, I’ve kicked off an MBA which I seriously don’t have time for. It’s interesting to learn, but painful to find time for the coursework. I’m a terrible student. Especially at essays.

I had three wisdom teeth removed this year, which wasn’t fun at all. And in combination with a slight overdose of painkillers and a perforated sinus, I had a bad time. On the plus side though, I got really thin for a couple of months. I’m still syringing food out of my empty socket, which is exactly as gross as it sounds.

I really enjoyed being Daddy to a three year old full of energy. It’s been The Most Fun. I heartily recommend it.

I finally went to JSConf this year. It was an outstanding conference. Huge thanks to Chris and family. Sadly, it seems this year was the last – but hopefully they revive it someday.

Last year I said I’d get a cat. I failed. Partly because Amazon doesn’t deliver pets, and I don’t know any other way to buy things. Maybe next year. My wife wants a dog, which I’m really not sure about. Dogs are nasty. We’ll see.

This year I’ve been drinking more craft beers and really enjoying it. I’ve spent an enjoyable few nights sampling flavours in Øl, our local specialist beer shop. And I’ve invested the boy’s college fund in a local brewery. Should be fun to explain that to him in a few years.

Next year, I’m really excited about getting a VR kit at home. I daresay I won’t use it a lot (like my dusty Apple Watch), but it’ll be fun to play with.

Maybe we’ll buy a house. Get that (shudder) dog.

And I’d like to be fitter. More than anything, I’d like to be thin, fit and healthy by the end of 2016. Time to dig out that gym card.

Age three

Three years of age is a fantastic time. You’re putting sentences together yourself, expressing your own feelings, and beginning to understand feelings of others. Here are some of our favourite phrases:

  • Excu Mees
  • Thanks you
  • Bye bye daddy, have a great sooon!
  • Enough talking to me daddy!
  • You don’t say things to me!
  • I missed you daddy.
  • Every day for six months: “What are you going to dream about?” Agiday! (MyGym day)
  • Six months: “What are you going to dream about?” The city! (Peekadoodle)
  • Three months: I’m going to dream about Katie and the city!
  • Now: I’m going to dream about mummy and playing and YOU!

Flight Mixins

We started building Flight.js at Twitter back in 2011. The brainchild of Dan Webb, it’s a component-based framework based on his previous frameworks polished with what we’d learned from working with Twitter’s existing codebase. One feature of the framework we wanted to include from the outset was Angus Croll‘s mixin model. His blog post on the subject is beautifully readable, and he’s also given a presentation on Flight’s mixin model at BrazilJS. It’s well worth reading both the blog and slide deck now, if you haven’t already.

Two and a half years later, with the whole of now running on Flight, how do we feel about Flight and mixins? Are they working for us?

Rather than using the classical talking animals to describe our components, I’ll try to use real-life twitter components, though I’ll be dramatically simplifying for readability.

module.exports = defineComponent(customTimeline,
function customTimeline() {
    itemType: 'tweet'

Here’s an example of the code running our new Custom Timelines. As you can see, all the functionality is provided by our mixins. The code for our timeline is powerful, using delegated event handlers to pick up and handle most of the events sourced by the tweets themselves.


We’ve always described mixins as “specialisations”. The idea is that you’d write a module, and then extend it with extra functionality.

For example,

module.exports = defineComponent(newTimeline);

We could then add functionality like infinite scroll:

module.exports = defineComponent(newTimeline,

But if we break apart this model a little further, then things get complicated. The mixin is able to wrap and override code in our newTimeline model.

function newTimeline() {
  this.updateTimeline = function() {
    // something
function withInfiniteScroll() {
  this.around('updateTimeline', function(originalFunc) {
    // something

However, this doesn’t really make sense. If we follow this model, then we need to define the core methods of timeline in every single component that wants to use withInfiniteScroll. We also have no way to extend or override the behaviour of the mixin without using another mixin on top.

A far better model would be this:

module.exports = defineComponent(withInfiniteScroll,

Putting the mixins at the start of the component definition will allow us to override any behaviour we want. This is much more like mixins used by other languages (Ruby or Scala used here at Twitter, for example).

If we apply this new model back to our original component code, we get this:

module.exports = defineComponent(withBaseTimeline,

This is a simple change, but gives far more power to the customTimeline. Flight gives us this flexibility because it treats all the arguments to defineComponent as mixins. If you’re using Flight.js in the wild, I would strongly recommend making this change.


One thing that’s very clear from our Custom Timeline example is that our mixins have become reasonably verbose. If we wanted to create another similar Timeline component, we’d have to duplicate that whole definition.

module.exports = defineComponent(withBaseTimeline,
function newTimeline() {
    itemType: 'tweet'

Something we’ve done in a few cases is create mixin collections:

var compose = require('flight/lib/compose');
module.exports = customTimelineMixins;
function customTimelineMixins() {
  compose.mixin(this, [

This will work, but I dislike having to reach into the framework and apply the mixins myself. This is also taking us back to the idea of inheritance:

module.exports = defineComponent(customTimelineMixins,
module.exports = defineComponent(customTimelineMixins,

Ultimately, I think there is some value in this combination of mixins and inheritance. In wider discussions with the team at Twitter, we took this further. Ideally, we’d like to be able to treat a defined component just as another mixin.

module.exports = defineComponent(customTimelineComponent,

This isn’t possible in the framework today, but conceptually there’s no reason why we couldn’t treat every component as a collection of mixins, and defer the creation of the component itself until it is actually used for instantiation and attachment. I’m hoping something like this will make Flight v2.


One of the huge benefits of Flight is the enforcement of modularity. Each component is written and tested as a unit, and the only communication layer is through events.

However, large components are more complex to test, and when there are lots of mixins, it can be really hard to trace through the code, especially when advice is used liberally.

If you’ve got a lot of mixins, as we clearly do for our timelines, then you might be better breaking the component apart, into multiple components.

Our current timeline component is attached like this:

CustomTimeline('#timeline', options);

But there’s no reason why we couldn’t have done something like this:

CustomTimeline.attachTo('#timeline', options);
TimelinePagination.attachTo('#timeline', options);
TimestampUpdating.attachTo('#timeline', options);
TimelineActions.attachTo('#timeline', options);

Of course, we could attach those components within CustomTimeline:

function customTimelineMixins() {
  this.before('teardown', function() {
  this.after('initialise', function() {
    TimelinePagination.attachTo(this.$node, options);
    TimestampUpdating.attachTo(this.$node, options);
    TimelineActions.attachTo(this.$node, options);

However, as you can see, we have to be clever about handling our own teardowns here, which may not be worth the hassle.


If you’ve used mixins at all, you’ve likely encountered the default attribute conflict. If an attribute in declared in a mixin, it cannot be redeclared in your component, or even in another mixin. Our aim was to prevent unintentional ‘clobbering’ of methods and properties, where two mixins use the same property for different purposes, producing unexpected and hard-to-debug conflicts.

However, I’ve often wanted to avoid this guard, to give more specific default attributes for my mixins in my component definition. To do so, we can define a new method, “overrideDefaultAttrs”:

this.overrideDefaultAttrs = function(defaults) {
  utils.push(this.defaults, defaults, false) || (this.defaults = defaults);

This will behave exactly the same as the defaultAttrs method, but will pass “false” to utils.push, which will allow us to overwrite the attributes when conflicts arise.

It’s tempting to redefine defaultAttrs itself, but I think it’s better not to redefine the framework for future compatibility, and the guard may prove useful in other places. The method is also blocked from redefinition when being mixed in.

To add the method above, one could either add it to the global component base (be sure to do so before any components are defined):

define(['./base', './utils'], function(base, utils) {
  this.overrideDefaultAttrs = function(defaults) {
    utils.push(this.defaults, defaults, false) || (this.defaults = defaults);

Or simply create a mixin to be applied to each component as you need it.

We haven’t yet tried this in-house, but I think it would solve some readability and precedence issues.


Mixins have proved to be a vital part of Flight and Key learnings:

  • move your mixins to the start of the component definition
  • consider using overrideDefaultAttrs in component definitions
  • only use mixins where appropriate; use different components if you can
  • keep an eye on Flight for new features

2013: This year I have …

My annual End of Year update. See previous years: 2012201120102009 and 2008.

This year, we survived.

Yes, I know I said that last year. But it’s also how we feel. Exhausted.

Things are getting better. Our son is growing, learning new words every day. We might not have the sleeping situation sorted, but it’s still a fantastic feeling to have a family.

This year, we have also: bought a new car (my first new car), been to England for three weeks to see friends and family, been to Poland to see grandparents, moved out of San Francisco to a proper house in Walnut Creek with a garden, and endured the subsequent hundred-degree heat of the summer and the shivering freeze of winter.

At work, we’ve IPO’ed. Achievement unlocked. I’ve also switched from being a day-to-day coder to being an Engineering Manager, responsible for my team of six and, the website. I’m still coding too. Well, deleting code. This year I deleted #NewTwitter.

We also got our Green Cards this year, so we can stay as long as we need.

At New Year’s, people make all sorts of resolutions and then fail to achieve them. This year, I’m going to take it easy on myself by listing antiresolutions. These are things that I would like to do, but not this year.

  • Run another marathon.
  • Do more programming after work.
  • Write a book.
  • Learn to play the piano. (long-standing antiresolution)
  • Buy another car.
  • Fly to England for a holiday.
  • Learn Polish.
  • Study for another degree.
  • Move house.

Wow, that feels better. What aren’t you doing this year?

Waiting for Bill

I throw another log onto the fire. I’m not sure we really need it – it’ll be warm enough all night long. Out here in Palm Springs, it’s only bearable when the sun sets anyway. The fire simply gives us something to watch while we wait.

Bill Gates is due for dinner. Most of the other guests have already arrived, so he should be next. Or the one after.

I poke the fire. Sparks fly. It’s been a few good hours now, and I still haven’t decided.

Do I shake his hand, or kick him in the fork?

This was about ten years ago. I’d never suggest or condone violence in any form these days. Hell, even then I wouldn’t really. So let’s moderate the language.

Do I shake his hand heartily, welcome him like an old friend, thank him for all he’s done for my career, and propose my next big idea? Or do I ignore him, snub him, turn the other cheek?

I should clarify my position. I don’t have dinner with billionaires. That doesn’t happen. I’m really not that kind of guy.

I’m here on holiday. Vacation, if you will. I’m visiting an old friend from London, who is originally from Perth, who is currently working as a hot air balloon pilot in Palm Desert. And in the evenings, he works as a parking valet at The Reserve, an exclusive golf club in Palm Springs. And, since I’ve got nothing else to do, I’m here to help.

I say “parking valet” to emphasise that I’m using the American meaning of “valet”. Someone who parks your car. Not the English meaning, which you might be familiar with from Downton Abbey, of someone who dresses you in the morning.

To make this slightly more bizarre, I can’t actually drive. No license. Never even sat behind the wheel. I’m opening the car door, welcoming them, opening the restaurant door, that kind of thing. Oh, and I get to drive the golf cart, ferrying my fellow valets back from the car park. This is a nice place – you expect your valet to be fast. This is a classy place – even the valets have a little nook with a fireplace.

When I arrived, they told me Bill Gates was booked for dinner. Yes, that Bill Gates. That one.

Obviously I was somewhat in awe. He was, I believe, the richest man in the world at the time. And I’d been working with his software for years. My job, my life, was founded upon it.

And yet, that brought so much trauma. I was out here for a much-needed break. I’d been fighting poorly implemented APIs, buggy applications, incomprehensible error codes, absent or irrelevant documentation, and that blasted comedy paperclip. In no small way did I hate this software as much as I loved it. I should snub this man for all the suffering he put me through.

But what a wasted opportunity. I should be pitching an idea. I’ve got maybe 20 seconds with the most powerful man in technology. I’ve got to plant a thought in his head, one that will distract him over dinner, so that he’ll emerge with a warm smile and an offer of partnership.

All I needed now was the idea.

Ideas are funny things. After a few pints, or several sleepless hours, your mind is full of amazing, wonderful, life-changing, world-changing, revolutionary ideas. When you’re put on the spot, nothing.

Fast forward to the future, and hindsight brings the answers. I could’ve pitched Twitter. Facebook. Myspace. The cloud. Groupon. Well, maybe not Groupon. Instagram. The iPhone. I could’ve begged him to continue development of IE.

If you were put on the spot, right here, right now – could you pitch? What’s your idea? Are you ready?

I wasn’t ready, but that was ok. Bill never showed up.

The other guys were fine with it. Apparently he’s not a big tipper.

Since then of course, he’s donated most of his wealth to charity. Seems like a generous tip to me. I’d heartily shake his hand. Or fist bump. Or whatever he’d prefer.

And he tweets. I build the software he uses every day. That’s pretty awesome.

Maybe it’s a good thing he didn’t show.


I’m English.

England is vast. Despite holding about fifty million people, most of the land is still dedicated to farming, and enjoys large exports to the rest of the world.

We complain about the variable weather that always comes with island life, but it gives us acres of fertile soils. From the air, the land looks terraformed: neat rectangles of colour.

Fifty million people is also a huge populace, mostly living in cities. The cities are vast and sprawling, with thousands of years of history behind them. Your local church can be a thousand years old as easily as a hundred. You can travel from town to town, city to city, with barely a break in housing.

An hour’s drive is a good trip. In ten hours, you can cross the country, even the long way. Rail travel is good, expensive and sometimes unreliable, but generally good. Motorway travel is excellent. Speeds are fast, accidents are infrequent.

Wherever you travel, you are surrounded by people. At most, you could be half an hour from people, a few miles from people.

I live in America.

American cities feel like English cities. There’s that mix of all-comers, the blend of cultures thrown together. Buildings, housing, stacked closely together. People rubbing shoulders on the bus.

Further out, to the suburbs, there is still very little difference. The houses are generally a little bigger. They’re less likely to fit the upstairs/downstairs template of English life. They’ll have proper garages. They’re made of wood. The urban sprawl surrounds the cities, giving families some breathing space and distance from the bustling city nightlife.

Further out still, there is more difference.

Because America is absolutely, staggeringly, incomprehensibly, mindbendingly vast.

Looking out of the window at the Rockies as you travel here, you can see the breathtaking landscape still raw and scarred, like the surface of Mars. It’s enormous, it’s beautiful, and it’s empty.

Travelling from city to city, it’s easy to forget this. Close the window, close your eyes, and move seamlessly from one identikit airport to the next.

But out there, people live. They live off the land, they live different lives. Farm fields roll over the horizon, without limit. Farmers have planes.

How far can you be from other people? How far can you be from help? How far from the nearest mobile phone tower?

If your family lives on a farm, miles from anywhere, how can you feel safe? Who will be the next person to drive by? If trouble came knocking, how long before anyone came to ask if you are ok?

England has a wonderful position of security.

America is different.

I don’t support the gun lobby. I believe that fewer guns mean fewer deaths. But I’m disappointed in polarity of argument, and the lack of imagination in recent commentary. One should try to see both sides of the picture to find where to draw the line.

I’m not making a point one way or the other. I’m saying: think.
Use your imagination.