dan stowell

The past four years I have focused on simplifying programming at Vercel and Replit.

"Keep lowering the barrier to entry. It should be possible to build something interesting in two minutes." ← that's the bar

Prior to that, I surfaced undiscovered gems at Canopy, Spotify, and The Echo Nest


essays

Engineering management for nice people

This post is for nice people who find themselves leading engineering teams.

Not kind people who treat everyone politely even when disagreeing. Nice people. People who care a lot about what other people think and how other people feel.

Because they put the success of their team or their company ahead of individual glory, nice people often get pulled into management. That's great! To a point.

Once you, a nice person, take charge, there's a temptation to keep putting other people first. After all, that's what got you to where you are! But it's not your job.

Your job is not to be everyone's friend. Your job is not to be the cool aunt.

Your job is to provide clarity.

What should I work on next? Which goal should our team focus on? Is this bug bad enough that we have to stop everything and fix it?

Your job is to come up with answers to those questions.

This is where being a nice person comes in handy. If you listen to people, and care about what they think and say, they will tell you how things are actually going. You will hear about the real issues and what's genuinely exciting.

Your job is not to keep everyone happy. Your job is not parrot the last person you talked to.

Your job is to share where the team stands and where it's headed next. People can then either get on board or not. Most often they will. (If you're listening well.) Your job is also to provide clarity to your boss. Providing clarity to your boss is like providing to your team except different. Your boss has less context on the day-to-day than your team and a stronger grasp of the big picture. So you'll need to spend more time describing the present. There's lots more that goes into managing engineering teams! But you, as a nice person, are probably already doing those things. Don't let other people's thoughts and feelings distract you from your one job.
Sales for squeamish engineers

For a long time, I did not understand or want to understand sales. It seemed artificial and boring. So long as whichever company I was working at hit its quarterly numbers, I didn't give sales a second thought.

Then I found myself on the hook for recruiting engineers.

That meant reaching out to people I didn't already know, piquing their interest in joining a startup, interviewing them, and convincing them to sign.

It took a lot of work. Much of it felt wasted at the time.

But every time we hired someone awesome I would feel euphoric.

This is sales, I thought to myself. I get why salespeople do what they do. They're chasing that euphoria.

Most engineers get their energy from building. They don't need an additional dopamine source. But they do need to sell.

What do engineers need to sell? Their time, if they want employment. Their company, if they want great teammates. Their product, if they want to build what people want.

Sales starts out as a search problem. You've got something to sell. You need to find buyers.

If you had time to speak to everyone on the planet, you could brute-force this search. You don't!

There's no clear algorithm here. Talking to people you already know who are familiar with the domain works great. Often they can introduce you to other folks. When this approach pays off it pays off big, because you get a warm introduction to someone interested in buying.

Another path is to search for people on the internet. This can be fun! I especially enjoy finding new sources of signal. "Oh I see you starred this repository on GitHub, you would love to come work with us."

Most people on this earth do not share anywhere near enough about themselves online in order for you to be able to just scan a web page and know whether they're likely to buy what you're selling. You'll have to reach out and ask.

Reaching out to people you don't already know is probably the most uncomfortable part of sales for engineers. That, and nailing down next steps.

Over many years of reaching out cold, I've found that a short, straightforward email sent today beats a perfect email sent next week.

Just write it and send it! If you don't get a response, it has little to do with you or your writing and a lot more to do with people being busy or flat-out not interested in what you're selling.

(If you're launching something entirely new and people don't know you or your company, you will have to work harder on cold emails. Still, sent beats unsent.)

You'll have to bounce between talking to humans and searching on the internet many times. If a particular group of people or spot on the internet proves fruitful, spend more time there!

Once you have scheduled time with someone, they've officially entered your sales pipeline. A sales pipeline is like a CI/CD pipeline or a data pipeline. There are stages and you're trying to move people from one stage to the next.

Some pipelines are pretty clear-cut. When you're looking for a job, you expect an initial conversation, a recruiter screen, a technical screen, an on-site of some sort, and an offer call. Details may change but there's a well-known order to the process.

When you're selling something unique, like a multi-million dollar enterprise software license or a private island, you have to make up the pipeline as you go along. That's where experienced salespeople can make a difference.

Back to the beginning of the pipeline. In your first conversation with someone, you want to learn as much as you can about them. Why are they talking with you? What do they need? What do they want? When you describe what you're selling, when do they light up? What bores them?

The tone you're trying to strike is "I've got this awesome thing that I would love you to have! If you're interested."

Not "please please say yes on the first call and save me from having to talk to more people."

Your whole job in that initial conversation is to learn. You will not close the deal. If someone's not interested, you may be able to figure out what would excite them. At the very least, you can tune your internet searching to look for more people like the person you're talking to or fewer.

At the end of this and every conversation, you want to agree on next steps. The buyer will need to decide if they want to move forward. Ask them when you should expect to hear from them.

Most often, you'll hear back from people before the agreed time.

Sometimes you won't hear back. Usually it's because the person is busy. Or they're not interested but don't want to hurt your feelings by saying no. It's hard to interpret silence!

It is a-okay to send a polite note to someone asking if they want to move forward or if they have any other questions. I like to wait until the morning after the deadline (Monday morning if the deadline's a Friday).

Shy people (engineers) don't like following up. "What if I come across as pushy?" they worry. Sending a single note is not pushy. Sending notes after some has said "I'm not interested" is pushy. Sending multiple notes through multiple channels in rapid succession is pushy.

What people are really avoiding when they don't ask questions is hearing "no." They prefer silence to a clear answer because they can imagine that silence means "maybe."

Silence does not mean "maybe." Silence means "no." Vague "I'll think about it" means "no." Anything other than "yes" means "no."

Expect to hear "no."

That doesn't mean you should approach people with your tail between your legs! Remember, you're going for "check out this great thing that I would love you to have," not "you're probably not interested but here's this thing."

It's easier to face "no" and to strike the right tone if you have other options. You want to talk to many people at once. Not so many that you lose track of who's who or waste time talking to people who will never buy. Enough so that when you hit "no" you can turn your attention to other people instead of sulking.

What about when people say "yes"? Go to the next stage and repeat the process. Keeping going until it's time to close.

Closing simultaneously works like any other stage and takes extra juice. The time scales grow shorter. If the person you're selling to signs with a competitor, the game is over. (99.9% over. Sometimes you can salvage deals or candidates. But the fact that salvaging makes for great stories shows how rare it is.)

As the sales process goes on, you should be building trust and growing comfortable. What started with emails should move to texts and calls.

Expectations also go up. If the person said you'd hear from them by four o'clock on a Friday and you didn't, call them up!

(Unexpected silence at the closing stage is not a good sign. Sometimes people who don't have experience buying will stumble here. But if someone who's been around the block goes cold, brace yourself.)

Closing is the time to shoot your best shot. That doesn't mean making false promises. That doesn't mean bad-mouthing alternatives. It does mean painting a picture of what the person will get by signing and explaining why you want that future for them.

Sometimes it's as simple as calling out of the blue and saying, "I really want to work with you."

A wise person once told me, "don't celebrate until there's ink." The funny thing is, though, that selling doesn't stop once someone has signed.

The candidate has to show up to their first day of work. And their second. And many more after that.

The customer has to receive whatever they bought. And use it. And like it.

People (engineers) say "always be selling" or "always be closing" as a joke. Haha, look at those bros out there chasing deals. Glad that's not me.

Really, you can think of sales as manufacturing options. Just as you can think of coding as building possibilities out of thin air. When you have options you carry yourself confidently, which leads to even more options magically appearing.

If you're not selling, you're choosing to live with the options in front of you. Which can be great! But make that choice deliberately.

What's funny is, the times I've felt most pumped up about my job have been when I'm selling. You'd think it'd be the other way around: when you feel good about your work, then you're motivated to sell. But recruiting or demoing has pulled me out of ho-hum moods often enough that I think selling is the cause, not the effect.

Fresh Finds

The first time you hear a new favorite song, it reaches out of the background noise and the passing of seconds and picks you up by your too-thin t-shirt to keep you from moving or listening to anything else.

If you're like me you start chasing that feeling, knowing that you can't force it but maybe you can put yourself in the right place often enough that it'll find you. It's hard to set out for serendipity. Fresh Finds, a playlist that Kurt, Athena, Jason, Brian, some computers, and I publish on Wednesdays, is the closest I've come to hand-delivery of good, sometimes great, new music.

We started publishing the playlist regularly last November. Kurt said something like 'we haven't looked at what our cool users are listening to.' (He probably didn't use the word 'cool'). The first attempt yielded every huge pop song released in the last eighteen years. By copying a deceptively simple formula from Glenn and Stu, we moved from the hits to the decidedly hip. Since then it's been a matter of listening to a lot of obscure music, tightening our filters, philosophizing, and tweeting. I'm particularly proud of all the small, boring tweaks we made along the way to give this playlist its distinct feel.

Hearing a grab-bag of songs most every day for eight months has changed the way I listen. I'm much more excited to skip from single to single, but when I need refuge from hearing anything unfamiliar I will happily loop an album for days on end. Two finds in particular saved me from the blank ocean of pop and EDM: Green Sky Accident's Fever Dreams (imagine Blink-182, Galaxie 500, and Band of Horses holed up in western Norway for a winter to record an album) and Darts' Below Empty & Westward Bound (imagine early Modest Mouse reincarnated as wistful Australian rockers). My guilty pleasure of the year is Goodbye Tomorrow, who is either the realest thing to come out of Chicago or the product of a marketing machine targeted at formerly/slightly disaffected youth who now have real jobs that pay them real salaries to spend on their real nostalgia.

Having watched Fresh Finds in action for the better part of a year, I worry less often about all good, new music drying up, but the fear does strike on random nights and it's a good fear to have, that maybe people will stop recording in their parent's basements.

How to mmap and execute a flat binary on Linux

Let's say you have some machine code lying around (without any jumps) that you want to run. I don't know why you would want to do that. I found myself wanting to (in order to, say, send machine code across the network and execute it on many nodes) but couldn't find a single-page guide. Here it is.

First, let's write a tiny program to execute.

        unsigned int justreturn() {
            return 243;
        }
        

We'll compile it and then grab its .text section.

        $ clang -O0 -c justreturn.c
        $ objcopy --only-section=.text -O binary justreturn.o justreturn.bin
        

Now we have raw machine code sitting in justreturn.bin. We'll need to open that file, map it into readable and executable memory, then call justreturn().

        #include <fcntl.h>
        #include <sys/mman.h>
        
        
        typedef unsigned int func();
        
        
        int main(int argc, char* argv[]) {
            int fd = open(argv[1], O_RDONLY);
            if (-1 == fd) {
                return 1;
            }
            func* f = mmap(
                0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
            if (MAP_FAILED == f) {
                return 2;
            }
            unsigned int result = f();
            if (243 == result) {
                return 0;
            } else {
                return 3;
            }
        }
        

Compiling and running this beauty at least exits successfully. If we've screwed anything up we'll most likely segfault.

        $ clang -O0 -o mapped mapped.c
        $ ./mapped justreturn.bin; echo $?
        0
        

I spent a lot of time on StackOverflow and Eli Bendersky's site. The one piece I was missing for the longest time was passing --only-section=.text to objcopy. I was in fact copying and attempting to run the ELF header. Like a chump.


jams