A Python script decided my salary
I think one of the scariest conversations at an early-stage startup is neither with investors nor with customers. It’s between co-founders about money.
At my first company, we were very aligned that salary should come from good work, not just venture capital. So we wrote a Python script to determine what we’d get paid.
The company, which ended up building SwiftOnTap and which I started with my co-founder Alex, was called Peach Blossom Spring.1 The script was a joint idea. I took one day to write it, and Alex helped me determine what should go in it. So yeah, I guess you could say I wrote the program that set my own pay.2
This is where Alex and I slept for the first few months in New York. It was the standard of living that the formula was going to get calibrated against.
The script was simply called salary.py. It had three inputs:
- Our revenue over the last two weeks
- Our NPS3
- Our year-over-year growth
It had one output: the number we both got paid. That number was identical for both me and Alex, of course.
The formula
I have the file, and it still runs. Base salary was logarithmic to projected annual revenue:
def early_days_base(revenue):
return 5000 * (math.log10(revenue / 5) + 2)
def vets_base(revenue):
return 30000 * (math.log10(revenue / 5) - 3)
def base_salary(revenue):
if (revenue) < 50000:
return early_days_base(revenue)
else:
return vets_base(revenue)There were two regimes:
- For when the company was pre-revenue
- For when the company started to earn
The constants were not arbitrary. They were meant to connect the branches. This meant that the pay curve would have no step change at the switchover. Even though we were broke, the piecewise function had to be continuous.
My apartment in San Francisco when I was creating salary.py. I didn’t have a bed frame or furniture, just a mattress. This was where I wrote the formula.
We also had two multipliers on the base curve, both logistic:
def nps_multiplier(nps):
L = 1.02
k = 0.11
x_0 = 65
return logistic_func(L, k, x_0)(nps)
def growth_multiplier(growth):
L = 1.05
k = 0.43
x_0 = 13
return logistic_func(L, k, x_0)(growth)The peak multiplier, L, is a generous little cap. We could theoretically get 2% extra for customer love and 5% extra for fast growth, but that’s not how we saw it. We saw it more as a trap door. If our NPS ever went below 65 or growth ever went below 13%, we would basically stop making a salary.
NPS goes from −100 to 100. Centering the curve at 65 puts the point at which we receive half of our pay at an NPS score that most companies don’t ever reach. In other words, at an NPS of 65, we would keep half of our paycheck. At an NPS of 50, we would keep 16% of our paycheck. At an NPS of 0 (meaning customers are equally as likely to promote us to other people as they are to not promote us to other people), we would keep 0.08% of our paycheck. At 0% growth, the growth multiplier would be 0.39%. This means that if our company ever went flat, we would have basically no salary automatically.
I still have a saved run in the file from the two-week stretch when the company first earned 20 cents:
Calculating Peach Blossom Spring founders salary...
Based on our $0.2 revenue in the last two weeks,
which projects to a yearly revenue of $5.2,
combined with our NPS score of 90
and your inf percent growth,
your base salary is $387.89,
which projects to $10,085.17 on the year.
You keep 95.87% of this from NPS.
and 105.00% from growth.
Ben's and Alex's resultant salaries for the last 2 weeks are $390.47$0.20 of revenue equated to a $390 check for each of us.4
Here you can drag the inputs to get a sense of what we would have paid ourselves at different metrics:
Calculating Peach Blossom Spring founders salary... Based on our $0.20 revenue in the last two weeks, which projects to a yearly revenue of $5.20, combined with our NPS score of 90 and your inf percent growth, your base salary is $387.89, which projects to $10,085.17 on the year. You keep 95.87% of this from NPS. and 105.00% from growth.
salary.py. If you drag the revenue up to $1 million in two weeks, you can see the way that the logarithm destroys your raise. If you drop the NPS to 64, you can watch the logistic curve erode.This was the real salary that we actually lived on: $390 every two weeks, or about $10,000 a year.
Here is the $10,000-a-year budget. That’s seven Soylents a day.
We actually qualified for food stamps based on our salary.5 I ended up sleeping at the office after I stopped being able to afford rent. When we were working out of a WeWork, I’d sleep on the floor in the new mothers’ room. That was an awkward conversation with the cleaning people in the morning.
Sort of a joke
Founder pay is actually very emotionally loaded in a small company, and it doesn’t really end. Every time you want to have a raise, you have to have a conversation with your co-founder. Whenever you have a hard month, you have to have the conversation again. It’s not really that much about the dollars. It’s sort of an argument about value. Having these types of arguments at a two-person company is very challenging.
For as long as we adhered to it, the script really removed the argument.
We agreed about the rules ahead of time, so we wouldn’t be tempted later on. It really is the philosophically sound way of dealing with it.
There actually is some amount of wisdom in this, because agreeing on a formula is a lot easier than agreeing on a single number, as long as the direction is generally correct. We had to argue about the principle rather than the take-home pay, and we made the entire argument at the beginning, before the pain of the low salary really started to set in.
And from there, the script handled the dirty work. The inputs were mechanical, and the output would come out of it. We didn’t have to continually have a negotiation every time things changed. Nobody could get higher pay than the other, because we were both beholden to the same formula.
How it ended
Did it produce a good salary? Well, that’s impossible to say. It produced the salary that we told it to, but the problems associated with making $390 every two weeks are probably more than the benefits of aligning incentives. Maybe we just needed a multiplier. It’s hard to say.6
Ultimately, though, I don’t think the longevity of the formula was really the most interesting part of this story. This represented us trying to start a company in the most idealistic and thoughtful way, stressing every possible detail. I wouldn’t run a company that way if I was starting again, but I think it is a beautiful vision in its own way. That attention to detail would also end up making its way into our beloved products, like documentation.
Footnotes
-
Named after a fifth century Chinese fable about a hidden utopia. An ambitious name for a company earning ten cents a week. ↩
-
The fox designing the henhouse, except the fox submitted it for review first. ↩
-
The NPS was 90, entered by hand at the top of the file, by us, about us. Survey methodology: vibes. ↩
-
“Your inf percent growth” is a real output. The script set growth to
float("inf")because the comment next to it says “TODO: implement growth rate calculations when we have the data.” We never had the data. The growth multiplier paid out its full five percent anyway. Infinite growth: technically undefeated. ↩ -
Two compensation systems evaluated my situation that year. The federal government’s was more generous. ↩
-
Also, the comment above the final block reads “Calcualte salary.” We were moving fast. ↩