Hi! I'm Chris, the CTO and co-founder of Grove Collaborative. Over the years I've written a number of articles about software, technology, and teams.



Adventures in Candy Land

I play Candy Land occasionally with my two boys (the six year old gets it much more than the three year old). It has the strange property of involving both zero skill and zero agency. There are absolutely no decisions for the player to make at any point; the outcome …


Explorations in The Card Game SET®

SET is a classic pattern-matching card game that's been around since the 1970s, but really took off in the 90s. It hits all the right marks for a great game casual game; easy to learn, works for any number of players, you can play for 5 minutes or for hours …


A Simple Trending Products Recommendation Engine in Python

Our product recommendations were boring. I knew that because our customers told us. When surveyed, the #1 thing they wanted from us was better product discovery. And looking at the analytics data, I could see customers clicking through page after page of recommendations, looking for something new to buy. We …


How to Buy Expensive Software Part 1: Vendors & Demos

Some days it seems like all I'm good for is buying other companies' software.

It's a little ridiculous. I get 5-10 emails a day pitching some SaaS solution. You probably get them too. Recognize any of these subject lines?

  • Christopher, do you have 15 minutes to connect about my previous …


Photography & Journalism with Darcy Padilla & Julian Cox - Opening Remarks

On November 17th, I chaired an event at the de Young Museum related to the opening of the exhibit Danny Lyon: Message to the Future. It's there through April 30th, 2017 and I encourage anyone in San Francisco during its run to see it. Danny Lyon is a remarkable photographer …


Actually Understanding Timezones in PostgreSQL

Timezones are the worst. We should all just live in UTC, reasonable sunset hours be damned. And learning about timezone implementation details is incredibly boring and esoteric1, so most developers are not inclined to figure out what the hell is actually going on until they really need to. Like …


Eight Surprises During My First Year as a Father

I have a 13-month-old son named Dashiell (pronounced Dash-uhl, and I'm sorry in advance to schoolage Dashiell, whose teachers will all say "Dah-sheel?" on his first day). He's awesome. I mean...I'm not super objective, but even so, he's definitely a good dude. We're going to keep him.

Most of …


Zero Downtime Rebrand

Noah Smith and I gave this presentation at the San Francisco Django meetup in March of 2016, shortly after we rebranded ePantry to Grove Collaborative. Here's how we pulled it off.

first-screen Welcome folks!

first-screen That's us

first-screen We rebranded on March 8, 2016. Grove is an aspiration brand that speaks to our …


The First Thing I Tell New Engineers

The first thing I tell junior programmers is: keep going.

If you've been programming a while, you know that feeling of encountering a new project, with a new stack, in a new language. The feeling is: OK. And you roll up your sleeves and get to work.

But do you …


Software at Companies that Don't Sell Software

If you're a software professional, there are two types of companies you might work for; those whose products are fundamentally software (they make money directly from technology), and those that make their money some other way, but rely on software. Let's call the first Type A, and the second Type …


Trello vs. Asana

In two totally different companies over the past 4 years, across different personalities, teams, and processes, I've seen Asana rejected no fewer than a dozen times in favor of Trello, in spite of multiple executive mandates to use Asana.

In both companies, management (of which I am a part) made …


Pushing Bits with Python

When was the last time you needed to directly manipulate a bunch of binary data? Most engineers run across it only in the context of bit flags and masks in C++ or Java.

It's a little rarer to muck about with direct binary file data. It's nonetheless quite a bit …


A Simple Content-Based Recommendation Engine in Python

Let's pretend we need to build a recommendation engine for an eCommerce web site.

There are basically two approaches you can take: content-based and collaborative-filtering. We'll look at some pros and cons of each approach, and then we'll dig into a simple implementation (ready for deployment on Heroku!) of a …


How Celery Chord Synchronization Works

Celery is a powerful tool for managing asynchronous tasks in Python. The basic model is synchronous Python code pushes a task (in the form of a serialized message) into a message queue (the Celery "broker", which can be a variety of technologies - Redis, RabbitMQ, Memcached, or even a database), and …


Refactoring for Testability: A Real World Example in Python/Django

At ePantry, we strive to have enough automated test coverage that we can deploy with confidence, without being dogmatic about our approach. We certainly aren't a TDD shop, and we don't have rules about code coverage metrics ("no commit can reduce code coverage!"), but it's very unusual that a non-cosmetic …