If It Doesn’t Ship, It Doesn’t Exist

Feb 3, 2023

The top four companies with the most papers at NeurIPS, one of the leading AI/ML research conferences, are Google, Microsoft, Meta, and Deepmind (Google). The 2017 paper, Attention Is All You Need, which introduced the transformer architecture and kick-started large language models, was published by Google. Blake Lemoine, the engineer from Google who believed the company's internal chatbot, LaMDA, was sentient, sounded the alarm six months before OpenAI released ChatGPT. A paper describing Google's text-to-image diffusion model, Imagen, was released shortly after OpenAI launched DALL-E.

Without a doubt, OpenAI and other companies productionizing AI are standing on the shoulders of giants. But from a product standpoint, there's a lot more work (a different kind of work) that goes into wrapping these models up in a usable interface. And when it comes to products, if it doesn't ship, it doesn't exist.

A story from Steve Jobs on his first visit to Xerox PARC, the research lab which invented the computer GUI, object-oriented programming, the Alto PC, Ethernet, and many more foundational computer technologies (but failed to monetize them):

I had three or four people who kept bugging me that I ought to get my rear over to Xerox PARC and see what they were doing. And so I finally did. I went over there. And they were very kind. And they showed me what they were working on. And they showed me really three things, but I was so blinded by the first one that I didn’t even really see the other two. One of the things they showed me was object-oriented programming. They showed me that, but I didn’t even see that. The other one they showed me was really a networked computer system. They had over a hundred Alto computers all networked, using e-mail, etcetera, etcetera. I didn’t even see that. I was so blinded by the first thing they showed me, which was the graphical user interface. I thought it was the best thing I’d ever seen in my life. Now, remember, it was very flawed — what we saw was incomplete, they’d done a bunch of things wrong, but we didn’t know that at the time. It still, though they had — the germ of the idea was there and they’d done it very well. And within, you know, 10 minutes, it was obvious to me that all computers would work like this someday.
Subscribe for daily posts on startups & engineering.

Optimal Stopping Theory

Feb 2, 2023

A company is looking to hire a worker out of n applicants, and the company knows that one of the applicants is the best. The company interviews the applicants individually, and after each interview, it must decide whether to hire the applicant or keep looking. If the company decides to hire an applicant, it can no longer interview other applicants. The goal is to maximize the probability of hiring the best worker.

Let's assume that the best worker is the k-th applicant in the list, where k is unknown. If the company stops and hires the k-th applicant, the expected value of the decision is k/n. On the other hand, if the company continues to interview the next applicant, the expected value of the decision is (k+1)/(n+1). With these values, you can derive the expected value for continuing the search and compare that against the expected value of stopping the search (selecting the current candidate).

The optimal solution to the hiring problems ends up being this:

Reject the first n/e applicants, where n is the total number of applicants and e is the natural logarithm. Then stop at the first applicant who is better than every applicant that has been interviewed so far. If you get to the last candidate and you haven't selected anyone, choose the last candidate.

For large values of n, the probability of selecting the top candidate is about 37% with this method. Of course, this is a toy example, and the constraints in the problem rarely hold (especially not when hiring employees). But it's an interesting way to reason about a class of problems.

Future is Not Evenly Distributed

Feb 1, 2023

"The future is already here – it's just not evenly distributed" – William Gibson.

Many of us spend our time at the very beginning of technology S-curves – debating the next foundational model, the next edge runtime, and the next framework.

Sometimes that early focus makes it challenging to recognize the growth and maturity parts of the S-curve.

Most developers:

  • have never compiled a WebAssembly binary
  • don't know how to write a Dockerfile (or Kubernetes YAML)
  • use Java or C#
  • develop on a Windows PC
  • don't have a sophisticated push-to-deploy pipeline
  • don't use infrastructure-as-code to deploy their applications

Most companies

  • don't have their data organized cleanly in a data warehouse
  • don't use their data to make business decisions
  • don't utilize the cloud fully
  • don't use machine learning in any helpful capacity
  • don't have a real DevOps team (or ever will)

There's still a lot of growth left in many of these trends, and there's still a lot of work to bring them to the masses.

Zero Interest Rate Phenomena

Jan 31, 2023

It's hard to find a more expensive risk-free rate of return than the one you can get today.

Risk-free rates reflect how much risk investors are willing to take on and how much liquidity they require. That's why they've always been usually below the inflation rate – in an inflationary environment, the real rate is zero.

But what happens when interest rates are so low that they approach zero? A zero interest-rate policy (ZIRP) is when a central bank maintains a 0% nominal interest rate.  Banks weren't making any money off their deposits (or even paying negative rates), so why not lend it out at a higher rate? ZIRP opens up an entire class of uses for money that wouldn't exist in most other monetary environments.

But as Warren Buffet says, "Only when the tide goes out do you discover who's been swimming naked." So, as rates have risen, the deals that looked great under ZIRP are no longer profitable. On the surface, that's things like SPACs and meme stocks. But we're getting more data on what else was enabled by access to cheap capital.

Maybe a more interesting question than what was due to ZIRP is – what did the bubble get right?

Subscribe for daily posts on startups & engineering.

The Frontend Bundling Cycle

Jan 30, 2023

In NextJS v13, the framework's compiler got 17x faster. Why? An extensible Rust-based platform for JavaScript compilation and bundling called swc. The compiler went v1 in 2019, and Vercel hired the lead developer in 2021.

For a minute, Svelte/SvelteKit was emerging as a viable alternative to NextJS/Vercel. Now, Rich Harris, the author of Svelte/SvelteKit, is employed at Vercel. The platform now supports SveleKit deployments. Users don't have to choose.

On the one hand, this highlights Guillermo Rauch's skill at one of the most challenging parts of being a startup's CEO – hiring and attracting the best talent. But on the other hand, it emphasizes the bundling phase that the frontend toolchain is converging on – the winners consume the best ideas and technology in the ecosystem.

This is the frontend bundling cycle.

Jarred Sumner announced that Bun will support WASI executables in the next release. The enabler? Bundling Wasmer-JS.

Shopify acquired the company around the Remix framework.

This trend goes beyond the open-source cross-pollination of ideas between these frameworks over the year. Instead, it hints at the emergence of frontend platforms – bundled end-to-end and opinionated toolchains. Single-page applications? Vercel. Multi-page applications? Vercel. Edge API routes? Vercel.

The biggest question in my mind is how durable these platforms can be. The half-life of frontend frameworks is much shorter than the rest of the infrastructure. It's not only tied to particular developer preferences but the UI/UX demands of applications and their platforms.

Can these rigid platforms keep up with a fast-moving ecosystem? Will the bundling phase go beyond the immediate toolchain and encompass other PaaS-like features like databases (e.g., Convex) or more?

Type-Safe API Calls: tRPC vs. gRPC

Jan 29, 2023

Type-safe API calls are those in which a client application can specify the exact API protocol and data types used for communicating with a server. Type-safe API calls reduce the probability of mismatched errors between clients and servers – unexpected fields, missing but expected fields, and fields of the wrong type or shape. I call this Schema-driven development.

How do you make type-safe API calls? You must type-check the request and response on both the client and server. You can't really do this in the wire protocol for two reasons. First, it's expensive to send schema information along with every request – JSON and protobuf don't send this information for that reason. Second, there's no guarantee that the client and server agree on the particular schema – i.e., it might be the right type and suitable shape for the client. Still, the server has been upgraded and is no longer backward compatible.

First, let's look at how gRPC implements this feature. First, gRPC uses protobuf, a compact wire protocol with a schema defined in a proto file. Next, those proto files are used to generate clients/servers in various languages (C++, Java, Go, Python). gRPC solves many other problems, but let's dig into the issues with this process.

  • Generated code is hard to read and hard to debug. In addition, it needs to be regenerated every time the schema changes.
  • Because of the bespoke protobuf toolchain (it was invented at Google), it's difficult and heavyweight to run in browser environments.

tRPC is a new library with a different approach. It's not as optimized over the wire as gRPC (it uses HTTP), but it's much easier to use. Unfortunately, it's only a TypeScript library, so you can't share code across different languages.

  • There's no code generation. Instead, the schema is defined in TypeScript and can dynamically be imported by both the client and server.
  • It is web-native rather than backend-agnostic (at the cost of only supporting TypeScript).
  • It uses the JSON-RPC specification, which can be difficult to parse for many backend languages with strict type systems.  

tRPC is interesting because it makes some (seemingly reasonable) tradeoffs for developer productivity and maintainability. Moreover, it's an interesting example of solving the simple case.