You’re reading Signal vs. Noise, a publication about the web by 37signals since 1999.

37signals

Signal vs. Noise: Programming

Our Most Recent Posts on Programming

The all-new API for the all-new Basecamp

David wrote this on / 20 comments

We’re finally ready to unveil the API for the new Basecamp. The documentation lives on Github and we encourage developers to help us improve it with pull requests.

The new API covers most of what’s available in the web UI and whatever is currently not there, we’ll be sure to add in the future. You can create projects, add people to those projects, work the calendar, upload files, the works.

We’re really excited to see where people will take the API. Especially the Events API that allows you to poll for changes since a given timestamp. This should make it easy to have local notification style integrations and much easier for people who want to build synching services.

So have at it!


Signal vs. Noise is a founding member of The Deck advertising network

Using event capturing to improve Basecamp page load times

Sam Stephenson wrote this on / 55 comments

We’ve been busy tightening the nuts and bolts on the all-new Basecamp in the wake of last week’s launch. As part of the process, I decided to take a closer look at client-side page load performance. Shaving even a tenth of a second off of page load time can have a big impact on perceived performance, so it’s a worthwhile investment.

Profiling the JavaScript page load event led to a surprising revelation. On pages with many to-dos, an overwhelming majority of the time was spent initializing sortable behavior. The culprit looked something like this:

$.ready(function() {
  $("article.todolist, section.todolists").sortable();
});

In other words, when you’d load any page with to-dos on it, Basecamp would make the items of each to-do list reorderable, then make the whole collection of to-do lists reorderable. That could take up to half a second on heavy pages.

Here’s the thing: you probably aren’t reordering to-dos every time you visit a project. It would be best if we could avoid initializing sortables until the last possible moment, just before you start to drag a to-do.

Deferring Initialization

That got me thinking. What would happen if we tried waiting until the first mouse press before initializing sortables? The mousedown event gets us a lot closer to the intention of reordering than the page load event. I tried it out:

$(document).on("mousedown", ".sortable_handle", function() {
  $("article.todolist, section.todolists").sortable();
});

The new code says that when we receive a mousedown event on the page that comes from somewhere inside a sortable drag handle, we should go ahead and initialize all the sortables on the page.

Sadly, this code doesn’t work. The sortable() initialization installs a mousedown handler of its own, but by that time it is too late. The event has already bubbled its way up to our delegated event handler.

If only there were a way to catch the mousedown event just before it begins its ascent up the DOM

Continued…

How key-based cache expiration works

David wrote this on / 67 comments

There are only two hard things in Computer Science: cache invalidation and naming things — Phil Karlton

Doing cache invalidation by hand is an incredibly frustrating and error-prone process. You’re very likely to forget a spot and let stale data get served. That’s enough to turn most people off russian-doll caching structures, like the one we’re using for Basecamp Next.

Thankfully there’s a better way. A much better way. It’s called key-based cache expiration and it works like this:

Continued…

Find more opportunities on the 37signals Job Board.

How Basecamp Next got to be so damn fast without using much client-side UI

David wrote this on / 116 comments

When we started working on Basecamp Next last year, we had much internal debate about whether we should evolve the existing code base or rewrite it. I’ll dive more into that debate further in a later post, but one of the key arguments for a rewrite was that we wanted a dramatic leap forward in speed — one that wouldn’t be possible through mere evolution.

Speed is one of those core competitive advantages that have long-term staying power. As Jeff Bezos would say, nobody is going to wake up 10 years from now and wish their application was slower. Investments in speed are going to pay dividends forever.

Now for the secret sauce. Basecamp is so blazingly fast for two reasons:

Continued…

Developing for old browsers is (almost) a thing of the past

David wrote this on / 86 comments

It used to be one of the biggest pains of web development. Juggling different browser versions and wasting endless hours coming up with workarounds and hacks. Thankfully, those troubles are now largely optional for many developers of the web.

Chrome ushered in a new era of the always updating browser and it’s been a monumental success. For Basecamp, just over 40% of our users are on Chrome and 97% of them are spread across three very recent versions: 16.0.912.75, 16.0.912.63, and 16.0.912.77. I doubt that many Chrome users even know what version they’re on — they just know that they’re always up to date.

Firefox has followed Chrome into the auto-updating world and only a small slice of users are still sitting on old versions. For Basecamp, a third of our users are on Firefox: 55% on version 9, 25% on version 8. The key trouble area is the 5% still sitting on version 3.6. But if you take 5% of a third, just over 1% of our users are on Firefox 3.6.

Safari is the third biggest browser for Basecamp with a 13% slice and nearly all of them are on some version of 534.x or 533.x. So that’s a pretty easy baseline as well.

Finally we have Internet Explorer: The favorite punching bag of web developers everywhere and for a very good reason. IE represents just 11% of our users on Basecamp, but the split across versions is large and depressing. 9% of our IE users are running IE7a browser that’s more than five years old! 54% are running IE8, which is about three years old. But at least 36% are running a modern browser in IE9.

7% of Basecamp users on undesirables
In summary, we have ~1% of users on an undesirable version of Firefox and about 6% on an undesirable version of IE. So that’s a total of 7% of current Basecamp users on undesirable browser versions that take considerable additional effort to support (effort that then does not go into feature development or other productive areas).

So we’ve decided to raise the browser bar for Basecamp Next and focus only on supporting Chrome 7+, Firefox 4+, Safari 4+, and, most crucially, Internet Explorer 9+. Meaning that the 7% of current Basecamp users who are still on a really old browser will have to upgrade in order to use Basecamp Next.

This is similar to what we did in 2005, when we phased out support for IE5 while it still had a 7% slice of our users. Or as in 2008, when we killed support for IE6 while that browser was enjoing closer to 8% of our users.

We know it’s not always easy to upgrade your browser (or force an upgrade on a client), but we believe it’s necessary to offer the best Basecamp we can possibly make. In addition, we’re not going to move the requirements on Basecamp Classic, so that’ll continue to work for people who are unable to use a modern browser.

Basecamp Next, however, will greet users of old browsers with this:

Basecamp

Basecamp, the world’s #1 project management app, gets better every single day. Have you seen the newest features?


Take a tour to see why others use Basecamp every day.

Code statistics for Basecamp Next

David wrote this on / 77 comments

When I did all the programming for the original version of Basecamp back in 2003, we ended up shipping with just about 2,000 lines of code. A lot has happened in those eight years and we’ve acquired a more delicate taste of just how beautiful we want the basics executed.

This means significantly more code. Here are the stats from running “rake stats” on the Rails project:

On top of that we have just over 5,000 lines of CoffeeScript — almost as much as Ruby! This CoffeeScript compiles to about twice the lines of JavaScript.

Basecamp Next is running Rails 3.2-stable and we’ve got a good splash of client-side MVC in the few areas where that makes sense through Backbone.js and various tailor-made setups.

Got any questions about our stack or code base? Post them in the comments and we’ll fill you in.

Three years later, Mr. Moore is still letting us punt on database sharding

David wrote this on / 30 comments

Three years ago, I wrote about how improvements in technology keep allowing us to punt on sharding the Basecamp database. This is still true, only more so now.

We’ve grown enormously over the last three years but RAM keeps getting cheaper and FusionIO SSD’s keep getting faster. If anything, it seems like recent advances in SSD technology are accelerating and it’s ever more unlikely that we’ll need to shard Basecamp.

Basecamp remains a perfect candidate for sharding. Isolated accounts, no sharing between them. Yet the cost in increased complexity is constant while the cost of throwing hardware at the problem keeps dropping.

It’s like how some old people have a hard time dealing with inflation and “they want how much for a gallon of milk these days?”. Technologists who grew up when RAM cost $1,000 per megabyte can have a hard time dealing with the luxury of RAM being virtually free (we just bought about a terabyte worth of RAM for a Basecamp Next caching system that cost just around $12,000).

The progress of technology is throwing an ever greater number of optimizations into the “premature evil” bucket never to be seen again.

Kicking the tires: My trial month

Nick wrote this on / 28 comments

I saw some questions on David’s last posts about remote work and hiring asking how we evaluate potential employees. Racing metaphors aside, tossing new developers on real projects is a time honored tradition here, and one that we haven’t written yet about “what” exactly happens along with the “why”. Here’s how my trial month went, and what I learned.

Giordano's pizza and a pint of 312, can't get more Chicago than this meal.

The first week

I’ve never been to Chicago, outside of O’Hare airport. I have terrifying memories of that airport, so I was cautious to visit. I once left an a320 Pocket Retro Emulator in a seat pocket while deboarding, and didn’t realize it until soon before my connection was to leave. I sprinted back through 2 terminals to find the plane had already left for Nashville. I hope someone else is enjoying a slightly buggy version of Tetris Attack. My first week at 37signals went much better than this experience.

The first week in the office was great. Getting up to speed was a breeze: I fired Ruby and Rails up on a fresh box with rbenv and ruby-build. After cloning down a few repositories, and the usual run-around of “what passwords/sites do I need access to”, I was tossed into the fray of our support queue.

I was introduced to Assistly, which we use for customer support. I have to say, our support team is awesome to work with. We typically have 3 developers rotating in on-call, usually on a weekly or so basis. Here’s basically what on-call for a 37signals developer looks like:

  1. Support is stuck with an issue, and our set of internal tools isn’t helping.
  2. An issue is called out for developers to look at.
  3. Cue hacking montage as we dive into that specific product and various gems’ codebase to find the problem. This usually involves a trip into our server cluster to look for logs, find emails that didn’t process or hook up to a Rails console and hit the database.
  4. If it’s a bug, try to squash it. At least make sure we know about it in GitHub Issues.
  5. Ship it! Bug fixes and more are logged through Champagne, our internal change tracking tool. Champagne is in charge of publishing our Changes page.

Sometimes there’s not always an easy fix, or it’s a deeper issue. Typically we’ll discuss these over in Campfire to begin and see if anyone’s seen it before. This usually escalates into kicking off or contribute to ongoing discussion in Basecamp about how to solve the root problem.

Back to remote

On my first week back in Buffalo, I was tasked with creating a fresh application we’ve needed for a while. The workflow for discussing changes and features was pretty much what I expected: Here’s a list of things to accomplish, let’s see what we can get done in a week. The timeboxed aspect of the project was definitely new to me, and I think it was a great factor in focusing on what needed to get done instead of what could be done. I’m very new to a product-focused company, and this was a great way to be dropped into the environment where it’s really the customer and user experience that comes first and foremost.

After that second week remote, I went back to on-call. I really enjoy the balance of the on-call work. It’s usually split 50/50 between helping customers with issues blocking their work, and improving our infrastructure and apps. There’s lots of dirt to sweep up, including deep bugs that need investigating and apps/gems that need a fresh coat of Ruby or Rails.

Back in Buffalo, this is Bidwell Parkway.

Top score!

One thing I learned really quickly was that our users are creative: If you give them the ability to do anything, they will do everything! I found this out the hard way when we got a support issue for an extremely broken Basecamp page. After some investigation, I found out that Basecamp todos allow HTML tags, and they forgot to close one. After a fruitless hunt for why this behavior existed, I shipped a fix to strip out HTML tags and clean up ones that might cause the page to break.

The flood of support issues started almost immediately. Apparently a lot of users customize their todos with colors, images, and more. Suddenly, they couldn’t, and it was my fault. This might be a new personal top score for breaking things at a new job. I reverted the fix and deployed once again, and we apologized to those users.

Keep kickin’

I’m still getting used to remote work, but I’m enjoying the greater freedom and flexibility so far. The discipline of working near so many distractions is something I’ll be working on for a while.

This is my second official month being a signal, and I’m definitely still learning about our infrastructure and the internals of our products. I have to say though, it’s been a lot of fun and I’m excited for what’s next. If you have any other questions about the trial month experience let me know!

Why we don't hire programmers based on puzzles, API quizzes, math riddles, or other parlor tricks

David wrote this on / 174 comments

I remember the first time I interviewed for a front-end programming position and got asked how to do something in JavaScript on a white board. The specifics are vague, but it’s crystal clear how stupid it made me feel and how little it had to do with the actual job.

Since then I’ve rarely heard a kind word about the parlor tricks of programmer hiring, but I’ve heard plenty of scorn. There’s certainly a minority of puzzle solvers who love to get their fancy tickled like this, but I sure wasn’t one of them and neither have most programmers I’ve met.

I’ve known fabulous programmers flame out in the quizzing cage and terrible ones excel. So unless you’re specifically hiring someone to design you the next sorting algorithm, making them do so on the white board is a poor gauge of future success.

The only reliable gauge I’ve found for future programmer success is looking at real code they’ve written, talking through bigger picture issues, and, if all that is swell, trying them out for size.

(If you need help posting a comment, feel free to use any of these samples: “You make todo lists, you don’t need real software engineers”, “Math is actually really important, you know!”, “Google is worth one gajillion dollars and they use quizzes, so there!”)

Top-tier this

David wrote this on / 96 comments

If I hear one more Silicon Valley type gush over a computer science graduate from CMU, MIT, or Stanford, I’m going to puke. Yes, yes, I’m sure these are mighty dandy nice schools, but you’re letting the stench of superiority and shallow whiff of superficial judgement pollute my airways.

The fantastic thing about programmers is that we don’t have to give a fuck about where they were trained because we have something much better available: We can look at what they actually do! We don’t need the indirection of pedigree to guess at their skills, we can look at their code and know it.

Here’s a list of the top tier schools that helped shape the fine band of programmers we employ at 37signals:

  • Lawrence University
  • Rochester Institute of Technology
  • Brock University
  • Washtenaw Community College
  • California Institute of Technology
  • Copenhagen Business School
  • Brigham Young University