Have You Ever Come Across the Term “Fail Fast” in Software Development?
Probably. Alongside well-known development principles like SOLID, YAGNI, and IOSP, “fail fast” is one of the lesser-known concepts – but that doesn’t make it any less important. On the contrary: for me, “fail fast” is one of the most essential principles in software development. In this article, I’ll show you why.
What Does “Fail Fast” Mean?
“Fail fast” isn’t about failing in our software development careers! 🙂 Instead, the goal is to make programming errors and bugs visible as early as possible. If our software contains a mistake, we want to detect it as soon as possible.
Why is this important?
When Errors Are Discovered Too Late – A Short Story
I manage several software projects on the side. Some of them don’t have the best code quality and lack unit tests and integration tests. It’s not quite legacy code, but it’s close…
A few days ago, I added new libraries to a Laravel project. In the process, another library was automatically updated from version 3.0.x to 3.4.1. According to semantic versioning, this shouldn’t be an issue since increasing the minor version (from .0 to .4) should only introduce backward-compatible changes.
Unfortunately, the library’s developer didn’t notice that they had actually introduced a breaking change. The library now requires an additional configuration value, and there’s no default for it. If the configuration value is missing, the library crashes with an error.
And that’s exactly what happened—multiple times—in production. The issue wasn’t caught during manual testing before deployment. Fantastic.
Several Things Went Wrong in This Process:
- Since only the minor version was updated, I assumed the component didn’t need to be fully retested.
- The project has a limited budget, so full manual testing before deployment isn’t feasible.
- There are no unit or integration tests.
- Neither the project nor the library follows the “fail fast” principle.
If “fail fast” had been implemented in both the project and the library, it would have been immediately apparent that a configuration value was missing. I wouldn’t have been able to load any project pages in the test system or run any command-line commands. I would have noticed the issue right away, rather than days after deployment.
In Terms of “Failing Fast”, Symfony Fails Faster
In Laravel projects, configuration values are typically stored as simple PHP arrays in PHP files (see Laravel Configuration). These values are retrieved and validated only when they are needed. This could happen anywhere, at any time, deep within the user process. By then, a lot may have already happened—perhaps a reservation has been started, a payment process initiated, or some other preparation has been made—before the system realizes, “Oops, something is missing in the configuration.”
In Symfony projects with high code quality, things work a bit differently. With Symfony’s Config component, you can precisely define which configuration values are required and what values are valid.
This is where “fail fast” comes into play. The entire configuration is validated at application startup. Even if a configuration value is only needed later in the process, it will be checked right away—at startup (for web applications, at the beginning of the request processing). If configuration values are missing, the issue becomes immediately apparent. You won’t be able to execute any console commands or web requests; instead, you’ll get an immediate error message.
That’s “fail fast”.
What Do You Think About “Fail Fast”?
Do you apply the “fail fast” principle in your own projects? How do you implement it? Have you chosen a specific framework because it is optimized for “fail fast”? Feel free to share your thoughts in the comments!