More from Tom Blomfield
TL;DR I built and launched a recipe app with about 20 hours of work - recipeninja.ai Background: I’m a startup founder turned investor. I taught myself (bad) PHP in 2000, and picked up Ruby on Rails in 2011. I’d guess 2015 was the last time I wrote a line of Ruby professionally. I’ve built small side projects over the years, but nothing with any significant usage. So it’s fair to say I’m a little rusty, and I never really bothered to learn front end code or design. In my day job at Y Combinator, I’m around founders who are building amazing stuff with AI every day and I kept hearing about the advances in tools like Lovable, Cursor and Windsurf. I love building stuff and I’ve always got a list of little apps I want to build if I had more free time time. About a month ago, I started playing with Lovable to build a word game based on Articulate (it’s similar to Heads Up or Taboo). I got a working version, but I quickly ran into limitations - I found it very complicated to add a supabase backend, and it kept re-writing large parts of my app logic when I only wanted to make cosmetic changes. It felt like a toy - not ready to build real applications yet. But I kept hearing great things about tools like Windsurf. A couple of weeks ago, I looked again at my list of app ideas to build and saw “Recipe App”. I’ve wanted to build a hands-free recipe app for years. I love to cook, but the problem with most recipe websites is that they’re optimized for SEO, not for humans. So you have pages and pages of descriptive crap to scroll through before you actually get to the recipe. I’ve used the recipe app Paprika to store my recipes in one place, but honestly it feels like it was built in 2009. The UI isn’t great for actually cooking. My hands are covered in food and I don’t really want to touch my phone or computer when I’m following a recipe. So I set out to build what would become RecipeNinja.ai For this project, I decided to use Windsurf. I wanted a Rails 8 API backend and React front-end app and Windsurf set this up for me in no time. Setting up homebrew on a new laptop, installing npm and making sure I’m on the right version of Ruby is always a pain. Windsurf did this for me step-by-step. I needed to set up SSH keys so I could push to GitHub and Heroku. Windsurf did this for me as well, in about 20% of the time it would have taken me to Google all of the relevant commands. I was impressed that it started using the Rails conventions straight out of the box. For database migrations, it used the Rails command-line tool, which then generated the correct file names and used all the correct Rails conventions. I didn’t prompt this specifically - it just knew how to do it. It one-shotted pretty complex changes across the React front end and Rails backend to work seamlessly together. To start with, the main piece of functionality was to generate a complete step-by-step recipe from a simple input (“Lasagne”), generate an image of the finished dish, and then allow the user to progress through the recipe step-by-step with voice narration of each step. I used OpenAI for the LLM and ElevenLabs for voice. “Grandpa Spuds Oxley” gave it a friendly southern accent. Recipe summary: And the recipe step-by-step view: I was pretty astonished that Windsurf managed to integrate both the OpenAI and Elevenlabs APIs without me doing very much at all. After we had a couple of problems with the open AI Ruby library, it quickly fell back to a raw ruby HTTP client implementation, but I honestly didn’t care. As long as it worked, I didn’t really mind if it used 20 lines of code or two lines of code. And Windsurf was pretty good about enforcing reasonable security practices. I wanted to call Elevenlabs directly from the front end while I was still prototyping stuff, and Windsurf objected very strongly, telling me that I was risking exposing my private API credentials to the Internet. I promised I’d fix it before I deployed to production and it finally acquiesced. I decided I wanted to add “Advanced Import” functionality where you could take a picture of a recipe (this could be a handwritten note or a picture from a favourite a recipe book) and RecipeNinja would import the recipe. This took a handful of minutes. Pretty quickly, a pattern emerged; I would prompt for a feature. It would read relevant files and make changes for two or three minutes, and then I would test the backend and front end together. I could quickly see from the JavaScript console or the Rails logs if there was an error, and I would just copy paste this error straight back into Windsurf with little or no explanation. 80% of the time, Windsurf would correct the mistake and the site would work. Pretty quickly, I didn’t even look at the code it generated at all. I just accepted all changes and then checked if it worked in the front end. After a couple of hours of work on the recipe generation, I decided to add the concept of “Users” and include Google Auth as a login option. This would require extensive changes across the front end and backend - a database migration, a new model, new controller and entirely new UI. Windsurf one-shotted the code. It didn’t actually work straight away because I had to configure Google Auth to add `localhost` as a valid origin domain, but Windsurf talked me through the changes I needed to make on the Google Auth website. I took a screenshot of the Google Auth config page and pasted it back into Windsurf and it caught an error I had made. I could login to my app immediately after I made this config change. Pretty mindblowing. You can now see who’s created each recipe, keep a list of your own recipes, and toggle each recipe to public or private visibility. When I needed to set up Heroku to host my app online, Windsurf generated a bunch of terminal commands to configure my Heroku apps correctly. It went slightly off track at one point because it was using old Heroku APIs, so I pointed it to the Heroku docs page and it fixed it up correctly. I always dreaded adding custom domains to my projects - I hate dealing with Registrars and configuring DNS to point at the right nameservers. But Windsurf told me how to configure my GoDaddy domain name DNS to work with Heroku, telling me exactly what buttons to press and what values to paste into the DNS config page. I pointed it at the Heroku docs again and Windsurf used the Heroku command line tool to add the “Custom Domain” add-ons I needed and fetch the right Heroku nameservers. I took a screenshot of the GoDaddy DNS settings and it confirmed it was right. I can see very soon that tools like Cursor & Windsurf will integrate something like Browser Use so that an AI agent will do all this browser-based configuration work with zero user input. I’m also impressed that Windsurf will sometimes start up a Rails server and use curl commands to check that an API is working correctly, or start my React project and load up a web preview and check the front end works. This functionality didn’t always seem to work consistently, and so I fell back to testing it manually myself most of the time. When I was happy with the code, it wrote git commits for me and pushed code to Heroku from the in-built command line terminal. Pretty cool! I do have a few niggles still. Sometimes it’s a little over-eager - it will make more changes than I want, without checking with me that I’m happy or the code works. For example, it might try to commit code and deploy to production, and I need to press “Stop” and actually test the app myself. When I asked it to add analytics, it went overboard and added 100 different analytics events in pretty insignificant places. When it got trigger-happy like this, I reverted the changes and gave it more precise commands to follow one by one. The one thing I haven’t got working yet is automated testing that’s executed by the agent before it decides a task is complete; there’s probably a way to do it with custom rules (I have spent zero time investigating this). It feels like I should be able to have an integration test suite that is run automatically after every code change, and then any test failures should be rectified automatically by the AI before it says it’s finished. Also, the AI should be able to tail my Rails logs to look for errors. It should spot things like database queries and automatically optimize my Active Record queries to make my app perform better. At the moment I’m copy-pasting in excerpts of the Rails logs, and then Windsurf quickly figures out that I’ve got an N+1 query problem and fixes it. Pretty cool. Refactoring is also kind of painful. I’ve ended up with several files that are 700-900 lines long and contain duplicate functionality. For example, list recipes by tag and list recipes by user are basically the same. Recipes by user: This should really be identical to list recipes by tag, but Windsurf has implemented them separately. Recipes by tag: If I ask Windsurf to refactor these two pages, it randomly changes stuff like renaming analytics events, rewriting user-facing alerts, and changing random little UX stuff, when I really want to keep the functionality exactly the same and only move duplicate code into shared modules. Instead, to successfully refactor, I had to ask Windsurf to list out ideas for refactoring, then prompt it specifically to refactor these things one by one, touching nothing else. That worked a little better, but it still wasn’t perfect Sometimes, adding minor functionality to the Rails API will often change the entire API response, rather just adding a couple of fields. Eg It will occasionally change Index Recipes to nest responses in an object { “recipes”: [ ] }, versus just returning an array, which breaks the frontend. And then another minor change will revert it. This is where adding tests to identify and prevent these kinds of API changes would be really useful. When I ask Windsurf to fix these API changes, it will instead change the front end to accept the new API json format and also leave the old implementation in for “backwards compatibility”. This ends up with a tangled mess of code that isn’t really necessary. But I’m vibecoding so I didn’t bother to fix it. Then there was some changes that just didn’t work at all. Trying to implement Posthog analytics in the front end seemed to break my entire app multiple times. I tried to add user voice commands (“Go to the next step”), but this conflicted with the eleven labs voice recordings. Having really good git discipline makes vibe coding much easier and less stressful. If something doesn’t work after 10 minutes, I can just git reset head –hard. I’ve not lost very much time, and it frees me up to try more ambitious prompts to see what the AI can do. Less technical users who aren’t familiar with git have lost months of work when the AI goes off on a vision quest and the inbuilt revert functionality doesn’t work properly. It seems like adding more native support for version control could be a massive win for these AI coding tools. Another complaint I’ve heard is that the AI coding tools don’t write “production” code that can scale. So I decided to put this to the test by asking Windsurf for some tips on how to make the application more performant. It identified I was downloading 3 MB image files for each recipe, and suggested a Rails feature for adding lower resolution image variants automatically. Two minutes later, I had thumbnail and midsize variants that decrease the loading time of each page by 80%. Similarly, it identified inefficient N+1 active record queries and rewrote them to be more efficient. There are a ton more performance features that come built into Rails - caching would be the next thing I’d probably add if usage really ballooned. Before going to production, I kept my promise to move my Elevenlabs API keys to the backend. Almost as an afterthought, I asked asked Windsurf to cache the voice responses so that I’d only make an Elevenlabs API call once for each recipe step; after that, the audio file was stored in S3 using Rails ActiveStorage and served without costing me more credits. Two minutes later, it was done. Awesome. At the end of a vibecoding session, I’d write a list of 10 or 15 new ideas for functionality that I wanted to add the next time I came back to the project. In the past, these lists would’ve built up over time and never gotten done. Each task might’ve taken me five minutes to an hour to complete manually. With Windsurf, I was astonished how quickly I could work through these lists. Changes took one or two minutes each, and within 30 minutes I’d completed my entire to do list from the day before. It was astonishing how productive I felt. I can create the features faster than I can come up with ideas. Before launching, I wanted to improve the design, so I took a quick look at a couple of recipe sites. They were much more visual than my site, and so I simply told Windsurf to make my design more visual, emphasizing photos of food. Its first try was great. I showed it to a couple of friends and they suggested I should add recipe categories - “Thai” or “Mexican” or “Pizza” for example. They showed me the DoorDash app, so I took a screenshot of it and pasted it into Windsurf. My prompt was “Give me a carousel of food icons that look like this”. Again, this worked in one shot. I think my version actually looks better than Doordash 🤷♂️ Doordash: My carousel: I also saw I was getting a console error from missing Favicon. I always struggle to make Favicon for previous sites because I could never figure out where they were supposed to go or what file format they needed. I got OpenAI to generate me a little recipe ninja icon with a transparent background and I saved it into my project directory. I asked Windsurf what file format I need and it listed out nine different sizes and file formats. Seems annoying. I wondered if Windsurf could just do it all for me. It quickly wrote a series of Bash commands to create a temporary folder, resize the image and create the nine variants I needed. It put them into the right directory and then cleaned up the temporary directory. I laughed in amazement. I’ve never been good at bash scripting and I didn’t know if it was even possible to do what I was asking via the command line. I guess it is possible. After launching and posting on Twitter, a few hundred users visited the site and generated about 1000 recipes. I was pretty happy! Unfortunately, the next day I woke up and saw that I had a $700 OpenAI bill. Someone had been abusing the site and costing me a lot of OpenAI credits by creating a single recipe over and over again - “Pasta with Shallots and Pineapple”. They did this 12,000 times. Obviously, I had not put any rate limiting in. Still, I was determined not to write any code. I explained the problem and asked Windsurf to come up with solutions. Seconds later, I had 15 pretty good suggestions. I implemented several (but not all) of the ideas in about 10 minutes and the abuse stopped dead in its tracks. I won’t tell you which ones I chose in case Mr Shallots and Pineapple is reading. The app’s security is not perfect, but I’m pretty happy with it for the scale I’m at. If I continue to grow and get more abuse, I’ll implement more robust measures. Overall, I am astonished how productive Windsurf has made me in the last two weeks. I’m not a good designer or frontend developer, and I’m a very rusty rails dev. I got this project into production 5 to 10 times faster than it would’ve taken me manually, and the level of polish on the front end is much higher than I could’ve achieved on my own. Over and over again, I would ask for a change and be astonished at the speed and quality with which Windsurf implemented it. I just sat laughing as the computer wrote code. The next thing I want to change is making the recipe generation process much more immediate and responsive. Right now, it takes about 20 seconds to generate a recipe and for a new user it feels like maybe the app just isn’t doing anything. Instead, I’m experimenting with using Websockets to show a streaming response as the recipe is created. This gives the user immediate feedback that something is happening. It would also make editing the recipe really fun - you could ask it to “add nuts” to the recipe, and see as the recipe dynamically updates 2-3 seconds later. You could also say “Increase the quantities to cook for 8 people” or “Change from imperial to metric measurements”. I have a basic implementation working, but there are still some rough edges. I might actually go and read the code this time to figure out what it’s doing! I also want to add a full voice agent interface so that you don’t have to touch the screen at all. Halfway through cooking a recipe, you might ask “I don’t have cilantro - what could I use instead?” or say “Set a timer for 30 minutes”. That would be my dream recipe app! Tools like Windsurf or Cursor aren’t yet as useful for non-technical users - they’re extremely powerful and there are still too many ways to blow your own face off. I have a fairly good idea of the architecture that I want Windsurf to implement, and I could quickly spot when it was going off track or choosing a solution that was inappropriately complicated for the feature I was building. At the moment, a technical background is a massive advantage for using Windsurf. As a rusty developer, it made me feel like I had superpowers. But I believe within a couple of months, when things like log tailing and automated testing and native version control get implemented, it will be an extremely powerful tool for even non-technical people to write production-quality apps. The AI will be able to make complex changes and then verify those changes are actually working. At the moment, it feels like it’s making a best guess at what will work and then leaving the user to test it. Implementing better feedback loops will enable a truly agentic, recursive, self-healing development flow. It doesn’t feel like it needs any breakthrough in technology to enable this. It’s just about adding a few tool calls to the existing LLMs. My mind races as I try to think through the implications for professional software developers. Meanwhile, the LLMs aren’t going to sit still. They’re getting better at a frightening rate. I spoke to several very capable software engineers who are Y Combinator founders in the last week. About a quarter of them told me that 95% of their code is written by AI. In six or twelve months, I just don’t think software engineering is going exist in the same way as it does today. The cost of creating high-quality, custom software is quickly trending towards zero. You can try the site yourself at recipeninja.ai Here’s a complete list of functionality. Of course, Windsurf just generated this list for me 🫠 RecipeNinja: Comprehensive Functionality Overview Core Concept: the app appears to be a cooking assistant application that provides voice-guided recipe instructions, allowing users to cook hands-free while following step-by-step recipe guidance. Backend (Rails API) Functionality User Authentication & Authorization Google OAuth integration for user authentication User account management with secure authentication flows Authorization system ensuring users can only access their own private recipes or public recipes Recipe Management Recipe Model Features: Unique public IDs (format: “r_” + 14 random alphanumeric characters) for security User ownership (user_id field with NOT NULL constraint) Public/private visibility toggle (default: private) Comprehensive recipe data storage (title, ingredients, steps, cooking time, etc.) Image attachment capability using Active Storage with S3 storage in production Recipe Tagging System: Many-to-many relationship between recipes and tags Tag model with unique name attribute RecipeTag join model for the relationship Helper methods for adding/removing tags from recipes Recipe API Endpoints: CRUD operations for recipes Pagination support with metadata (current_page, per_page, total_pages, total_count) Default sorting by newest first (created_at DESC) Filtering recipes by tags Different serializers for list view (RecipeSummarySerializer) and detail view (RecipeSerializer) Voice Generation Voice Recording System: VoiceRecording model linked to recipes Integration with Eleven Labs API for text-to-speech conversion Caching of voice recordings in S3 to reduce API calls Unique identifiers combining recipe_id, step_id, and voice_id Force regeneration option for refreshing recordings Audio Processing: Using streamio-ffmpeg gem for audio file analysis Active Storage integration for audio file management S3 storage for audio files in production Recipe Import & Generation RecipeImporter Service: OpenAI integration for recipe generation Conversion of text recipes into structured format Parsing and normalization of recipe data Import from photos functionality Frontend (React) Functionality User Interface Components Recipe Selection & Browsing: Recipe listing with pagination Real-time updates with 10-second polling mechanism Tag filtering functionality Recipe cards showing summary information (without images) “View Details” and “Start Cooking” buttons for each recipe Recipe Detail View: Complete recipe information display Recipe image display Tag display with clickable tags Option to start cooking from this view Cooking Experience: Step-by-step recipe navigation Voice guidance for each step Keyboard shortcuts for hands-free control: Arrow keys for step navigation Space for play/pause audio Escape to return to recipe selection URL-based step tracking (e.g., /recipe/r_xlxG4bcTLs9jbM/classic-lasagna/steps/1) State Management & Data Flow Recipe Service: API integration for fetching recipes Support for pagination parameters Tag-based filtering Caching mechanisms for recipe data Image URL handling for detailed views Authentication Flow: Google OAuth integration using environment variables User session management Authorization header management for API requests Progressive Web App Features PWA capabilities for installation on devices Responsive design for various screen sizes Favicon and app icon support Deployment Architecture Two-App Structure: cook-voice-api: Rails backend on Heroku cook-voice-wizard: React frontend/PWA on Heroku Backend Infrastructure: Ruby 3.2.2 PostgreSQL database (Heroku PostgreSQL addon) Amazon S3 for file storage Environment variables for configuration Frontend Infrastructure: React application Environment variable configuration Static buildpack on Heroku SPA routing configuration Security Measures: HTTPS enforcement Rails credentials system Environment variables for sensitive information Public ID system to mask database IDs This comprehensive overview covers the major functionality of the Cook Voice application based on the available information. The application appears to be a sophisticated cooking assistant that combines recipe management with voice guidance to create a hands-free cooking experience.
We held a YC event a couple of months ago where Brian Chesky from Airbnb gave a passionate talk about his experience running Airbnb over the last 17 years. He believed that as Airbnb hired more professional managers, he lost a close connection with the details of the end product and the company suffered as a result. It clearly touched a nerve with a lot of people present. It was uncomfortable to realize that I made many of the same mistakes when I ran my startup, yet somehow comforting to know I was in good company. Paul Graham wrote an essay about a few weeks later, the now-famous Founder Mode, which I want to explore today. The essay defines “manager mode” as “treat[ing] subtrees of the org chart as black boxes. You tell your direct reports what to do, and it’s up to them to figure out how. But you don’t get involved in the details of what they do.” On the other hand “there are things founders can do that managers can't” - this is “founder mode” - and it’s left largely undefined. PG’s essay is perhaps best read as an invitation to founders to compare notes to discover a better way of running companies at scale. But the essay left me questioning whether “founder mode” and “manager mode” are useful labels. They certainly generated a lot of controversy online, but if you hire bad executives and let them run your company with minimal intervention or oversight, you’re in for a bad time whether you’re a founder or not. And, empirically, we can point to numerous examples of both founders and hired CEOs who have either been extremely successful or totally useless. Whether someone is a founder seems largely orthogonal to whether they’re a competent leader. Maybe my quibble is just a semantic one - these labels distract from the debate. I do believe there is a really interesting question here - how do good leaders stay in the detail and run great companies at scale? Are there areas where founders really do have a persisting advantage? And that’s what I want to explore in more detail here. I think the general pattern that Brian was identifying was the following. A young, inexperienced founder with limited management experience is running a rapidly scaling company. Famous VCs invest a lot of money and join the board. Headcount passes 100 and quickly grows beyond 1000. The VCs (who often have never run anything themselves) encourage the founder to hire “executives” with “scaling experience”. The founder is told to “empower” these executives, who typically then implement techniques that worked for them at previous companies. But, too often, these techniques fail in the new company. The founder is too nervous to intervene - these people are supposed to be “experts” - or is rebuffed by the experienced executives for “micromanaging”. Things don’t go well, and the company slowly stagnates. The founder gets sad and eventually quits or is pushed out. Now, it’s very common to hire executives who are ineffective. Every CEO has that experience. But it’s not sensible to give those executives unverified trust and free reign from day one. I don’t think any competent CEO should treat “subtrees of the org chart as black boxes”. As a leader, of course you constantly need to do skip-level meetings with people further down in the organization. You need to have your finger on the pulse of the company and be able drill down into each area when necessary. The process of building and maintaining trust between a CEO and an exec involves the CEO repeatedly going incredibly deep on niche subjects, verifying that the exec really knows what’s going on in their department, and has a good grasp on the problems. As the exec builds trust, these deep-dives can become less frequent, but they never totally disappear. If the exec repeatedly doesn’t have a good grasp of the details as you dive deep into their domain, you quickly realize that you need to replace them. To do this, leaders need an extremely detailed and nuanced understanding of their business. There’s a cliched idea of clueless MBAs jumping from company to company, treating them as black boxes that might as well be making widgets. They clearly don’t have the domain expertise to dive into any kind of detail. This is not a successful way to run a company. Over time, and without constant pruning, companies do seem to accumulate layers of management who do very little. These managers spend their time coordinating people, trying to establish consensus, and padding out their promotion packets to ascend to the next rung of the corporate ladder. Instead, I believe that great leaders have to be able to dig into the details, have an incredibly high bar for quality, and ultimately do great IC work themselves. Great managers have to manage the work - they should primarily be responsible for quality and speed of output. Managing people must be secondary to managing the product. At Monzo, we experimented with some pretty wacky management structures at times. There was a period when our middle managers were basically just responsible for “pastoral care” of each employee. They were not connected at all with the output that the ICs were producing. It was totally insane and overlapped with our period of lowest productivity by far. As you scale a company, you do have to figure out which executives you can trust with what kind of work, and delegate decisions to them appropriately. The limiting factor in any scaling company is usually management bandwidth. I believe one of the best articulations of this idea is Keith Rabois’s Barrels vs Ammunition (at 14:32, but the whole video is excellent) If you think about people, there are two categories of high-quality people: there is the ammunition, and then there are the barrels. You can add all the ammunition you want, but if you have only five barrels in your company, you can literally do only five things simultaneously. Finding those barrels that you can shoot through — someone who can take an idea from conception to live and it’s almost perfect — are incredibly difficult to find. This kind of person can pull people with them. They can charge up the hill. They can motivate their team, and they can edit themselves autonomously. Once someone demonstrates “barrel-like” ability, you should quickly put more on their plate. Often, the best leaders at your company will have been promoted from within, over a period of several years. They’ve established huge amounts of trust and have deep domain knowledge. Constantly micromanaging these people is a waste of your time and will actually limit the great work your company can do. You must empower them. On the other hand, trying to hire in senior executives from outside the company is fraught with difficulty. Sadly, many really are just “professional fakers”. These people have run hundreds of job interviews in their career and are experts at “managing up” to a CEO. This makes standard interviews almost entirely useless. Instead, I would try to pick previous projects they’ve run and dig into as much detail as you can. See how granular they can go on the problems they encountered, the decisions they made and the results they achieved. I would do a very large number of reference checks - try to find bosses, peers and subordinates and talk to them in detail about the person you are about to hire. Every time I failed to do detailed reference checks on an executive hire, I deeply regretted it. Spend significant time with the person before hiring them. I spent about a year meeting TS Anil (the now-CEO) before hiring him at Monzo, and 9 months meeting with Sujata, the COO. They are two of the best executive hires I ever made, and I’m sad I didn’t get to work with them for longer. Once you’ve hired someone, you need to ensure they’re doing a good job before giving them free-reign in your company. Are they really a “barrel”? Sadly, at least 50% of executive hires don’t work out. It’s essential that you identify these people early and weed them out. And the way you do this is dive deep with them into their domain and see if they can keep up. When a CEO takes their eye off the details, the career politicians and bureaucrats thrive. I’ve heard from many founders that their senior managers - C levels and VPs - react badly when young founders want to dig into the details. They seem to say “You hired us to be the experts here. Now you need to get out of the way while we run the company.” As PG’s essay says, “Founders feel like they’re being gaslit from both sides — by the [VCs] telling them they have to run their companies like managers, and by the [execs] working for them when they do.” They “hire professional fakers and let them drive the company into the ground.” This is also the pattern that Brian identified in his talk, and I think it’s absolutely destructive. I have to say that this generally wasn’t my experience - I had access to all metrics from across the company, on dozens of pages of real time dashboards. I’d frequently roam the office and sit next to a random employee and start talking to them about their work. Teams would often have their dashboards up on walls and I loved digging into what the data was showing. I had an obsession with extremely granular metrics - it cost us £4.40 to onboard a single customer, split between KYC cost, debit card manufacturing, postage and packaging. Our CAC varied between £10.50 and £14.00 depending on channel. Our NPS started at +78 and declined to +71 (and we spent a really long time trying to figure out why). The average customer transacted on their Monzo card 7.4 times a week, with an average spend of £14.10 per transaction. They deposited £600 month (which grew to £950 after 18 months of using Monzo) and they opened the app 22 times per week. I could go on and on - I was obsessed with these metrics. Another thing we did was to have everyone at Monzo - including the entire senior management team - do customer service for one day a month. This was a great way to make sure everyone stayed closely connected to the issues customers really cared about. We stopped doing this in about year 4 or 5, and it seemed to coincide with a rapid slow-down in the pace of execution. Sadly, I hired a number of bad executives, but the techniques above generally allowed me to identify them pretty quickly, and we ended up firing a lot of senior people. There were certainly times when I was too busy and didn’t have the time, or I didn’t feel like I had the expertise to really dive in. Certain teams’ work was so alien to me that I couldn’t effectively go deep. In retrospect, they were also the lowest performing teams when I was there. I think that the final part of successful leadership is the ability to make hard decisions in the absence of complete information. At some point or another, companies will encounter these bet-the-company moments, and maybe this is one area that founders do have an advantage over professional managers. Having the moral authority to take a really hard decision comes with the founder title. Zuckerberg’s decision to go all-in on mobile 2012 is an example of this. Professional managers inevitably have a level of risk aversion due to the insecurity of their job position - if it goes wrong, the founder is less likely to lose their job. Zuckerberg’s bet on the Metaverse would probably have gotten a professional CEO fired. But there are relatively few of these bet-the-company decisions. Everything slows to a crawl if the CEO needs to be consulted every time a decision needs to be made. You want your (competent) execs and your top ICs to be making great decisions every day - and you as the CEO should dive in only occasionally to spot-check these decisions. This is how you scale leadership. I’ve worked at a startup where the founder CEO came in every Monday with a new idea. He seemed to spend every weekend talking to investors and then turned up with heaps of enthusiasm for a new initiative. But we never had time to actually make progress on the idea before he’d change his mind again. This kind of leadership thrash is depressingly common with inexperienced founder-CEOs. I encountered a similar thing at my own company - I learned that I had to be really careful about sharing half-formed opinions and ideas, especially with less experienced team members (and as the company grew past 1000 people). I would sometimes get enthusiastic about a new half-formed product idea, or make an off-the-cuff remark about something I found interesting. Without intending to, I’d derail an entire team for weeks. You need to be deliberate and intentional about CEO-level interventions when you’re running a company of thousands. I learned that if I wanted the company to focus, I had to have a singular message that I repeated endlessly. I would write a 3-4 page letter to the entire company about every 6 months, outlining the one or two things we needed to focus on. At our weekly all-hands, I would just repeat the same message in different ways. I think I said “fix unit economics” several thousand times in 2018. It became a meme at the company. But it worked. I sat in every weekly product review meeting with my CPO and CTO, even as we got to 2000 team-members. Our main input to the teams was typically to try to cut scope and launch faster. I learned to save my open-ended product brainstorming for a much smaller group - VP Marketing, VP Design, CPO, CTO, and a couple of very senior engineering ICs. We’d meet every 2-3 weeks and spend a couple of hours jamming on the kinds of things we could build in future. These meetings were the most fun I had at Monzo. Some of these became a core part of the product, others were just a fun way to blow off steam without distracting the company. I’m not saying I have all the answers here - and I was far from a perfect CEO. I don’t think I really ever figured out how to balance the extremely onerous regulatory constraints of running a bank with a desire to move quickly and delight our customers. Especially as we grew past 500 people, I think we lost a lot of the early intensity and focus that made Monzo great. We raised hundreds of millions of dollars, so when new employees turned up to a fancy office with catered lunches they believed they had joined a company like Google, and everything slowed down. Personally, I was in the detail to such an extent that I couldn’t ever really disconnect from the company. I treated every criticism of Monzo as an attack on me personally. I found it impossible to keep a sense of perspective or any balance in my life, and ultimately I burned out. I believe this is the biggest danger for founders once they’ve hit product-market-fit. I return to the original questions - how do good leaders stay in the detail and run great companies at scale? Are there areas where founders really do have a persisting advantage? I’ve shared some of my views here - I would insist that all CEOs stay connected to the details of their product, have an incredibly high bar for quality, manage for output, and delegate only to the extent that your leaders have earned your trust. Don’t feel embarrassed about the way you want to run your company. I would love to hear how others run their companies, whether they’re founders or not.
I just spent a week talking with some exceptional students from three of the UK’s top universities; Cambridge, Oxford and Imperial College. Along with UCL, these British universities represent 4 of the top 10 universities in the world. The US - a country with 5x more people and 8x higher GDP - has the same number of universities in the global top 10. On these visits, I was struck by the world-class quality of technical talent, especially in AI and biosciences. But I was also struck by something else. After their studies, most of these smart young people wanted to go and work at companies like McKinsey, Goldman Sachs or Google. I now live in San Francisco and invest in early-stage startups at Y Combinator, and it’s striking how undergraduates at top US universities start companies at more than 5x the rate of their British-educated peers. Oxford is ranked 50th in the world, while Cambridge is 61st. Imperial just makes the list at #100. I have been thinking a lot about why this is. The UK certainly doesn’t lack the talent or education, and I don’t think it’s any longer about access to capital. People like to talk about the role of government incentives, but San Francisco politicians certainly haven’t done much to help the startup ecosystem over the last few years, while the UK government has passed a raft of supportive measures. Instead, I think it’s something more deep-rooted - in the UK, the ideas of taking risk and of brazen, commercial ambition are seen as negatives. The American dream is the belief that anyone can be successful if they are smart enough and work hard enough. Whether or not it is the reality for most Americans, Silicon Valley thrives on this optimism. The US has a positive-sum mindset that business growth will create more wealth and prosperity and that most people overall will benefit as a result. The approach to business in the UK and Europe feels zero-sum. Our instinct is to regulate and tax the technologies that are being pioneered in California, in the misguided belief that it will give us some kind of competitive advantage. Young people who consider starting businesses are discouraged and the vast majority of our smart, technical graduates take “safe” jobs at prestigious employers. I am trying to figure out why that is. ___ Growing up, every successful adult in my life seemed to be a banker, a lawyer or perhaps a civil engineer, like my father. I didn’t know a single person who programmed computers as a job. I taught myself to code entirely from books and the internet in the late 1990s. The pinnacle of my parents’ ambition for me was to go to Oxford and study law. And so I did. While at university, the high-status thing was to work for a prestigious law firm, an investment bank or a management consultancy, and then perhaps move to Private Equity after 3 or 4 years. But while other students were getting summer internships, I launched a startup with two friends. It was an online student marketplace - a bit like eBay - for students. We tried to raise money in the UK in 2006, but found it impossible. One of my cofounders, Kulveer, had a full-time job at Deutsche Bank in London which he left to focus on the startup. His friends were incredulous - they were worried he’d become homeless. My two cofounders eventually got sick of trying to raise money in the UK and moved out to San Francisco. I was too risk-averse to join them - I quit the startup to finish my law degree and then became a management consultant - it seemed like the thing that smart, ambitious students should do. The idea that I could launch a startup instead of getting a “real” job seemed totally implausible. But in 2011, I turned down a job at McKinsey to start a company, a payments business called GoCardless, with two more friends from university. We managed to get an offer of investment (in the US) just days before my start date at McKinsey, which finally gave me the confidence to choose the startup over a prestigious job offer. My parents were very worried and a friend of my father, who was an investment banker at the time, took me to one side to warn me that this would be the worst decision I ever made. Thirteen years later, GoCardless is worth $2.3bn. I had a similar experience in 2016, when I was starting Monzo, I had to go through regulatory interviews before I was allowed to work as the CEO of a bank. We hired lawyers and consultants to run mock interviews - and they told me plainly that I was wasting my time. It was inconceivable that the Bank of England would authorise me, a 31 year old who’d never even worked in a bank, to act as the CEO of the UK’s newest bank. (It turned out they did.) So much of the UK felt like it was pushing against me as an aspiring entrepreneur. It was like an immune system fighting against a foreign body. The reception I got in the US was dramatically different - people were overwhelmingly encouraging, supportive and helpful. For the benefit of readers who aren’t from the UK, I hope it’s fair to say that Monzo is now quite successful as well. ___ I don’t think I was any smarter or harder working than many of the recent law graduates around me at Oxford. But I probably had an unusual attitude to risk. When we started GoCardless, we were 25 years old, had good degrees, no kids and supportive families. When fundraising was going poorly, we discussed using my parents’ garage as an office. McKinsey had told me to contact them if I ever wanted a job in future. I wonder if the offer still stands. Of course, I benefitted from immense privilege. I had a supportive family whose garage I could have used as an office. I had a good, state-funded education. I lived in a safe, democratic country with free healthcare. And I had a job offer if things didn’t work out. And so the downside of the risks we were taking just didn’t seem that great. But there’s a pessimism in the UK that often makes people believe they’re destined to fail before they start. That it’s wrong to even think about being different. Our smartest, most technical young people aspire to work for big companies with prestigious brands, rather than take a risk and start something of their own. And I still believe the downside risk is small, especially for privileged, smart young people with a great education, a supportive family, and before they accumulate responsibilities like childcare or a mortgage. If you spend a year or two running a startup and it fails, it’s not a big deal - the job at Google or McKinsey is still there at the end of it anyway. The potential upside is that you create a product that millions of people use and earn enough money that you never have to work again if you don’t want to. This view is obviously elitist - I’m aware it’s not attainable for everyone. But, as a country, we should absolutely want our smartest and hardest working people building very successful companies - these companies are the engines of economic growth. They will employ thousands of people and generate billions in tax revenues. The prosperity that they create will make the entire country wealthier. We need to make our pie bigger, not fight over the economic leftovers of the US. Imagine how different the UK would feel if Google, Microsoft and Facebook were all founded here. ___ When I was talking with many of these smart students this week, many asked me how these American founders get away with all their wild claims. They seem to have limitless ambition and make outlandish claims about their goals - how can they be so sure it will pan out like that? There’s always so much uncertainty, especially in scientific research. Aren’t they all just bullshitters? Founders in the UK often tell me “I just want to be more realistic,” and they pitch their business describing the median expected outcome, which for most startups is failure. The difference is simple - startup founders in the US imagine the range of possible scenarios and pitch the top one percent outcome. When we were starting Monzo, I said we wanted to build a bank for a billion people around the world. That’s a bold ambition, and one it’s perhaps unlikely Monzo will meet. Even if we miss that goal, we’ve still succeeded in building a profitable bank from scratch that has almost 10 million customers. And it turns out that this approach matches exactly what venture capitalists are looking for. It is an industry based on outlier returns, especially at the earliest stages. Perhaps 70% of investments will fail completely, and another 29% might make a modest return - 1x to 3x the capital invested. But 1% of investments will be worth 1000x what was initially paid. Those 1% of successes easily pay for all the other failures. On the contrary, many UK investors take an extremely risk-averse view to new business - I lost count of the times that a British investor would ask for me a 3 year cash-flow forecast, and expect the company to break even within that time. UK investors spend too much time trying to mitigate downside risk with all sorts of protective provisions. US venture capital investors are more likely to ask “if this is wildly successful, how big could it be?”. The downside of early-stage investing is that you lose 1x your money - it’s genuinely not worth worrying much about. The upside is that you make 1000x. This is where you should focus your attention. ___ A thriving tech ecosystem is a virtuous cycle - there’s a flywheel effect that takes several revolutions to get up-to-speed. Early pioneers start companies, raise a little money and employ some people. The most successful of these might get acquired or even IPO. The founders get rich and become venture capital investors. The early employees start their own companies or become angel investors. Later employees learn how to scale up these businesses and use their expertise to become the executives of the next wave of successful growth-stage startups. Skype was a great early example of this - Niklas Zenstrom, the co-founder, launched the VC Atomico. Early employees of Skype started Transferwise or became seed investors at funds like Passion Capital, which invested in both GoCardless and Monzo. Alumni of those two companies have created more than 30 startups between them. Matt Robinson, my cofounder at GoCardless, was one of the UK’s most prolific angel investors, before recently becoming a Partner at Accel, one of the top VCs in the world. Relative to 15 or 20 years ago, the UK tech ecosystem is flourishing - our flywheel is starting to accelerate. Silicon Valley has just had a 50 year head start. There is no longer a shortage of capital for great founders in the UK (although most of the capital still comes from overseas investors). I just believe that people with the highest potential aren’t choosing to launch companies, and I want that to change. ___ I don’t think the world is prepared for the tidal wave of technological change that’s about to hit over the next handful of years. Primarily because of the advances in AI, companies are being started this year that are going to transform entire industries over the next decade. It doesn’t seem hyperbolic to say that we should expect to see very significant breakthroughs in quantum computers, nuclear fusion, self-driving vehicles, space exploration and drug discovery in the next 10 or 20 years. I think we are about to enter the biggest period of transformation humanity has ever seen. Instead of taking safe, well-paying jobs at Goldman Sachs or McKinsey, our young people should take the lead as the world is being rebuilt around us.
I’ve been asked a few times recently how we got customers to sign up to Monzo in the early years and I haven’t been able to give a satisfactory answer in a sufficiently short space of time. I thought I’d write out my thoughts in a longer piece so I can feel less bad about giving an incomplete answer - anyone who wants to know the details can read this instead. Let’s start with a rough timeline, which I’ll then flesh out below. 2015 Started the company in February 2015. We had a big, ambitious goal - to start a bank - and worked hard to get press coverage before publicly launching. Ended the year with 3k “Alpha” cardholders and a waitlist of 20k. 2016 We launched an early prototype and continuously improved it. Scarcity (waitlist) seemed to drive more signups - there was a standard “invite a friends and we’ll bump you up the queue” mechanic. A lot of hustle and hard work (100+ in-person events). Community + Mission + Transparency - lots of blogging and social media. Crowdfunding. Ended the year with about 70k “Beta” cardholders. 2017 Genuinely great product. Market-leading customer service. Hot coral card! We consciously worked on viral product features & referral mechanics for the first time. Ended the year with about 600k “Beta” customers. 2018 Full banking licence. Hit 1m customers in September! — First, a note about the context. We started the company in the UK in February 2015, when “digital banks” weren’t yet a popular idea. BankSimple had launched in 2012 with some big plans, but sold to BBVA in early 2014 with about 100,000 accounts, having struggled to raise sufficient funding to continue. N26 started development in late 2013, initially as a card for kids, while Revolut was founded a few months after Monzo, in April 2015. At around the same time, the UK regulator had announced plans to make it easier to start new banks, following the “too-big-to-fail” mess of the financial crisis, and it was on the back of this initiative that Monzo was born. We spent the first couple of months of the company’s life furiously writing a banking licence application, believing that the licence might be granted within 12 months. In fact, it took 3 years before we were able to open full bank accounts for the bulk of our customers. Even 12 months felt slow; it had only been a handful of years since I’d gone through Y Combinator with my previous startup, GoCardless, and I was terrified of spending too much time building something without a real indication that customers wanted what we were building. Going back through my notes from the time, I found I’d peppered them with YC mantras like “Do things that don’t scale”, “Launch early and talk to users” and “Make something people want”. So we looked for ways to get a product into users’ hands as soon as possible. Pretty quickly we figured out that we could use prepaid debit cards as a sort of hacky prototype for a full bank. Before that point, prepaid cards had only really been used for kids’ accounts (Osper and GoHenry had both been founded in 2012) and the financially excluded - people who couldn’t get full bank accounts. These prepaid cards were horribly loss-making, and lacked about 60% of the functionality of a full bank account, so we budgeted for 10,000 cards. At the time, we couldn’t imagine more than 10,000 people would be willing to test out an incomplete bank account. In fact, we had almost 600,000 active prepaid cards by the time we transferred all customers to the full bank almost 3 years later. Despite the cost, these prepaid cards let us get a product into the hands of real users, who could help us figure out what product features to focus on. — So, about 3 months after the company was formed, we had a couple of dozen live prepaid cards linked to our backend systems and a very, very basic iOS app. We gave Eileen Burbidge, our first investor, one of the very earliest prototype cards and she was so excited about the payment push notifications that she immediately tweeted about it, which led to a Techcrunch article in May (and a reply from the N26 founder saying that it was nothing special 😆) I don’t think we were really ready for the press - we quickly scrambled to get a waitlist up on the website and launched our blog a few days later. In any case, we got so much interest following the Techcrunch article that we doubled down on PR as a strategy. One of my notes at the time said we were aiming to get “Press at fever-pitch”. Eileen seemed to know everyone in the UK press, and I worked really hard to meet journalists and explain what we were trying to build. More press followed over the next few months: We were covered in the Guardian, The Memo, Bloomberg (complete with weird sci-fi photoshoot), Business Insider, Techcrunch again, plus a bunch more. It’s important to note that we had zero real customers at this stage. Just two dozen internal test prepaid cards, a very basic iOS app and a lot of storytelling. I spoke to Kiki recently (now the Director Of Communications at Monzo) about a conversation we had at the time. “I remember you turning up to my office when I was at the Sunday Times, signing me up with a Monzo account and telling me all about your plans to grow the business (and deep fry your Christmas turkey that year!) You invested in forging relationships with the press and that paid dividends for you and Monzo. You were never too important to pick up the phone and explain simple stuff or go for a coffee with a journalist. Something many start-up founders don’t do because they think it’s all about finding angles and firing out press releases.” PR is not a strategy that works for all early stage startups. I’ve been thinking a little about how it worked so well for Monzo in 2015 and 2016. Timing and context were important - the UK press was getting interested in startups (the Social Network movie honestly felt like a tipping point), but there weren’t actually that many successful startups to write about in the UK in 2015. I had started another startup previously, and Eileen, our first investor, was very well known in the tech press, so I guess journalists were interested in covering us. Probably more importantly, it seemed like we were embarking on a bold, ambitious project - to build a new bank from scratch - and we felt like underdogs in the way that the British press loves. So we got a lot of press, and I was the very visible figurehead. I’m pretty sure all that press was the reason for the hype and user signups we got by the end of 2015 - we didn’t have a product live with users, nor did we really have any other meaningful marketing activity that year. Looking back, I’m not sure how I feel about it. At the start, it was exciting to see my face in newspapers and it felt good when my friends and family told me that they’d seen me in an article or on TV. I guess I felt important, and it seemed to drive user signups. It was also a Faustian bargain. When we became a national brand name 4 years later, we were no longer the underdog - we were a big bank that the press could criticise. I’m also not sure it was great for my relationship with my cofounders - we had 5 cofounders at the start, but it was often just my face in the picture. It was impractical to interview or photograph 5 people. They were busy working. Or at least that’s what I told myself. — “Is it a bit early to hire a Head of Marketing?” - conversation with Eileen in June 2015, four months into the life of the company. Throughout June, July and August 2015 we were interviewing marketing candidates. Although the hiring process was slow and frustrating, we learned a lot. We wanted to assess the paid social media ad skills of one candidate, so we had him set up and run 4 small Facebook campaigns. The first three were focussed on product benefits - “Here’s a card that has no FX fees”, “Turn off your overdraft”, “Instant notifications”. They all performed fine. But the fourth campaign outperformed the others by almost 300% - “Help us build a bank you’d be proud to call your own”. This was to become a core part of our marketing over the next couple of years. I eventually interviewed about 10 or 15 candidates, finally picking a woman who had decades of experience at a very large tech company and a UK media company. We hired her as a CMO. Looking back on my notes, all our conversations were about picking the right agency to run PR and another agency to run our paid social campaigns. She was used to running teams that were bigger than the entire headcount of the company at the time. I think she lasted less than 4 months. At the same time, we interviewed and hired a young guy called Tristan as a community manager - he was in his early twenties, he’d graduated in Economics and spent the previous year in Egypt working with a local startup, where he’d picked up Arabic. He’d taught himself web development as a young teenager, and seemed to be extremely hands-on and impact-focussed. Looking back, I think I would have counselled myself to think about what we wanted this person to do for the next ~12 months or so. If you hire a big-name CMO from a large, international brand, they are going to naturally assume there’s a budget to spend on agencies and a marketing team. Even if they talk about being “hands-on” and “scrappy”, that’s probably only true relative to their previous work. For the first 12 months, what we really wanted was someone to write blog posts, respond to social media and edit the copy for our app and website. Tristan was perfect for us because he was representative of our customer base. Young, cosmopolitan lifestyle, socially conscious. He had never employed a marketing agency or really hired anyone at all, so it just didn’t really occur to him to do that stuff. It was just obvious to him that he should write our Twitter posts himself. We made another Head of Marketing hire later in 2016 who also didn’t work out, and from that point onwards Tristan was put in charge of all marketing at Monzo. — Before talking about the launch of the product - the Alpha and then Beta programmes, I want to touch on a couple of things that didn’t work. First, we repeatedly thought about trying to pitch a TV production company to make a fly-on-the-wall documentary about Monzo in the early days. I still think that this might have been a great marketing idea to propel the brand onto a national stage (although may have made the eventual press backlash even harsher), but we just never followed through on it. Maybe it was just a vanity project! We spent more time on a second idea - hackathons and developer relations. A lot of the early team (including me) were software developers and we were really excited about the idea of a bank account with an API. We ran 3 or 4 hackathons early on (even before we had live prepaid cards) and folks came up with a handful of interesting ideas, but we realised pretty quickly that this wasn’t going to be a big growth mechanic. We only got 300 extra users, but it definitely helped hire several early engineers. — We finally got the “Alpha” prepaid debit card programme live to the public by November 2015 - it was a chance for people to get a card, try out the app and give us feedback to help improve the product. We capped the number of customers at 3000 because I think that was the limit for Testflight. There wasn’t even a public release of the app you could download from the App Store. What was the rationale here? The product wasn’t even nearly “complete” - the list of things that were missing before you could call it a full bank account spanned several pages. Customers had to come to an event at our office to pick up the card because we hadn’t yet built the functionality to collect customers’ postal addresses or post out cards. As a consequence, I met all 3000 of these users face-to-face - many of them would turn up to company events for the next 6 years and greet me with a smile. Even though the app wasn’t polished, exclusivity & scarcity was a big part of the strategy early on (drawing on early Gmail launch tactics). I read somewhere that human brains are basically wired to seek out scarce resources and perceive them as more valuable than those that are abundant. Being “in the know” - the first amongst your peers to get access to some new product or service - is a badge of honour amongst early adopters, and we harnessed that. Even the physical cards had “Alpha” printed on them - people would brag years later how early they’d signed up to Monzo. For these people, finding a bug wasn’t an annoyance - it was proof that they were experiencing something at the bleeding edge of development, and they were excited to help improve the product. So we ran with that. This is the first archived version of our website I can find - “We’ve only got 3000 invites for our Alpha Preview. Sign up now to be in with a chance” It turns out this strategy also works on tech journalists. The early preview accounts we gave to Techcrunch and Business Insider journalists led to great coverage. This strategy also let us organise events at a number of London’s top companies. We would promise to come along with 50 or 100 Monzo cards, give a 20 minute presentation during the lunch break, and enable attendees to skip the waiting list. This proved irresistible - I got into companies like Transferwise, McKinsey and the BBC. Much like the hackathons, it didn’t actually turn out to be a very effective way to sign up users, but it was an incredibly strong recruiting strategy. We’d get a flood of inbound CVs a week or two after each talk. Looking back, it’s quite surprising how many major pieces of functionality were missing from the app. You couldn’t make bank transfers or pay bills, for example, because we didn’t yet have access to the payments infrastructure we needed. Instead, we obsessed over the tiny details that we could control - accurate merchant logos that represented your spending, rather than the cryptic data you normally find on bank statements. Jonas (one of our cofounders) first came up with the idea to add emojis to the push notification customers received to alert them about spending. Plane tickets might show 🛫, while spend at a coffee shop would show ☕. I have so many notes from that first year about improving the logos - I even wrote some of the early code to put the right emojis onto transactions. We really cared about making it a delightful experience. Even before we’d opened up the product to the full waitlist, we decided to run a £1m crowdfunding campaign early in 2016. Again, we ran the “scarcity” and “exclusivity” playbooks. We anticipated the round would sell out, so we set up a pre-registration system so that our customers could invest before the general public, and we capped individual investment at £1000 to maximise the number of people who could invest. Along with owning shares in the company, investors would get “Investor” printed on their debit card (and this is still honoured to this day). Investors would also be able to skip the main queue and get access to a Monzo card if they didn’t already have one. The campaign turned out to be a huge PR coup, but mainly for reasons we had not anticipated. Approaching the launch date, we told our crowdfunding partner to expect larger than normal volumes of people looking to invest, as we already had 6500 pre registrations. For whatever reason, they did not take this warning very seriously, and their servers buckled under the load just seconds after the round opened on Monday. This was very annoying and stressful at the time, especially since 6500 simultaneous visitors is not a huge amount of load. We quickly decided we’d rebuild the investment registration page ourselves, and planned to relaunch the campaign a few days later. While our engineers rebuilt the site, we thought about how to communicate this to the press and our customers. It was an absolute gift of a PR story - we had so much demand to invest that the crowdfunding site had crashed. This story ran continually over the next couple of days. By Thursday, the campaign relaunched and sold out in 96 seconds, making it the fastest crowdfunding in history, and the press attention was intense. We ultimately raised £1m from 1861 investors, out of the 6500 people who had pre-registered. In comparison, we only had 3000 cardholders who up to that point had only spent £1m in total on our cards. I’m not sure how repeatable this lesson is - lots of companies have tried crowdfunding since, and it’s no longer newsworthy. I think we had an incredible amount of hype at the time, and we played the scarcity/exclusivity angles well. It also helped that we already had 45,000 customers on a waitlist, and £5m investment committed from Passion Capital - this was an extra £1m investment that normal people could get access to on the same terms as a VC. — Soon after the crowdfunding completed, we announced a public Beta in March 2016, the Alpha having capped out at 3000 users (the Testflight limit). This was 13 months after the company was founded. Anyone (as long as they were an iOS user) could download the Monzo app and see their place in the queue. People could improve their place in the queue by inviting friends to join and a certain number of people at the top of the queue every week would have a card sent out. In the spirit of “doing things that don’t scale”, we figured out a basic system for collecting addresses in the app and posting cards directly from our office. When we had a particularly big week of signups, the whole team would have to stop their regular work to help stuff all the prepaid cards into envelopes to catch the last post. I vividly remember stuffing envelopes at the time, thinking “each of these cards is another person who wants to use our product”. It really felt like customers were signing up faster than we could ship out cards - one of the first indications that we had “product-market fit”. It seemed like we were on the verge of something huge. I think there are a couple of interesting things worth mentioning in 2016 - both related to company values. The first is our name-change. We had been threatened with a trademark lawsuit from a German fintech company which had a similar brand name (we were “Mondo” at the time) and considerably more funding than us. I fought this for several months (against the counsel of my board and investors), before accepting we had to change our name. To make the most of a bad situation, we decided we’d ask our community members - our customers - to suggest new names. The only constraint was that it had to begin with “M” because we had recently designed a great new logo that we didn’t want to give up. Incredibly, bearing in mind we only had around 20,000 customers at the time, we received 12,000 suggestions in about two weeks. 6 people suggested the name we chose - Matt from Bristol had studied a rock called “Monzonite” and another customer, Ashley, told us it was slang for money when he was a kid in Scotland. We hosted a big party and live-streamed the announcement of the new name - Monzo. Predictably, our power-users overwhelmingly hated it, suggesting it sounded too much like “gonzo” (a form of first-person journalism and, later, pornography). It took a little while to stick, but I like it - it sounds much more dynamic and active than “Mondo”, which now feels quite staid to me. The second was our transparent Product Roadmap. In a world where the big banks had huge head offices and enormous marketing budgets, but very little personal trust, we wanted to come across as different. Where big banks were faceless and corporate, we would be human and personal. Where they were impenetrable and secretive, we would be transparent and approachable. So, in May 2016, we announced we’d publish the plans for our product, and take input from our community. In other situations, when things went wrong, we’d proactively tell our users about it and explain what we were doing to fix the situation. Invariably, this transparency generated more customer goodwill and positive PR. These two core values - Community and Transparency - permeated almost everything we did throughout the life of the company. They became a fundamental part of our brand. Prior to Monzo, I didn’t really believe in the concept of “brand” - I thought it was a made-up thing that marketing agencies tried to sell you. And that “brand” didn’t really extend beyond a company’s name and logo. I now believe it can be a superpower for any company - and particularly consumer-facing businesses. There’s been good stuff written about brand-building elsewhere, so I won’t try to recreate it all - I’ll offer just a handful of thoughts. A great brand is like a promise you make to your customers. It’s a shared set of beliefs, or the “why” behind the company. Building your brand is not a one-off thing; you build (or damage) your brand with every decision you make. Events like crowdfunding and the company rename were perfect examples to reinforce the brand. It has to be authentic - a lot of big banks’ marketing towards younger customers felt really painful. Monzo, in contrast, felt human and relatable. And when a brand really resonates with a customer, it becomes an extension of their identity. I wear Patagonia. I drive a Tesla. I use an iPhone. I bank with Monzo. I think a lot of customers were proud to pull out their Monzo card and feel like they were part of something. In the UK, at least, Monzo has become a verb. — We grew from about 3,000 users at the start of 2016 to 70,000 by year-end, which seemed pretty good, but I think we realised in the summer of 2016 that our strategies so far weren’t going to scale to drive the kind of continued growth we ultimately needed. So, towards the end of the year we really started to think about product features with network effects, and referral mechanics. Pretty quickly, this became “Monzo with Friends” - we aimed to build a product that worked better and better as more of your friends joined. We started working on ideas, but nothing really launched until early 2017, so I’ll talk about this more in the next section. Before that though, here are two things that failed in 2016. First was the idea of “Campus Insiders” - university students that we employed to represent the Monzo brand and sign up new customers. They required a lot of babysitting and delivered no measurable impact, as far as I can tell. One of our early ideas was to have a custom Monzo card for each university - similar to how we had “Alpha” and “Beta” subtly printed on the corner of the card. Students might get Monzo “Oxford” or Monzo “Birmingham” if they signed up with a student email address. This could have maybe extended into discounts at local shops, but it seemed like too much work and we never followed through with it. The second was a campaign to work with local businesses in the Old Street area of London in the run up to Christmas. I think we had folks out flyering and offering discounts in local shops, but again it was a lot of manual work with no discernible impact. — 2017 was the year of product-driven growth. We had a slide in several of our early investor presentations that said “Viral mechanics will get us to the first million customers”, but investors overwhelmingly didn’t believe it. We set out to prove them wrong. I’ll make a distinction between two related ideas - viral mechanics and network effects. A “viral mechanic” normally uses the existing customer base to spread the product to friends. It’s sometimes called “member-get-member”, and it can be incentivised or free. An example is the way Wordle allowed you to post your “score” to social media. Other people see it and sign up for Wordle themselves. The game isn’t really improved in any way by having your friends join - they’re just curious to check it out. Gmail used a viral waitlist + invitation mechanic in the early days - again, your experience of Gmail wasn’t really improved if you convinced your friends to switch from Outlook. A network effect is different - the product itself actually improves as more of your network joins. Whatsapp and Skype are great examples. The more of your friends who join, the more people you can communicate with for free. That was a big hook at a time when people paid for SMS and international phone calls. Great products have both network effects and viral mechanics. Facebook’s early photo tagging is an example. “You’ve been tagged in a photo” email - prompts you to sign up for Facebook, see the photos you’re in, upload your own photos, tag more friends, repeat. The network gets more valuable and drives more growth as more users join. At Monzo we had both of these, and 2017 was the year they really took off. I’ll talk about “Golden Tickets” first - a silly allusion to the Willy Wonka story. We had a pretty big waiting list at this point, but the “Invite friends to get bumped up the queue” felt a little old and ineffective. People who wanted an account enough would just create a bunch of throwaway email addresses. We figured that the best people to be making referrals were those who were already actively using the product. Presumably they liked it enough because they kept using it, and they’d all had the experience of having to wait in the queue, so they perceived a Monzo account to be both scarce and valuable. Rather than paying our users to refer friends like most apps did, we decided that once you’d used the account for about two weeks, we’d send you a single “Golden Ticket”. This was a one-time-use invitation that you could send to one friend to enable them to skip the queue entirely and get a Monzo account straight away. You can think about the psychology by analogy - you’ve queued all afternoon to attend a cool new event in your city, you’ve just managed to get in the door, and you’ve been able to talk the bouncer into getting your friend a queue-jump ticket. You get the early-adopter social credibility of having known about the event before your friends, plus you’ve done your friend a favour by getting them access. It just worked incredibly well - about 40% of our signups in 2017 came from Golden Tickets, and it cost us nothing. Second, “Monzo with friends” was our drive to make Monzo work better if you invited your friends to use it. This might sound obvious now, but I can’t really think of any other bank that had previously done this, beyond suggesting you get a joint account with your spouse. If you used Barclays and your friends used Natwest, there was no change in how useful the account was, right? We wanted to change that. We started with peer-to-peer payments, based on the contact-list of your mobile phone. For US audiences, this was Venmo, but inside your bank account. UK banks already allowed you to pay any other UK account holder instantly, for free, but you needed to know their account number and sort-code, and the interface was really clunky. It basically worked, but it wasn’t a delightful experience. We asked people to share their phone contact lists (using some clever encryption so that we’d never actually saw your friends’ mobile phone numbers), and then allowed you to pay your friends on Monzo with just a couple of taps. For contacts who weren’t on Monzo, that’s where Golden Tickets came in! It was a really slick interface, and we allowed you to include longer-than-normal messages with the payment, including emoji. Later that year, we added “Reactions” - if you’d received money from a friend, you could send a quick response - just a single emoji. This was just a quick way of saying “thanks, payment received”. And we let people quickly upload profile pictures to make it feel more personal. We then added “Split the bill” functionality for a single payment, plus a more general “Request money” feature, and finally more complex “Shared Tabs” for multi-day trips away with friends and family that might include dividing several payments. If your friends weren’t on Monzo, you could still request money with your personal Monzo.me link, which would allow folks to pay you using another bank card or Apple/Google Pay (and Monzo covered the transaction fees), and included a little upsell for Monzo at the end. Mine is https://monzo.me/tomblomfield. If you clicked on this link with a Monzo app installed, it would just deep-link straight into the Monzo account with all the payment information pre-populated. Alternatively, if you went for dinner or drinks and wanted to split a bill with someone who already had Monzo, but who wasn’t in your phone’s contact list, you could securely broadcast your account details by bluetooth, so you could pay each other without having to type in any account information. It’s an incredibly slick experience that I am proud of to this day. Peer-to-peer payments drove massive adoption - time and time again we saw Monzo take hold in a new group of friends and then quickly spread to the entire group. At the start of 2017, only 5% of our users had 10 or more friends on Monzo. By the end of 2017, more than 40% of our users had 10+ friends on Monzo. Today, the average Monzo user has more than 100 friends on Monzo. This is network effect in full force. 2017 was also the year that we really got a handle on our metrics - particularly retention. There are much more complete retention guides out there, but I’ll give a quick summary here. Say 100 users sign up for Monzo, complete KYC, register a card and load money into the account. That’s the denominator - 100 funded accounts. Fast forward say three months - how many are still using the account? Maybe 60? That’s the numerator. So we have 60% (60/100) retention at Month 3 (or day 90). You can draw a curve to show how quickly retention falls off day by day since signup. What does “still using the account” actually mean? We decided to count “at least one financial transaction in the 7 days” would make you a Weekly Active User (WAU). “At least one financial transaction in the preceding 30 days” would make you a Monthly Active User (MAU). Clearly, a WAU was more engaged than a MAU. I dug out our stats for 2017 - about 60% of our signups were WAU on day 90. These retention rates still strike me as surprisingly high, especially considering that every user had to proactively add money to the account every time they ran low on funds. This wasn’t (yet) a bank account where you sort of “defaulted” into retention once a customer set up the account - users could not deposit their salary into the account until 2018, and there was no auto-top up functionality. Monzo started 2017 on 70k users and ended the year on around 650k - averaging just under 5% compounding weekly growth for 52 weeks of the year. So why did it grow organically and retain so well? First of all, I think the day-to-day product experience (for all its functional limitations) was world-class - it was a delight to use, especially compared to the clunky old banking apps in the market. Without that, basically nothing else would have mattered. The customer service was also exceptional - this was often mentioned in our NPS surveys (NPS was around +70 at the time). Secondly, I think the brand we had started to build really resonated with people. Our mission and values (mainly transparency and community) seemed to strike a chord with customers. Even the card itself was visibly different to traditional banks. The Monzo card was “hot coral” (aka bright pink) - the colour alone often started a conversation when customers pulled it out of their wallets to pay. Our tone of voice was youthful, direct and extremely personal. By 2019, Monzo was the single most recommended brand in the UK. And third, the network effect really started to kick in - if you had 3+ friends on Monzo when you joined, you had a 70% chance of being a WAU by day 90, versus only a 50% chance if you didn’t have any friends on the platform. As a result of these things, Monzo hit 1 million customers in September 2018, without having spent any significant money on marketing. — This feels like a good place to draw this chapter of a story to a close. There are other topics I’d like to write about - getting a full UK banking licence, fixing unit economics, and spending money on paid advertising to catapult the bank from 1m to 4m customers - but they will have to wait for another time.
More in startups
We Live in the Dependently Typed Future Now In the thirty-four days between the fourth of September and the seventh of October, the following things happened. Claude formalized Fermat's Last Theorem in Lean. OpenAI announced a finite-time blowup for the Navier-Stokes equations, found by ten thousand agents in eighty-eight hours, with a Lean formalization attached. A model proved Khot's Unique Games Conjecture. Another multiplied two integers faster than \(n \log n\), with an exponent improvement of \(2^{-182}\) (so maybe don't expect it in GMP anytime soon!). The rational Hodge conjecture fell for CM abelian varieties. Then OpenAI dumped 722 new maths papers on GitHub on a Tuesday. And it's only been a month. The question everyone is asking now is how long until the Generalized Riemann Hypothesis folds to the swirling pool of tensors? Sixteen months ago I wrote that the future of maths may be deeply weird, and then, welp, just like that we're here now in that weird future. And it's f'ing awesome. Somewhere in a data centre there is now, more or less permanently, a building full of accelerators working the truth mines at the frontier of mathematics, just like in Greg Egan's sci-fi novel Diaspora, tunnelling outward from the three axioms propext, Quot.sound, and Classical.choice, and hauling results back to the surface around the clock. OpenAI posed its model roughly four thousand problems at an average of three hours of thinking each, and that is the slow, artisanal, normie-friendly version. The industrial version doesn't stop. It will produce results faster than any human community can read them, many of them correct, some of them important, and a growing fraction of them inscrutable. True (for some twisted philosophical definition of truth), machine-checked, and understood by no one. Human understanding of mathematics is about to become a luxury good. Whatever else this world needs, it needs something that can tell the true results from the confabulated ones at the rate the models produce them, and right now that something is dependent types, namely Lean. Let me dwell for a moment on how strange it is that this is the shape the future took. I spent a good portion of my twenties around the London FP community, where dependent types were the thing we talked about over pints at the Crown Tavern in Clerkenwell (some of you will remember). Types that could depend on values, so that a function's signature could say not merely "returns a list" but "returns a sorted permutation of its input," and the compiler would hold you to it. Curry-Howard, the observation that proofs are programs and propositions are types, was the foundational north star. The pitch was always that one day we would write software against specifications and the machine would check them, and the reply was always that this was a lovely idea for people with tenure and no deadlines. Dependent Haskell has been "a few years away" for about fifteen years. Idris and Agda remained boutique. Software engineering still mostly runs on C++, prayer, and the occasional dark incantation. And then the dependently typed future arrived anyway, through the back door. Mathematics and reinforcement learning got there first. It turns out the killer application for a dependently typed language was using its typechecker as a reward function. A type checker is an oracle that says yes or no to a candidate proof with no partial credit and no opinions, and that is precisely what you need when you want to point a very large optimiser at an open problem and let 'er rip. The thing we dreamed about at the pub is now critical infrastructure at frontier labs, and every one of the results above is, in the end, a claim that a type checker returned true. Which is why we need better tooling, and we need it ASAP. The dependent type renaissance is here and the golden age of formalized mathematics is upon us, but the inner loops of these data centres now run dependent type kernels day in and day out, elaborating, checking, discarding, and retrying at breakneck speed, and the thing that certifies their output should run at the same speed. If the search runs at microseconds and the verification runs at minutes, the verification becomes the bottleneck, and bottlenecks in trust have a way of being quietly skipped. We should not be in a position where the most important epistemic question of the decade, "is this proof actually correct," is answered by whichever checker happened to be fast enough to keep up. Breaking the Mathlib Minute Barrier Just like the four-minute mile, which went from physiological impossibility to something club runners now train for, formal mathematics has had its own barrier for a while, which is type-checking all of Mathlib from scratch in under a minute. That now turns out to be quite tractable. nano-lean is a minimal, but complete, type checker for the Lean kernel language, written in Rust on top of my unbound binding library for doing efficient de Bruijn indices for binders. It reads an export of a Lean environment and independently re-checks every declaration from scratch (inductive types, positivity, recursors, quotients, universe levels, projections, structure eta, all of it). It checks all of Mathlib, 718,577 declarations, with zero errors and zero timeouts in 16.7 seconds on an Apple Silicon M5 Max. A surprising amount of that speed comes from not parsing text. The standard way to get declarations out of Lean is lean4export, which writes one JSON object per line, and parsing gigabytes of JSON turns out to be a large share of the cost of checking anything. So nano-lean's companion tool olean-export reads the compiled .olean files directly, decoding modules in parallel, about a hundred times faster than lean4export on a Mathlib-dependent library, and it can emit blean, a new binary format designed for fast mmapping. Blean is the same record stream as the NDJSON export, in the same order, with nothing left to parse. Every record is a compact postcard encoding, ids are implicit and dense, records only refer to earlier ids, and each expression carries its precomputed hash. The checker mmaps the whole file, tells the operating system it will be read once front to back, and decodes names, levels, and expressions straight off the mapped bytes into its term arena. There is no parsing step at all. The bytes on disk are already very nearly the shape of the data in memory, which is how you check Mathlib in under a minute. -j 1 -j 10 Wall time 57.4 s 16.7 s Kernel check 53.5 s 12.5 s Peak memory footprint 7.5 GB 9.2 GB The same trick works on the frontier results too. Here is nano-lean checking the full imported environment of OpenAI's Navier-Stokes and Euler proofs on an M5 Max. -j 1 -j 14 Wall time 83.58 s 17.13 s Kernel check 78.83 s 12.11 s Peak memory footprint 10.14 GB 12.29 GB Divide Mathlib's kernel time by the declaration count and you get an amortised seventeen microseconds per declaration. That is the number that matters, because it is the right order of magnitude for a checker that lives deep inside an RL-driven search loop, where it gets called hundreds of billions of times, instead of sitting at the end of a release pipeline. The entire library of human-formalized mathematics, the product of a decade of volunteer effort, is re-verified in less time than it takes to make an espresso. I also happened to have an m2-ultramem-416 lying around on Google Cloud (416 vCPUs and 12 TB of RAM, as one does), so naturally I pointed nano-lean at it. Yes, it breaks the two-second Mathlib barrier. But Amdahl's law sends its regards, and the curve flattens out hard somewhere past a hundred cores, as the dependency graph runs out of independent work to hand out. Mathlib, it turns out, is too small. I look forward to the day a future Mathlib, or something like Tau Ceti, grows big enough to actually saturate this machine. That's the real future! I wrote it to make a point about where the bottleneck has moved. The kernel is now the hot loop of a new kind of scientific economy, and hot loops deserve to be engineered like hot loops. The whole bargain of formal proof is an asymmetry. Finding a proof can take three hours of frontier-model thinking, or eighty-eight hours of ten thousand agents, but checking it should take microseconds. That asymmetry is what makes it reasonable to trust a result no human has read. It only holds if the checker actually scales, and with Fermat's Last Theorem now weighing in at five times the size of Mathlib, scale is no longer a hypothetical. Mathlib is the small library now. Caveat emptor, though. nano-lean is a proof of concept, built to show that it can be done with the right amount of low-level Rust-fu. That said, we do use it internally at OneChronos to check our larger Lean proofs of market infrastructure, which have grown quite excessive. It is nowhere near as trustworthy as the official Lean kernel, which has years of scrutiny, a community of experts, and every Mathlib build ever run behind it, and which takes around fifteen minutes to check the same library. The claim is narrower and, I think, more interesting. Checking at this speed is totally possible, so we should stop treating minutes as the natural cost of trust and start building checkers that are both fast and trustworthy. A future version of the Lean compiler could be as blazing fast as rustc or clang. The Shape of the Future In my previous post last year I predicted that mathematicians would come to look more like software engineers working through pull requests on GitHub than like Andrew Wiles toiling in his attic. The largest single release of new mathematics in history shipped as a GitHub repository, with a CONTENTS.md, a Lean library, a lean-toolchain file pinned to v4.34.1, and a promise that "corrections and revisions will be recorded as new versions." So, yup, that happened. I predicted that an AI system would be unleashed on a list of formalized open conjectures in an attempt to systematically push the frontier. Four thousand problems, three hours each. Check. I predicted a data centre tasked with the Riemann hypothesis that would come back after weeks with a proof no human could follow. What we got was the quasi-Riemann hypothesis, every Dirichlet \(L\)-function zero-free in \(\Re s > 7/8\), with a Lean page, which is the sort of near miss that would be funny if it weren't so unnerving. And the inscrutability has arrived on schedule. OpenAI released "reasoning summaries" for ten families, which turn out to be summaries of excerpts of reasoning traces, two removes from anything the model actually did. I joked that the million-dollar Millennium Prize might cover a hundredth of your GPU bill. The Navier-Stokes run reportedly consumed around 130 billion tokens. So definitely yes. What I got wrong was the timing. Last year I wrote "we're not there yet. Not even close." It was sixteen months. I probably got the chess analogy wrong too. I argued that, as with Stockfish and chess, machines would make mathematics more popular and more accessible rather than less. Maybe in the long run. In the short run the mood among working mathematicians is closer to existential crisis, and the open questions are about career pipelines, PhD students getting scooped by a press release, and the concentration of the most powerful mathematical instrument ever built inside a handful of private companies running unreleased models. What I missed entirely is that the bottleneck would turn out to be plumbing. I spent paragraphs on Gödel and the epistemology of inscrutable proofs, and the actual first-order problem is that the OpenAI Lean library is over a gigabyte of source across tens of thousands of files, and their README has a section warning that building it may fail because Linux's vm.max_map_count is too low, with a suggested workaround of recompiling Lean with -DMMAP=OFF. The philosophy is still there. But the frontier of mathematics is currently being held up by a kernel tunable. Which isn't the future we wanted, but maybe it's the future we deserve! Who Checks the Checkers The obvious objection to everything I've said so far is that a Lean proof is only as trustworthy as Lean. And that's very true! Lean, like every proof assistant, has a small trusted kernel and a very large untrusted everything else (the elaborator, the tactic framework, the compiler, the build system). The design is sound. The only code that has to be correct is the kernel, which is small enough to read. But "small enough to read" describes the source code. It guarantees nothing about correctness, and Lean's kernel has had soundness bugs before, as has every kernel of every proof assistant in history. Historically that was tolerable, because the adversary was a starving human grad student who wanted their proof to go through and had no interest in hunting for a way to make False typecheck. That assumption is now obsolete. I wrote last month about reward hacking, the habit optimisers have of satisfying the letter of an objective rather than its intent. An agent told to make a Lean file compile, with enough compute and enough attempts, is an extremely diligent fuzzer pointed at your kernel. It needn't want to cheat. It only needs to stumble on a term that the checker accepts and shouldn't, once, and then the gradient does the rest. When the provers are adversarial optimisers, a single kernel is a single point of failure, and a soundness bug stops being an embarrassing GitHub issue and becomes a mechanism for manufacturing fake theorems at scale. The answer is the same one the compiler world arrived at. When Csmith started generating random C programs and compiling them with several compilers to compare the results, it found hundreds of bugs in GCC and LLVM that decades of ordinary use had missed. Diversity plus differential testing beats any amount of careful review of a single implementation. For proof checking this means multiple independent kernels, written by different people in different languages with different representations, all consuming the same export format and all required to agree. Mario Carneiro's lean4lean and Chris Bailey's nanoda were early here. nano-lean ships a third tool, nl-mutate, which takes a valid export, applies small semantics-breaking mutations to it, runs every available checker, and reports any disagreement, shrinking each one down to a minimal reproducing case. Every disagreement is either a bug in someone's kernel or a spec ambiguity in the type theory, and both are worth knowing about before a GPU farm finds them for you. The other half of trust is the statement. A perfectly checked proof of the wrong theorem is worthless, and the most effective way to cheat a proof checker has never been to break the kernel. It's to quietly weaken the statement until the thing being proved drifts away from the thing anyone cares about. OpenAI's repository leans on Comparator, which checks a submitted proof against a separately specified challenge statement inside a sandbox, precisely because this is where the real trust boundary now sits. Anyone who has watched a model grind away at a stubborn goal knows it has a nasty tendency to cheat in the most boring ways available. It will quietly introduce an axiom that happens to be exactly the lemma it needed, leave a sorry buried three files deep, redefine a notation or macro so the statement on the page no longer means what it appears to mean, or reach for native_decide and drag the whole compiler into the trusted base. The kernel stays perfectly sound through all of this, because these tricks route around it, and the only defence is to pin the statement down independently and check what the proof actually depends on. Someone has to formalize the conjecture, and someone has to check that the formalization means what the English means. That job will outlast every other part of the process. If anything, it is where human mathematical taste migrates to, away from writing proofs and towards writing and auditing specifications. The proof becomes an implementation detail. The theorem statement becomes the interface. If you want to see the seed of what this looks like as a way of working, look at Tau Ceti, a Lean library downstream of Mathlib. The division of labour is the whole point. Humans write the roadmaps, as markdown in a separate repository, and humans write the review rubrics. AIs write all the code, open the pull requests, and shepherd them through an AI-driven review process. The rubrics are explicitly adversarial, with instructions to hunt for mis-formalizations, vacuous statements, and "pushing around the lump in the carpet." What Lean Needs Now Lean is a superb piece of engineering. But it was designed around a particular user, a starving grad student typing tactics in Emacs, waiting for the infoview to update, building a library at the pace a community of volunteers can review pull requests. The user is now a swarm of agents writing thirteen million lines in eleven days. The tooling has to grow up for its new authors, and the list of what that means is fairly concrete. A surface formatter. Lean still has no canonical, widely adopted formatter in the spirit of rustfmt or gofmt, and when your authors are agents producing millions of lines, every one of them invents its own indentation, line breaking, and tactic layout. Diffs fill with noise, reviews get harder, and deduplication across agents misses proofs that differ only in whitespace. This is a surprisingly hard problem, because Lean has grown into a very large language. Its grammar is extensible at runtime, so notation, macros, and entire tactic languages declared in imported files change how later files parse. A formatter cannot just read a fixed grammar. It has to load the environment, run the real parser with every syntax extension in scope, and then pretty-print a syntax tree whose shape depends on user-defined notation, all while round-tripping comments and never changing what the code means. It is a genuinely difficult piece of engineering, and it is now table stakes. A stable, specified export format as a public interface. Independent kernels are only possible if there is a well-defined way to get declarations out of Lean without linking against the C++ runtime and reading the oleans by hand. Tools like lean4export and olean-export already produce NDJSON, and blean shows that a binary form of the same stream, designed to be memory-mapped, can make the export nearly free. OpenAI's own verification instructions depend on lean4export. That format should be treated with the seriousness of a wire protocol. Versioned, documented, specified down to the hashing of expressions, and stable across toolchain releases. The export format is the boundary across which trust is established. It deserves a spec. Independent checking as a first-class citizen. Running a second kernel should be as normal as running the linter. Mathlib CI, the Comparator workflow, and any lab publishing formal results should re-check exports with at least two unrelated kernels and refuse to bless anything they disagree on. This is cheap, now that checking all of Mathlib costs less than a minute. Checkers as libraries, not just executables. The inner loop of a proving agent wants to submit a single candidate declaration and get a verdict back in microseconds, against an environment that is already loaded and hot. Process startup, re-reading oleans, and re-deserializing a few gigabytes of environment are costs that never mattered when a human hit save once a minute. They dominate when a search procedure checks a million candidates an hour. The kernel should be embeddable, with a persistent environment, incremental addition of declarations, and an API that a search harness can call in a tight loop. Memory and scale. Mathlib needs several gigabytes of memory to check. The FLT formalization is five times bigger, and OpenAI's library is already knocking over Linux virtual memory limits. Lean mmaps every imported module, which is a reasonable design for a library of thousands of files and an unreasonable one for hundreds of thousands. Term sharing, hash-consing across modules, compact on-disk representations, and lazy loading of exactly the declarations a proof depends on are the boring, unglamorous engineering problems that decide whether formal mathematics scales to the next order of magnitude. Elaboration is the real cost. The kernel is the fast part. The expensive part of building Mathlib from source is the elaborator, with its unification, typeclass resolution, simp, omega, decide, and the long tail of tactics. A cold build is still measured in CPU-hours, and a mining operation that elaborates candidate proofs at scale pays that cost over and over. Parallel and incremental elaboration, better caching of typeclass instances, and profiling tools that can tell you why a single simp call took four seconds are where most of the wall-clock time in a proving loop actually goes. Clippy-style linters. Mathlib already has a good set of linters, but agents need something closer to Rust's clippy, a large, opinionated catalogue of lints aimed at the specific ways machine-written Lean goes wrong. Flag the stray axiom, the buried sorry, the unnecessary native_decide, the forty-line simp only that should be a lemma, the theorem whose hypotheses are contradictory and therefore vacuously true, the local notation that shadows something standard, the copy-pasted proof that duplicates one already in the library. Each lint should be cheap, machine-readable, and come with a suggested fix, because the consumer is a search loop that will act on every warning, where a human would skim them. Linters are how you encode taste at scale, and taste is the thing agents most conspicuously lack. Search at machine scale. Moogle, Loogle, and LeanSearch were built to help humans find the lemma they half remember. Agents need the same thing but at a scale where the library grows by millions of lines a week, and where most of what's in it was written by other agents and has never been looked at by a person. The Prove2Me platform Anthropic used for FLT keeps a DAG of theorem statements with natural-language descriptions precisely so that agents can find and reuse each other's work. That idea, a living, searchable index of everything proved so far, needs to become shared infrastructure instead of something each lab rebuilds privately. Provenance. The current generation of models is notoriously bad at citing the literature for the techniques it uses. A proof term knows exactly which lemmas it depends on but nothing about where its ideas came from. If machine-generated mathematics is going to be integrated into the human literature rather than sitting beside it like an unread appendix, proofs need to carry their history (which model, which run, which prior results, which human-written papers the argument leans on). None of this is terribly exotic. It's the kind of infrastructure that every other field which industrialised went through. Compilers got test suites and multiple implementations, network protocols got RFCs, databases got formal isolation levels and Jepsen. Proof assistants are the newest member of that club, and they are being industrialised faster than anything before them. If I were a young, ambitious programmer, this is where I would be focusing my early career for the highest return on investment. Curry-Howard for the Real World The dependently typed future I was promised at the pub was one where software would be written against specifications and machines would check that it met them. What we actually got is stranger. The specifications are theorem statements, the software is proof terms, the authors are swarms of agents, and the thing being built is the frontier of mathematics itself. Curry-Howard turned out to be industrial infrastructure after all. It just took reinforcement learning to get us there. And this is only the mathematical half of the story. The same machinery that just checked Fermat's Last Theorem will check anything you can state precisely, and the most obvious next customer is industrial software. I argued last month that software sucks because almost nothing we ship has a specification, let alone a proof. That excuse is evaporating. If an agent swarm can produce thirteen million lines of verified mathematics in under two weeks, we're not far from applying the same techniques in software engineering. The labs are mining mathematics first because it is the cleanest verifiable domain, with no messy real-world spec to negotiate. Software is next, and it will need all the same tooling, namely fast kernels, diverse checkers, honest statements, and infrastructure built for authors who never sleep. So yes, the future of maths turned out to be deeply weird, and much sooner than I expected. The results are piling up faster than anyone can read them, and many of us will spend the rest of our careers trying to understand theorems that were proved before breakfast by something that cannot explain itself. I find that unsettling, and I also find it thrilling. One final shameless plug. If you'd rather work on the frontier of mathematical formalization than read blog posts about it, OneChronos is hiring Formal Methods Engineers. We build institutional markets out of combinatorial auctions (descended from the Milgrom and Wilson 2020 Nobel Prize), which turn out to be precisely the right mathematical formulation for a world where the bidders are increasingly reinforcement learners with very exotic expressive preferences. Our dark pool processes more than 1% of notional U.S. equity market volume, and we've already expanded into many other global asset classes. You'd be joining our new formal methods team, working alongside mathematicians and market structure experts, writing Rust and Lean. Dependent types, numerical optimisation, and Lean applied to moving hundreds of billions of dollars safely every day. If you're that kind of nerd, hit us up.
Calls for a new kind of slowdown were the talk of The Curve. PLUS: Slinking back to X
Figure out what you actually want. Find a game that's worth winning. Then be honest with yourself: are you going to be the person who wants it the most?