Bret Taylor cut his teeth in the workplace at Google. While completing his bachelors and masters degrees at Stanford, he got a job as an intern at the then-fledgling search company, back when the whole company fit into one Mountain View building. And it was there that he co-created Google Maps.
As a follow-up, he founded FriendFeed, which was quickly acquired by Facebook and resulted in him becoming CTO. That in turn led to the overall layout of Facebook shifting into what we know today. Now, Taylor’s building Quip, a company that seeks to supplant Microsoft Office and Google Docs as the hottest productivity tool for the cloud generation. (Taylor is also a member of the board of directors for Twitter.)
Taylor recently appeared at Salesforce’s Dreamforce conference to herald deep integrations into their systems. Thus, a field in a Quip spreadsheet can now be directly linked to information in the Salesforce CRM, making it always up to date. We sat down with Taylor to discuss the work he’s doing at Quip, the transition to Python 3.x, and just how his team managed to build an online/offline collaborative suite of productivity tools.
We spoke in September and you were just beginning the move to Python 3.x at Quip. How did that go?
What would you change if you had to do it over and you could change anything, even within Python?
I think optional typing. With a large engineering team, static analysis becomes really important. Is my change going to negatively impact the build? It’s hard to answer that with a dynamic language. You end up relying a lot on unit tests and integration tests and linters—these tools you strap on.
There have been proposals to add optional types [to Python], and I feel optimistic about that because it’s opt-in. Teams that choose to use them can hopefully benefit from an ecosystem built around static analysis for this feature. It’s hard for the community to consolidate on one [idea] and have a set of tools around it. I am optimistic there will be some version of Python 3 that will create that ecosystem of static analysis tools.
Most of these static analysis tools are focused on C++ and languages that already have static types. In the web industry, dynamic languages are dominant because they’re faster to develop in, they’re more fun to program in, and they’re accessible. The ecosystems around Node.js and Python, as a consequence, collectively as an industry we’ve given up some of the benefits of languages with static typing.
Languages like Go and Rust challenge some of those notions, but I do believe there are ways of introducing some of the benefits of those language tools in a way that doesn’t dilute the core of what makes languages like Python great.
The benefit of those language features go up with your team size. The larger your team, the more you appreciate those static checks. You end up, as you grow, having to graft these development tools onto languages that weren’t designed to support them. I am optimistic about Go and Rust; that can bridge that gap.
How do you measure engineer productivity?
I believe engineering productivity’s main measure is autonomy. How much can a single developer, or a small two- or three-person team make changes without needing permissions or conversations with other teams? There’s no black-and-white answer, but what we optimize for here at Quip is, “Can an individual engineer have the tools at their disposal to make the changes they need?”
That means documentation, to deployment, to automated testing. If you didn’t know the change you made broke anything, that slows you down. We work backward from that as a litmus test of an individual’s autonomy.
What does Quip’s data layer look like?
We have something [like a] pretty typical setup there. We use pretty standard data stores, but store opaque objects inside those stores and don’t use things like joins. It makes it easier to shard. You don’t need to worry about having data collocated to do fancy joins, and it makes it easier to synchronize across clients and servers. These serialized items are copied around.
We have—not exactly [the system used at FriendFeed]—but a system that looks like that shape. We use MySQL, Redis and Memcached, with MySQL being the underlying persistent data store. We use Redis for things that aren’t persistent.
I do think there’s a lot of innovation in data storage. We don’t necessarily want the data storage to be where we innovate. We want it reliable and fast, and it’s easy to horizontally scale. How much weight do you put on the features of our data store? We put very little.
It means it’d be easy to move to a different data store, not that we’re planning to. That was a conscious choice. I do like putting a lot of that logic at the app layer. It makes it easy to do things like have data exist in multiple data centers. We have a model where mobile and desktop apps synchronize with the server and work offline. We have a uniform view of data on the client and server if you have a simple data model.
Other companies have different goals. Notably, our documents are broken up into smaller atomic units. What’s unique about Quip is that if you have four people editing the same spreadsheet, they’re only each touching a small segment of the document. We represented that atomically.
It leads to a lot of efficiency. We have a unique model that looks less like a document, even though it manifests itself as a document. It’s something we consider one of our best architectural decisions, but it was no knock on MongoDB or CouchDB. It was more that we didn’t want to innovate at that layer. Our stack is very simple on the server. It’s very easy for new engineers to understand and use.
Is this something you’d done before, or something you’ve only done at Quip?
It was based on a discussion that we wanted a document editor that supported real-time co-authoring, but also supported offline editing. Those are seemingly contradictory. How do you synchronize online and offline? One of our goals from very early on was to structurally reduce the occurrence of conflicts. We asked, “How do we break our product into as small an atomic unit as possible?” It’s a really unique value proposition, but it’s fairly deeply down in the technology.
As a mobile-first company, how do you deal with Android development?
It’s really complicated. This word has been used to describe Android for a long time: fragmentation. One of the biggest points of fragmentation are the China versions of Android versus the rest of the world. They don’t have Google services in China. It turns out many parts of the Android stack depend on Google services, like push notifications. Not in China. If you want to have it supported in the Chinese app stores, you have to do a different thing for push notifications in China than the rest of the world.
Google has gotten more opinionated with design options in the new versions. Unlike iOS, which has a reliable upgrade cycle, many old Android phones are on the old versions of Android because OEMs decide what flavor those are. On top of that, there’s more device diversity. The fragmentation is really intense. We have a rack of 50 Android phones for testing.
It’s challenging. On the upside, though, it’s really popular and it’s worth the investment. You end up doing analysis on, “Should we support this version or that version?” based on the popularity. There’s stack ranking of development work based on popularity of the devices, and that’s a lot of work. It’s interesting how strong Apple’s developer ecosystem is.
What do your pipelines look like?
I think we’re pretty standard. We have apps for iPhone, iPad, Apple Watch, Android phones and tablets, macOS, Windows, and the web, so that’s eight device classes. Many have shared binaries, but they’re separate interfaces. As a consequence, one of the harder things about deployments is how you do releases across all these platforms on the web. On iOS, we release internally to employees every day, but once a month to the app stores. I do think managing your release schedule and then synchronizing across platforms is a fairly big logistical challenge because of the reviews and policies of app stores. It’s something every startup deals with.
The thing we’ve done with our mobile apps is that they are done on a schedule rather than on demand. That makes the test and deploy process more sane. That’s something a lot of companies did before the Internet. Everyone’s relearned this.
For developers, it must be appealing to have direct access via APIs to the minutiae of end-user productivity tools. How did you build this, and what can be done with these collaborative tools via API?
There are a few levels of integration we think about with APIs. The first is at the data level. All these other systems you use, from Salesforce to your engineering team, have data. If you want that data hooked into your productivity tool, you need an API that can keep all the systems up to date.
You could have it so that every time your data center goes down, it adds an entry to a spreadsheet and a check box to ensure an engineer looked over it. In another use case, you could imagine that as your sales reps are putting in opportunities to Salesforce, I can update a spreadsheet in Quip with forecasts.
It does feel like step one. It’s behind the scenes. It’s all about the real-time data synchronization. I’d like people to extend it in a more visual way, like what Quip does. Something I admired in Salesforce is that their product has always been an extensible platform. They’ve enabled this throughout the product experience.
We can actually do this deep integration so that data is automatically synchronized. I hope that’s step one. I really do think it’s, as you say, the last mile for an end user who just wants to crunch some numbers, or brainstorm, or have a weekly meeting that reflects the actual data. It creates this virtuous cycle: It means people have the incentive to keep the data up to date, and it means you don’t ever have to ask, “Did you update the numbers?”