In my garage, you’ll find a modest collection of tools: a chainsaw, a weed whacker, a pair of drills, a circular saw, an oscillating multitool, a Dremel, a spot welder, a lawnmower, a hedge trimmer, an orbital sander, lots of hand tools, and more. I had none of these before I bought my house. Every time I wanted to start a project but couldn’t, I’d hem and haw about the cost of a tool. Then I’d get it and enjoy the brief hit of dopamine from having a new toy, then think “my god, I’m never going to use this again.”
For some of my tools, like my circular saw, this has been true (so far). For other tools, I’ve used them countless times. I’ve used some of them so frequently that if I added up the cost of calling a professional, I’ve probably saved the cost of my entire tool collection a few times over. But every time I reach for my oscillating multitool, I don’t think about the cost savings, I just think about how convenient it is that I have it.
I’m going through this right now with my motorcycle: I need to tension the chain, but I need to buy some little wrenches, a new socket set, and a torque wrench. As much as the immediate cost of these items feels high, the long-term benefit will be that I don’t have to pay $100-200 to have the dealership spend twenty minutes fiddling with my bikes.
You can’t clone people
Growing a company means hiring more people. More work requires more hands. This is noncontroversial, I think: the more your business does, the more people you need to do the things that need doing.
But “things that need doing” are not fungible. Nobody’s sitting around turning a big crank to make the company go: people have specializations and domain expertise. Dependencies form between employees who need each other's skills. Support folks need customer issues sorted out, and if they don’t have a button to fix the customer issue, they need to go to the engineers to do some kind of magic to fix the customer’s issue.
If 5% of support tickets require engineering involvement, that’s probably fine when you have 20 issues a day. When you 10X your customers, that becomes 10 engineering asks per day, and that number will continue to rise as the user base and product grows.
As nice as it would be to clone people to do more work, that’s usually not an option. The only reliable solution is making your existing employees more productive with more and better tools.
Eventually you build a tool so the support folks have a button. Now maybe only 2% of support tickets require engineering involvement, but in absolute numbers the amount of engineering involvement will continue to rise. A second button might drop that to 1%. Until you hit the long tail of issues, you can dramatically decrease the percentage of tickets requiring engineers to context switch with a fairly small, fixed amount of effort.
One telescope can look at many stars
Tools come in many shapes and sizes. Some tools are not tools at all, they’re procedures: just having a defined workflow or canned message or checklist can eliminate the cost of repeated work. Some tools are functional ones, like the button that you add for support to fix customer issues. Other tools are more abstract.
When I was at Stripe, we had an amazing tool (made by amazing people) called Hubble. Originally it was a front-end for Redshift, but then Stripe moved to PrestoTrino. Hubble gained a ton of great features:
A really great schema explorer
Dashboarding
Scheduled queries
Shareable query results
It was invaluable as a tool for anyone, because it meant that anyone across the company could answer questions with data. This is a great example of an abstract tool: it doesn’t solve a single use case, it solves an infinite breadth of use cases.
My weed whacker solves one use case: whacking weeds. My beloved ratcheting screwdriver is an abstract tool that solves many use cases: I can use it to take the fairings off my bike, I can adjust the cabinet doors in my kitchen, I can use it to access the cabin air filter in my car, I can take the keystone wall plate off the junction box in my office so I can install a new network jack…the list goes on and on.
When our CFO, PM, partnerships lead, and my EM all came to me with questions that they needed answered, it was a natural choice for to build a Hubble clone1 called Kepler.
It started as a Slack bot that turned natural language queries into SQL and ran it in a Redshift Serverless namespace. Then I built a UI for it behind SSO. Then I added a chat feature to workshop the queries with AI. Then I added Stripe Data Pipeline, then AWS Cost Insights data. Then I built scheduled queries, then dashboarding features.
Now the whole company has access to data. Nobody outside of engineering needs access to production database infrastructure. Queries are fast, and you can get your results as CSV or exported as a GSheet.
Unlike a purpose-built tool, which breaks specific dependencies between specific people, an abstract tool breaks dependencies across the company. They don’t solve use cases, they solve classes of use cases, unblocking individuals by letting them solve their own problem. And when someone does need help, they come equipped with more data and a better understanding of what they need.
The wrong tool is still a tool
There’s the old saying, “When all you have is a hammer, everything looks like a nail.” Which is supposed to suggest that you should have the right tool for the job. But if you don’t have any tools at all, most jobs are out of reach.
At some point, I wrote down this (unattributed) quote in my notes:
I might not have the right tools, but I have tools, and they're all sharp.
The wrong tool is almost always better than having no tool. I might not have given folks the right tool with Kepler, but I gave them a sharp tool that they can use with effort. Making a rough estimate with data is likely always better than a guess based on vibes. Accomplishing a task in thirty minutes yourself is better than waiting two hours for help, then spending 15 minutes with someone else (who also spends 15 minutes) to get the same work done.
Hubble and Kepler unlock the ability for folks to help themselves, which is the first and most important way to scale people. If folks depend on other folks to accomplish day to day functions, effort becomes fragmented across individuals, directly translating to wasted time2.
As with any iterative process, the key isn’t to get it perfect on the first try. The key is to ship something that works and then refine it. You can’t refine it until people use it, and if it doesn’t exist there’s nothing to use.
Being unrefined doesn’t imply that a tool is not sharp. If Kepler returned bad data half the time, that would be a dull tool. If it was offline half the day, or only supported a few concurrent users, that’s a dull tool. A sharp tool is one that, if given a problem that is within its capability of solving, solves it in its entirety without operational problems. Kepler takes questions (as SQL or natural language) and reliably returns data with answers: that’s sharp. Refining Kepler means simplifying the experience of using it and lowering the barrier to entry. If you can make someone productive with a tool faster and with less effort, you're immediately saving effort.
A case study of working with the support squad
The company I work for has had some major product releases in the last year. In that time, the number of customers that we support has grown superlinearly. The number of support folks that we employ has gone from ~2 people splitting their time to a dedicated three-person team: the Support Squad.
When I joined, we had no internal admin dashboard. At some point I stood up AdminJS, which fit nicely into our existing codebase. This immediately served as an amazing abstract tool for our support folks, who could now get information and make basic changes to customer accounts and their data without needing to go through engineering.
I’m a sucker for a Django Admin clone as much as the next person, but unfortunately AdminJS didn’t work out in the end. We found it difficult to modify and build novel functionality against. It also queried the database in ways didn’t consider indexes on the tables. Sorting a table with tens of millions of rows without using an index is bad, it turns out! Hell, even SELECT * FROM my_table LIMIT 30
is bad in the right context.
AdminJS was the wrong tool, but it proved the ROI on an admin panel. It was easy for me to justify the effort to build a new one from scratch, which was purpose-built rather than a completely open-ended tool3. This took me about two weeks of part-time effort to get through, and it launched alongside the legacy AdminJS site. Another two weeks of part-time effort allowed me to sunset AdminJS for good.
There’s far more freedom in AdminJS: it’s a simple CRUD interface for every table in your database. Any task that you can accomplish with another interface can be accomplished in AdminJS. It’s an abstract tool, why get rid of it?
A tool built with the context of the system it operates on, even if it has less functionality, is a sharper tool than one that has no context. If you can find what you need on a single page instead of spread out across many pages, or can complete tasks in bulk instead of one-by-one, you’re naturally going to be more productive.
For example, in my purpose-built admin panel, you can see user activity in a nice list, JOINed with data from multiple tables to provide context. If you had to go through each AdminJS table to manually search one-to-many SQL relationships, you’d spend all day finding data that the purpose-built tool gives you at a glance.
And it’s okay if the new admin panel doesn’t solve every problem! That’s why abstract, open-ended tools (like Kepler) exist. You can still get your job done, you just need to ask for the data in the right way and in the right place4.
The balance between open-ended and targeted tools
There’s no right answer! Tools are for messy, fallible humans carrying out jobs of varying and unusual shapes, and it would be wild to me or anyone to prescriptively say what the right tool for any particular job is.
You can absolutely go too far in either direction: giving someone only a SQL interface to do their job when they are, say, a support agent is Unfriendly. Giving someone a custom-made admin tool that doesn’t do what they need is Unhelpful.
The important things to consider:
The complexity of the tool: if you ship it, will folks be able to use it?
The adaptability of the tool: will the tool save enough effort to be worth it or is its use case too narrow?
The blast radius: does the tool give human beings too much power for their own good? Are you introducing human error into places where human error carries too much risk?
Sometimes, the juice just isn’t worth the squeeze. There’s definitely a ton of fun tools that I’d love to ship, but the return on investment is decidedly negative. That’s okay! Not every problem needs a tool. The mistake to avoid is to discount the value of a tool entirely by only considering only the up-front cost.
As I’ve said elsewhere, if I had a budget and a corp card, I’d have chosen Hex instead of building my own thing. If you’re in need of a solution for working with data, go check them out, they’re doing great work. (No, I’m not getting paid to say this)
A side note: I think this is why well-intentioned executives (read: not the ones who are doing it for the wrong reasons) are so bullish on return to office. It’s some version of “How can people possibly get anything done if the people they need to accomplish their tasks are working asynchronously?” It neglects to consider that the fix isn’t to reduce the time to resolve dependencies on others, it’s to break those dependencies entirely.
For those interested, the new admin panel is Koa + React + tRPC paired with the Ant design system. It’s no Sail, but it does the job.
Restricting write access to the production system turned out to be a good thing. AdminJS opened the door to folks making ad-hoc changes that caused issues later on. Data integrity is, as it turns out, more important than convenience.
I was on the other side of Hubble/Trino, my team supported it. I remember walking around the Stripe Seattle office and seeing more than half the people have the Hubble interface open.
Kepler looks great, any plan to open source it?
Thanks for the Sail mention in the footnote ❤️