Everyone told me not to build a SaaS in C++

Almost everyone seems to think building a SaaS in C++ is a terrible idea. Use Rails. Use Next.js. Use Go. Use literally anything else but C++

So, naturally I’ve decided to do it anyway. I’ve got a private MVP up and running already, and am working toward a public release. And no, I’m not doing this just to prove you wrong, because that would be a poor business decision.

I have two basic reasons:

  • First, I’m very experienced with C++. It’s the tool I know best, and I know how to use it. If I were to switch to Next.js or Go, then I’d first have to learn how to use those, before I can get moving
  • Second, I want to know what it’s actually like. Is writing a web app in C++ really that bad?

People say C++ is too dangerous. They say you’ll spend all your time fighting the language. That C++ has poor text processing capabilities. They say performance doesn’t matter for SaaS apps anyway, so you might as well use a language that’s slower, but designed for the web.

Let me walk through the most common arguments, what I’ve found so far, including the one drawback that I think matters the most. And no, it’s not actually a C++ language issue.

And remember, I’m already well under way in writing a web-app in C++, so I’ve got data to back this up

C++ is Too Dangerous?

Let’s take on the big one first: C++ is too dangerous. There is some truth to this. Have a look at this code:

int receive_message(char* buffer, int size) {
    // Imagine this function receives a message from the network and fills the 
    // buffer with data. It returns the number of characters received, which 
    // may be less than or equal to the size of the buffer.
    return size;
}

void printMessage() {
    char array[16];

    int numChars = receive_message(array, 16);

    for(int i = 0; i < 100; ++i) { // <= Buffer overflow! Never use magic numbers!
        out.print_char(array[i]); // <= Will trigger an error in Javascript.
                                // C++ will keep reading memory until it hits a 
                                // page access violation. A good way to leak data...
    }
}

If you ran this as Javascript, then the Javascript runtime would catch this buffer overflow and throw an error. With C++ the result is undefined. It might crash, but it’ll probably print data beyond the end of the buffer. Leaking data like that is clearly bad.

Sounds like a slam dunk case, right? No!

First, if you write code like this then you should be arrested, and sent to coding boot-camp where a drill-sergeant will drum some sense into your head. Never use magic numbers like this.

code bootcamp drill sergeant meme

Here’s a fixed version. This for loop won’t go beyond the end of the received data. And yes, you may assume that the receive_data() function obeys the buffer size limits.

int receive_message(char* buffer, int size) {
    // Imagine this function receives a message from the network and fills the 
    // buffer with data. It returns the number of characters received, which 
    // may be less than or equal to the size of the buffer.
    return size;
}

void printMessage() {
    const int bufferSize = 16;
    char array[bufferSize];

    int numChars = receive_message(array, bufferSize);

    for(int i = 0; i < numChars; ++i) { // <= Correctly reads only the number of characters received
        out.print_char(array[i]);
    }
}

In practise, the HTTP request handlers that I’ve written don’t access raw arrays. Instead, the code iterates through collections of objects using loops like this one:

// Iterates through a list of products using a range-based for loop.
// This code is safe. It doesn't go beyond the bounds of the list. It doesn't crash
for (const auto& product : products) {
    out.print(product.name);
    out.print(product.price);
}

This is a range-based for-loop. It doesn’t go past the end of the container of objects. It isn’t crash prone. It scans through data base rows returned from a SQL query. Other loops might iterate through JSON or form data. I’m using safe access patterns, and higher level constructs that reduce the chance of things like buffer overflow bugs or bad pointers causing undefined behaviour.

And if I’m feeling extra paranoid, then there are static code analysis and even runtime tools to catch buffer overflows and other bugs.

I know I’m going to get some hate for this, but the added “danger” of C++ code is overstated.

Fighting with the C++ Language & Poor Text Processing

The next two reasons people give against using C++ are: you’ll spend all your time fighting the language, and C++ has poor text processing capabilities. I don’t even know what the first one meanse, to be honest. But that’s probably because of my experience. I’m used to C++..

As for C++’s limited text processing capabilities, I’ve found that the limitations don’t really matter. There are four main areas where I need to process text:

  • The URL
  • POSTed form data
  • Parsing JSON
  • Create SQL queries and parse the responses

In all cases, I have libraries doing the heavy lifting for me. The drogon framework parses URLs for me. So it extracts the bits I need, and I can use it from there. Converting a number from string form to integer or float value is easy.

The jsoncpp library makes processing JSON easy, and even throws exceptions on bad access attempts.

Drogon’s database handling code both make extracting values of various types easy. And prepared statements makes constructing robust SQL queries easy as well.

So far, all the text parsing has been pretty easy. Generating HTML is done via drogon’s templating system, and the JSON library handles outputting (and parsing) JSON text.

Does Performance Matter?

Lets move on to performance. By far the top excuse given for using C++ is performance, and the usual answer is that the performance of your code doesn’t matter for a web app, because the web app’s performance will likely be limited by the speed of your database. That’s true, provided that database queries really are the big bottleneck.

I can’t give you a solid answer, because performance only matters when your web app has a lot of users, and it’s running at scale. I’m not there yet; it’s a problem I’d love to have, because it means that the business is doing well.

If you want informed opinions regarding web app performance, then go look for people and companies who migrated from node.js/Ruby-on-Rails to Go, and listen to their experience.

Actual Downsides to Using C++ For SaaS Web App Development.

Now, there are some actual downsides of using C++ for SaaS. The two main ones I’ve found are:

First, the tools and web ecosystem isn’t as developed. For example, you have to figure out how to deploy your server on your own. Next.js has hosting companies like Vercel that make deploying a Next.js app as easy as linking to your Github project and clicking a button. Nobody does that for C++.

I basically have two scripts. One creates a gzipped tarball of the server, while the other one unpacks it on the server, creates a symbolic link to the new version, and triggers a restart

While this didn’t take up much time, small tasks like this do add up.

The biggest downside to using C++ for web apps by far, is this: nobody writes web API integration code for C++, so you have to write it yourself. Stripe provide a set of SDKs for Ruby, Python, Node.js, PHP, .NET, and more (https://docs.stripe.com/sdks). There are even community maintained SDKs for a whole array of other languages. Guess which language isn’t there. Yes, that’s right. C++. At least, not yet

So far this hasn’t cost me much extra time and effort, because the only integrations I’ve done are:

  • Sending emails via PostMark, and
  • Sending authentication messages via WhatsApp

no incoming webhooks or anything even remotely complicated. It’s all been very basic. The real test is about to come, when I integrate with Stripe for payments. We’ll see what happens then.

Conclusion

To sum it all up, writing a SaaS app in C++ is very doable, provided that you’re already a C++ developer (if I weren’t a C++ developer then I’d probably use Next.js). If that’s you, then ignore all the “don’t do it” BS, and pick whatever tools work best for you.

The biggest down-side, is that you’ll probably have to write your own web API integration code, because right now, nobody is providing ready-made C++ SDKs for their web APIs. That and the limited web ecosystem for C++ are what will cost you the most time.

If you’ve already written a web app in C++, I’d love to hear how it went. Please let us know about it in the comments section below

Leave a Comment

Your email address will not be published. Required fields are marked *

 


Shopping Cart
Scroll to Top