Blog

  • Is the SaaSpocalypse real, or is it just a squeeze?

    Is the SaaSpocalypse real, or is it just a squeeze?

    There is a lot of noise right now about the SaaSpocalypse. Depending on who you listen to, AI is either about to destroy the software industry as we know it, or this is just another market panic dressed up as a technology story.

    I’ve spent close to 30 years building software, and much of that time has been spent building and managing products used by millions of people. So I’m not particularly interested in looking at this as a stock market story, or making dramatic predictions about every large SaaS company suddenly disappearing. I’m more interested in looking at it from the builder’s side.

    The squeeze starts below the enterprise tier

    To me, the interesting part of the SaaSpocalypse isn’t whether the biggest enterprise platforms survive. Big companies don’t rip out core systems just because a new tool exists. There are processes, integrations, procurement, compliance and, most importantly, a lot of people wrapped around how things already work. Replacing the software is one thing. Changing the way hundreds or thousands of people work is something completely different.

    What’s more interesting is what happens below that layer. What happens to the small tools, the narrow products, the things we bought not because they were impossible to build ourselves, but because building them was annoying, time-consuming or simply not worth it? That’s where I think the SaaSpocalypse starts.

    Software with an expiry date

    In workplaces and groups of friends, we constantly create small, temporary needs for software. Maybe there’s an office darts tournament. Maybe it’s some internal competition. And every major sporting event, such as the World Cup 2026, inevitably creates prediction pools between friends and colleagues.

    A few years ago, you’d find a SaaS product that was close enough to what you wanted. It probably wouldn’t do exactly what you wanted, but it would do 90% of it. You’d pay $15 a month because that was insignificant compared with the time it would take to build something yourself. Then you’d adapt to the product. Maybe your group wants to predict which player will score the most goals for Sweden. If the product doesn’t support that particular bet, you don’t have that bet. That’s just how it works. The product defines what you can do.

    With AI, that changes. Now I can describe exactly what I want. I can define the scoring system, the rules, the bets and the leaderboard. If someone comes up with another ridiculous prediction halfway through the tournament, I can add that too. Suddenly I’m the product manager.

    The application exists for exactly as long as I need it. We run it during the World Cup, declare a winner after the final, and then I can simply shut the whole thing down. There’s another small detail here that I think is worth mentioning: subscriptions. There is probably a surprisingly profitable long tail of people paying $10 or $15 a month for SaaS products they originally intended to use for a few weeks and simply forgot to cancel. Disposable software doesn’t have that problem. When the reason for the software disappears, the software can disappear with it.

    Software for a single room

    I see the same thing when I do public speaking or run workshops. Sometimes I want a live poll, a Q&A board or some other way of interacting with the room. Previously, that meant spending time researching which products were available, comparing their pricing models, figuring out which features were included in which tier, and eventually signing up for the one that came closest to what I wanted. Again: closest. It rarely fits exactly.

    Today, I can build something specifically for that presentation or workshop. I can decide exactly how people interact with it, what gets displayed on screen, how the results work and what happens with the data afterwards. It can be completely customized for that particular room and that particular session. And if I need to keep the responses afterwards, I export them into a data-readable format and move on. The software itself doesn’t necessarily need to survive the meeting.

    Do I still need Mailchimp for this?

    There’s another category where the calculation is starting to change for me. Let’s say I have a product and I’ve just released a new feature. I want to email the users and tell them about it. Historically, I’d probably reach for something like Mailchimp. That means getting the users into another system, giving their email addresses to another third party, setting everything up there and then using their tooling to send the update.

    There were good reasons for doing that. Building even a basic email system yourself meant spending time on infrastructure instead of the actual product. But that calculation is different now. For a relatively simple product update, I can use Amazon SES for delivery. I can handle bounces, keep a small data store for unsubscribes and send history, and put a simple admin interface on top. Then I send the update. Done.

    I’m not arguing that this replaces every use case for Mailchimp. It obviously doesn’t. But for the smaller use cases, something important has changed. The question used to be: “Which SaaS product should I buy so I don’t have to spend several days building this?” Increasingly, the question is: “Would it actually be faster to just build this?” And sometimes the answer is now yes.

    Why developers run this calculation differently

    I know my perspective isn’t that of the average software buyer. I’ve been building software for years, and over time I’ve naturally moved through a lot of the pieces around it: development, DevOps, infrastructure, product management and understanding customer needs. I genuinely enjoy all of those things. Each piece is interesting on its own, but together they give you a pretty good understanding of how the whole system works.

    So when I look at a small SaaS product, I don’t just see the interface. I see the pieces behind it. If it’s an email tool, I see something like SES handling delivery. I see bounce handling, a small data store for unsubscribes and send history, a simple admin interface and some logging so I know what happened. None of that is magic. It’s work. And historically, work was exactly why I paid for SaaS products.

    I knew I could build these things myself. The people around me knew they could build them themselves. But why spend several days, or perhaps several weeks, doing that when somebody else had already solved the problem for $15 a month? We weren’t necessarily paying because the technology was difficult. We were paying to save time.

    That’s the part AI changes. Something that previously wasn’t worth spending several days building can now sometimes be built in a couple of hours. And once I’ve built it, I own it, I can change it and I can reuse it.

    I’m probably a little unusual in how broad my technical background is, but I’m far from unique. There are a lot of developers, technical founders, product people and small teams who understand enough of the stack to look at a SaaS product and think: “I could build the version of this that I actually need.” The reason we didn’t was time. And that time-saving advantage is rapidly disappearing.

    So, is there really a SaaSpocalypse?

    Probably not in the way it’s being portrayed in the headlines. Salesforce isn’t going to disappear tomorrow because somebody figured out how to vibe-code a CRM over the weekend. Enterprise software has decades of processes, integrations, data and people wrapped around it. Replacing that is a very different problem.

    But there is something real happening further down. For a whole class of smaller SaaS products, particularly products solving narrow problems or problems with a short lifetime, the economics have changed. The first products to feel that aren’t necessarily the biggest or most complicated ones. They’re the products we bought because $15 was cheaper than spending two days building the thing ourselves.

    AI is attacking that equation directly. Maybe the SaaSpocalypse isn’t really an apocalypse. Maybe it’s a squeeze. And I suspect we’re going to see money gradually move away from small convenience SaaS products where the primary value proposition was simply saving us the time required to build them ourselves. Because for developers and technical teams, that time is getting very, very cheap.

    So, what do you think? Is the SaaSpocalypse real, or are we simply seeing the economics of small software change? I’d love to hear your take. Leave a comment below, or find me on X or Bluesky.

  • What if the next programming language isn’t for us?

    What if the next programming language isn’t for us?

    We’ve spent decades optimizing programming languages for humans. Nicer syntax, higher-level abstractions, better type systems and better tooling, all in service of human authors. But something is shifting. Increasingly, we describe what we want and AI writes the code.

    If that continues, there’s a question I can’t shake: if AI becomes the primary author of software, why would the next programming language still be designed for us?

    The optimization target has changed

    For most of the history of software development, the programmer has been human. That has shaped almost everything about the languages we’ve created. Readability matters because humans have to read the code. Syntax matters because humans have to write it. Abstractions matter because humans need to reason about increasingly complicated systems. AI doesn’t necessarily need those things in the same way.

    It doesn’t get tired reading verbose code. It doesn’t need syntactic sugar to save a few keystrokes. It doesn’t forget an API because it hasn’t used it for six months. If AI eventually does most of the actual authoring, then it seems reasonable that the things we optimize a programming language for will change as well.

    And if the optimization target changes, I think the language itself eventually changes with it.

    We’ve moved the abstraction before

    We’ve seen shifts like this before, although the comparison isn’t one-to-one.

    Assembly wasn’t designed to be pleasant to read. It maps closely to the underlying hardware and gives the programmer very direct control over what the machine does. As software became more complex, languages like C gave us a higher level of abstraction while still staying relatively close to the machine. From there, we kept climbing.

    The important part isn’t that an AI-native language would somehow be the new assembly. It probably wouldn’t look anything like assembly. The interesting parallel is that programming languages have always reflected what we’re trying to optimize for. Assembly was close to the CPU. Higher-level languages increasingly optimized for the humans writing software. So what happens when the primary author changes again?

    A programming language for AI

    I suspect the first truly AI-native programming language will look strange to us. Human readability might barely matter. Instead, the language could optimize for things such as unambiguous structure, deterministic behavior, rich metadata and the ability to compile efficiently to many different targets.

    The same language, or representation, could potentially target a browser, a server, a mobile device or a compiled desktop application. Portability wouldn’t necessarily mean bringing the same runtime everywhere. It could mean giving the AI one representation from which it can reliably produce software for whatever environment is required.

    There might still be humans who understand it, just as there are humans today who are perfectly comfortable reading assembly. But most developers wouldn’t need to. Because we wouldn’t be the ones writing it.

    Intent and architecture

    That doesn’t mean developers disappear. I think our role moves another level up the abstraction ladder.

    We spend less time describing exactly how software should be built and more time describing what we want built. But intent is only one part of that. The other part is software architecture.

    Someone still needs to reason about which services to use, where data should live, how systems communicate, which infrastructure makes sense, where the security boundaries are and which trade-offs we’re willing to make.

    Those are interesting problems, and they’re much bigger than whether a particular function should be written in Go, Rust, Kotlin or Java. The implementation increasingly becomes the AI’s responsibility. Intent and architecture become ours.

    I think someone will build this

    If this line of thinking is correct, I’d be surprised if the frontier AI labs weren’t already exploring this space in some form. Their models are increasingly capable of being the primary authors of code, so a language or intermediate representation optimized specifically for AI generation and reasoning feels like a natural next step.

    And if it doesn’t come from one of the frontier labs, I suspect one of the large technology companies will eventually arrive at the same conclusion.

    We’ve spent decades optimizing programming languages for human developers. If AI becomes the primary author of software, I think it’s inevitable that sooner or later we’ll optimize the language for AI instead.

    Today’s programming languages aren’t going to disappear overnight. There is far too much software, knowledge, tooling and infrastructure built around them. But perhaps Go, Rust, C++, Kotlin and Java eventually become less important as languages that humans actively write and more important as targets, runtimes or implementation details underneath another layer of abstraction. And maybe that next layer isn’t really designed for us at all.

    So, what if the next programming language isn’t for us?

  • Navigating Evernote’s UI Hurdles: The Android Widget Experience

    Navigating Evernote’s UI Hurdles: The Android Widget Experience

    As a dedicated Evernote premium user since May 2010, I’ve witnessed its evolution and have largely benefitted from its robust note-taking and task management capabilities. However, a significant portion of my interaction with Evernote is through its Android widget, which, I’ve found, is not keeping pace with user needs, particularly in terms of its UI/UX design and functionality.

    This post delves into the specific issues I’ve faced, highlighting areas where Evernote could improve to meet the demands of its long-term users.


    Syncing Issues with the Android Widget

    One of the core issues I’ve encountered is the widget’s inconsistency in updating tasks. Unlike the seamless sync we expect in today’s app ecosystems, the Evernote widget often falls out of sync. This discrepancy means tasks updated within the app itself don’t always reflect on the widget, or the other way around. For someone who relies on immediate updates for reminders and tasks, this lag is not just inconvenient; it’s a deal-breaker.

    Clunky Task Addition Process via the Widget

    The process of adding tasks through the widget is far from intuitive. An evident example is the inability to set due dates directly when adding a task from the widget. This oversight forces a two-step process: you add the task via the widget and then have to open the app, locate the task, and edit it to set the due date. This cumbersome process undermines the very efficiency that a task management tool should offer.

    Lack of Customization in Task Display

    The widget lacks essential filtering options. It displays all todo-items, regardless of their due date status. This “all or nothing” approach leads to a cluttered and overwhelming widget view, especially for users who have numerous tasks, some of which might not be immediately relevant. The absence of filters to tailor what appears on the widget means you can’t easily focus on the tasks that require your attention for the day or week.

    Need for a More Condensed Design

    The current design of the Evernote widget is too spaced out, taking up valuable real estate on the home screen. A more condensed design would allow for more information to be displayed, enhancing the widget’s utility in a limited space. This is especially crucial for users who depend on a quick glance to stay informed and organized.


    The issues mentioned above with the Android widget reflect a broader concern: the gap between Evernote’s core functionality and its adaptability to user-specific needs, especially for those who, like myself, have shifted to a widget-centric workflow.

    While I’ve been a satisfied customer for over a decade, these UX and UI limitations are pushing me to reconsider my reliance on Evernote. It’s crucial for productivity tools to evolve with user habits, and in this aspect, Evernote’s widget seems to be lagging.

    As a call to action, I urge Evernote to address these concerns, ensuring that its widget is not just an extension but a fully functional and integral part of the Evernote experience. The potential for improvement is immense, and it’s in areas like these that Evernote can truly enhance its value for dedicated Android users.

  • How to trigger and run Firebase scheduled functions from localhost

    How to trigger and run Firebase scheduled functions from localhost

    Every wonder how to trigger Firebase scheduled (pubsub) functions directly from localhost during development? It’s actually quite easy, but for some reason not very well documented.

    Start by installing Firebase CLI:

    npm install -g firebase-tools

    Setup local Firebase emulators:

    firebase init emulators

    Make sure that your firebase.json has a pubsub port defined.

    "emulators": {
      ...
      "pubsub": {
        "port": "8085"
      }
    

    Start your local emulators:

    firebase emulators:start

    Shell into the running Firebase emulator instance

    firebase functions:shell

    You can now trigger any functions.pubsub.schedule directly from this prompt. E.g:

    scheduleNotifier();

    You’re now able to significantly improve your firebase function development, since you can trigger the scheduled functions interactively.

    firebase > scheduleNotifier();
    'Successfully invoked function.'
    firebase > >  No matching documents.
    >  Notifier done: 0
    
  • How to check a DNS TXT record using OSX Terminal

    A lot of services today authenticate DNS via TXT records and i find myself looking for web-services that checks those values for me. However, doing this will only give me the DNS record(s) for the DNS where the service is running, not actually my local DNS response.

    Doing this via the Mac/OSX Terminal (command line) is trivially easy:

    dig -t txt domain.com

    Which will give you the TXT record for the specified domain. You can change the “txt” part to any other DNS parameters.

  • Updating PHP to 7.2 on OSX using Homebrew

    Updating PHP to 7.2 on OSX using Homebrew

    PHP 7.2 provides several critical security updates and it’s important for any PHP developer to make sure that they leave the 5.x branch and jump on the 7.x branch as soon as possible.

    Updating to PHP 7.2 is a breeze If you’re on OSX and using Homebrew.

    Start by making sure that brew is up to date:

    brew update && brew upgrade

    Unlink any previous PHP installation (this may vary, so you might need to replace the php71 accordingly):

    brew unlink php71

    Install PHP 7.2:

    brew install php72

    Once done, you can verify that PHP 7.2 was installed by using php -v

    Happy coding!

  • How to fix “Unprotected Private Key File!”-errors when trying to connect to a EC2 machine

    Most Amazon EC2-users run in the to pesky “Permissions XXXX for ‘xxx.pem’ are too open. It is required that your private key files are NOT accessible by others.”-problem from time to time. And the solution is surprisingly simple.

    Since you are trying to access a machine using a private key, SSH requires that this key is only readable by the current user. This is to ensure that no-one else on the system can access this file and use it.

    Simply change the permission of the .pem file to 400, which means that it’s only accessible by your user and the problem will be fixed:

    chmod 400 xxx.pem

  • Getting the PHP runtime for App Engine to run on Ubuntu

    AppEngine + PHPExciting news out of Google I/O 2013 reveals PHP support on Google AppEngine. As a php and a appengine-nerd, this is great news. And setting up the local development environment on Ubuntu (13.04) was a breeze.

    The PHP runtime for AppEngine requires the cgi-version of php 5.4 (and above) and python  2.7 (and above). Most Ubuntu-installations have python installed, but i’ll cover those steps as well, feel free to skip those if they are redundant for you.

    Installing Python

    sudo apt-get install python

    Installing php5-cgi
    (this should be safe to install even if you currently have a php-version installed since it’s the cgi version)

    sudo apt-get install php5-cgi

    Grabbing the AppEngine for PHP SDK

    wget http://commondatastorage.googleapis.com/appengine-php/appengine-php-sdk-1.8.0.zip
    unzip appengine-php-sdk-1.8.0.zip

    Starting a local AppEngine instance using php5-cgi

    ./dev_appserver.py /path/to/your/app –php_executable_path=/usr/bin/php5-cgi

    Your app should now be serving on http://localhost:8080/.

    More details can be found in the official documentation:
    https://developers.google.com/appengine/docs/php/gettingstarted/

  • How to re-enable workspaces on Ubuntu 13.04 Raring Ringtail


    enableworkspacesCanonical (the makers of Ubuntu) decided to remove the highly useful workspaces on default Ubuntu installations. But have no fear, this guide re-enables the workspaces within a minute or so.

    It’s actually a lot easier than i thought, so ignore below and just open Settings -> Appearance and click on Behavior. Now you can re-enable workspaces with the “Enable Workspaces”-checkbox.

    I’ve also updated the screenshot to better illustrate this.

    ———–

    First off we need to install unity-tweak-tool, either click on the link or type in the following commands in a Terminal (Ctrl + Alt + T)

    sudo apt-get install unity-tweak-tool

    Now open unity-tweak-tool using the Terminal:

    unity-tweak-tool

    In the window, click the “Workspace Settings”-icon (check the picture above) and flip “Workspace Switcher” to “On”.

    Workspaces have now been re-enabled on your machine and it’s a persistent settings, so you don’t need to redo this if you reboot your machine.

  • How to fix Unity And Compiz not showing after Ubuntu 13.04 upgrade

    Ubuntu 13.04 Raring RingtailAfter upgrading my installation of 12.10 Quantal Quetzal to Ubuntu 13.04 raring ringtail Unity decided to go in to hiding mode. Not sure why this happened, but resetting Unity And Compiz solved the issue for me.

    Resetting Unity and Compiz is exactly what it sounds like. It will reset all customizations and configurations you’ve done to Unity and Compiz. So make sure that you backup any settings you wish to keep. Your mileage may vary.

    Before resetting we need to install dconf-tools on your machine:

    sudo apt-get install dconf-tools

    Now run the following command to reset Unity and Compiz:

    dconf reset -f /org/compiz/

    All you need to do now is to logout and login and Unity should re-appear on you brand spanking fresh version of Ubuntu. Enjoy!