I'm proud to announce that we have launched a redesigned Oh Dear. If you're unfamiliar with Oh Dear, it's the best all-in-one monitoring tool for your entire website. You can register for a 10-day free trial.
In this blog post, I'd like to share what Oh Dear can do for you, how we've rebuilt various parts, and give you an overview of the technology behind the service.
What is Oh Dear?
Instead of just pinging the homepage, we crawl your entire site and notify you of any broken links on any of the pages.
Additionally, we can:
- perform multi-location uptime checks
- check your SSL certificate,
- measure your site's performance
- make sure your scheduled jobs run on time
- check if your application is healthy (by monitoring your free disk space, database, Redis, Horizon, security warnings, and more!)
- notify you of any changes to your DNS records
- monitor the expiry date of your domain
- render status pages so you can inform your users about the state of your service. Here's the status page of Laravel powered by Oh Dear.
All of these checks are feature rich on their own and can be customized to your liking. Want to monitor a password-protected page? No problem! Want to get notified 14 days before your certificate expires? Yup, we can do that! Want to know if your CPU is spiking for a couple of minutes? That's covered too!
You can read more about Oh Dear's checks in the extensive documentation.
When something goes wrong (or becomes ok again), we can notify you via mail, interactive Slack notifications, Telegram, MS Teams, SMS, webhooks, and more. Check out the notification docs to know more.
Of course, we also offer an extensive API, so you can integrate Oh Dear into your own systems. There's also a collection of tools that already integrate with Oh Dear, such as a CLI tool, a Raycast extension, a WordPress plugin, and much more!
The history of Oh Dear
About six years ago, I was looking for a good solution to monitor the uptime of the websites maintained by my company Spatie. When encountering such a problem, I always think: "how hard can it be to write my solution for this". I created a package called laravel-uptime-monitor. It was initially released on 22nd November 2016; how time flies!
At the time, I also wrote a few tools to check a website's SSL certificates and broken links. This got the attention of Mattias Geniar, a team lead of Nucleus, a popular Belgian hosting firm. He had the idea of partnering up to create an easy-to-use service to check uptime powered by my open-source stuff. During that period, my buddy Dries Vints and I were also thinking about working together on a nice side project.
Somewhere around July 2017, the three of us met in a bar in Antwerp, Belgium, to talk things through. The primary purpose of the meeting was to measure if we were enthusiastic enough about this project to put our hearts into it. From the get-go, we all liked creating an uptime service as our hobby project.
In that meeting, we also thought of a name. We all know that naming things is one of the hard things to do. Belgium has many good beers, so it's no surprise that the bar we were sitting in was covered in beer advertisements. One of them was this one for a fine one called "Moeder Overste", which translates to "Mother Superior".
We were thinking: "What would Mother Superior Superior say if her website was down". Immediately "Oh Dear" came to mind. We thought we would only keep it as a work-in-progress name, but over time we liked it so much that we used it as the final product name.
In that meeting, we didn't make any kind of business plans, or didn't make any financial agreements, or put any deadlines. We were creating Oh Dear as a pure hobby project.
I still remember that during initial development, I felt a lot of freedom compared to creating projects for a client. We took our time to get things right. During this initial development, Dries left us to work on other projects on his own, and he ended up working for Laravel, which is quite nice. Both Mattias and I decided to continue creating Oh Dear. Mattias had good in-depth knowledge of how certificates worked under the hood. I was (and think I still am) very proficient at structuring code and writing things in a readable way.
Oh Dear was built in public. We regularly tweeted and wrote blog posts about the state of the project and how we tackled technical problems. In this old moment on Twitter, you'll find some tips we were tweeting. We also started a mailing list so we could send people an email when launching our website.
Initial development took place in August of 2017 and was based on the first edition of Laravel Spark. This date is still visible in the very first migration of our database (our migrations are now squashed). By October - November, we had a working POC to monitor all Spatie websites and some of Nucleus.
In the following months, we added a notification system, the broken links and mixed content checks, and a lot of settings to customize the checking process.
From the very start, we also made sure that we had an automated suite of tests to make sure our code was working correctly. This test suite allowed us to refactor the code to our liking, making it more readable with each pass and without fear of breaking things.
The initial design of Oh Dear was made by my colleague Seb, and he had an idea to make our homepage stand out: make it screaming red.
It was also sort of a reference to the red error screens at the time you'd see when a site certificated had expired in the browser.
On 11 January 2018, we thought Oh Dear was stable enough and made it publicly available. We had not planned that date or had a formal launch plan. We even decided on the final prices that very evening. After the site was publicly available and people could register an account, we used our email list to inform every interested.
Here's a screenshot from our Slack of that moment (yeah, at that moment, we spoke Dutch internally).
In the years before launch, both Mattias and I had built up our audiences on Twitter. I did it by releasing open-source software for the PHP / Laravel Ecosystem. Mattias had a very popular DevOps newsletter, which we also used to inform people about the launch of Oh Dear. We were lucky that Laravel News picked up on our launch. So, it's no surprise that we had a lot of eyeballs on us that evening.
On a technical level, everything went very smoothly. There were no significant hiccups. After 30 minutes, we had our first paid customer. Here's how that looked like in our Slack
This was a very magical feeling for me. At that point, I only made money with software through client projects, and this first amount earned through a SaaS felt special.
At the end of the month, we had 32 paid customers, which in my mind, was a great success. Remember, Oh Dear was treated very much like a hobby project. The time we put into was considered "free". This first income was enough to cover our hosting costs. Even though profits were small, you could say that Oh Dear was profitable from the very first month.
In the following months, we kept adding features proposed by our clients, and we only added things that were useful for ourselves and 80% of our audience. One of the goals of Oh Dear was to be the most straightforward solution, so we tried to keep feature creep to a minimum.
We also tweaked our homepage a little bit as we got some "aaaarrgggh my eyes" feedback on the initial bright red design.
On the 25th of February 2020, two years after the initial launch, we launched the first redesign of Oh Dear. This redesign was made by Rik Grafiek. Along with our website, we also updated our logo. Here's how our new homepage looked at the time.
After that redesign, we started adding support for more types of checks:
Redesigning Oh Dear... for real!
Mid 2021, Mattias and I were thinking about how we could improve the service. We already added quite some features, both big and small.
When Oh Dear started, there were only a few checks and features. Our design improved over the years, but it was clear that we needed a total redesign to make all features fit. Tabula rasa! We thought: "How would Oh Dear look if the design was up to par with the best designed services, like Stripe."
As Mattias and I are no designers, we contacted a few trusted parties that could help us with creating the new design. The party we ended up with was Digital With You, a Belgian digital studio with which I already had good contacts.
We had multiple meetings with Dieter and Steve of Digital With You to explain how Oh Dear works and what we were aiming for. It certainly helped that they were already using Oh Dear for their own projects.
Steve came up with a gorgeous design for the homepage. After we all decided this was the way to go, he continued with every page of the front site. You might think our marketing site is only a homepage and one or two extra pages, but it's quite dense. We have pages explaining all of our main features, and each page has unique elements to explain a particular feature.
Steve designed all the individual elements and pages in Sketch, which we discussed in regular meetings. Here are some screenshots from that Sketch file.
Instead of using "Lorum Ipsum" copy or copying what was already on the live homepage, Steve came up with new copy that was better than what we had. A real power move! We used a lot of Steve's copy in our redesigned site.
Now that we had a redesign ready in Sketch, it was time to turn it into HTML. In early 2022, we brought on Nick Retel to our project. Nick is a kick-ass front-end developer hailing from The Netherlands.
He translated the Sketch file from Steve to Tailwind-style HTML sprinkled with Alpine components. During spring 2022, he concentrated on the marketing site, rebuilding each page with a lot of attention to the details. If you take a look at our new homepage or any of the feature pages, you can see that there are a lot of animations and little interactive elements.
At the start of summer, Nick concentrated on rebuilding the app. Nick used the design language from the marketing site to build the back end, but there was quite some work deciding how the UX would work. With Nick, I thought of ways to improve the site list, how we handle notification preferences, and how status pages are managed.
As the app part of Oh Dear is also extensive, this took us some time. It was a very rewarding experience as we paid a lot of UX debt from the past.
From mid-August to mid-September, we did extensive design testing and let some beta testers in to give feedback to spot issues. I feel that this time was very well spent: we made sure that our redesigned site is very polished and error-proof from day 1. In a next section of this post, I'll detail how we tested our design.
Our improved UX
Let's look at how the redesigned site looks and what improvements we made over our old site.
One of the most important pages is, of course, the homepage. Here's what our previous one looks like.
And here's our shiny new one:
You can see that together with redesigning our site, we've also updated our logo. Here it is in its full glory.
The whole front site is also available in dark mode. Here's how the dark version of the home page looks like.
On the redesigned homepage, there's a lot of content below the fold that's not shown in the screenshot above. We explain which features there are, show some testimonials and explain our pricing. Here are some more screenshots of the stuff below the fold.
You can't see in these screenshots that there are a lot of subtle animations.
We're also updating our docs section. Here's what it looked like before.
And here's what our new docs look like.
The public marketing pages are important for us as we hope they'll convince more people to use our service. But of course, we didn't stop at the marketing site, and we've also redesigned the app, solving long-standing usability issues.
The previous app UI was almost five years old. We designed it when Oh Dear only offered its initial four checks. Currently, we offer nine checks. Here's what our previous site list looks like.
You can see that, with nine checks, it's a bit busy.
Here's what the new list looks like.
You can see that this list is much calmer. We only show the issues that we find. If no issues are found, the dot before the site will be green.
When you click those three dots at the end of a row, you'll see a little submenu that allows you to navigate to common pages for that site.
Let's take a look at the old site overview page.
Not too bad, but it's much better in our new design. We'll show a lot more helpful information by default.
Again, those three dots allow you to take relevant actions or pages for a check.
Let's go to another important part of our application. Oh Dear can send you notifications whenever we detect something wrong with your site. There are many notification channels: mail, Slack, Telegram, and Discord, ... You can configure when and how we should notify you on the team notifications screen.
Here's what the previous screens looked like. We have screens per channel, and on the list of a channel, you can see all the possible notifications we can send.
The problem with this setup is that it's hard to see which channels you have configured. To do that, you'll have to click "Mail", "Slack", "Discord", ... in the sidebar and check if you have something configured.
We have revamped this screen. Instead of screens per channel, we now only have one screen that shows all notification configurations.
On the list, we don't show all those notifications toggles anymore. Instead, we show how many notifications are configured for the channel. If you want to see which notifications, you can edit a configuration.
In addition to monitoring sites and applications, Oh Dear also offers beautiful status pages. The status pages allow you to communicate the health of your service to your audience. Here are some Oh Dear powered status pages for the Laravel organization and Flare.
I almost didn't dare share how it previously looked to set up a status page. It's kind of messy.
You can do a lot here, but it isn't pleasing to the eyes. In our redesign, we've vastly simplified this list, and here's what it looks like now.
If you click one of the status pages, you'll see this status page overview.
Notice how similar this all looks to the site list and site overview. This is a benefit to us: if you are already familiar with sites, you'll immediately feel at home when working with status pages.
How we tested the redesign
Let's look at the PR that contains all of the changes of the redesign.
It is extensive: a lot of code has been changed, almost 2 000 changed files, and over a 1 000 commits. You might wonder how we managed maintaining, reviewing, and testing this PR.
All the redesign changes were done on a separate branch called
redesign-2022. Whenever we add features or fixed bugs on the
main branch, we immediately merged the
main branch with
redesign-2022. This way, we avoided large merge conflicts when merging
redesign-2022 back to
main. It also helps that Oh Dear has quite an extensive test suite. We made efforts to have passing tests on both the
redesign-2022 branches to ensure our code works correctly.
Most of our tests ensure that all back-end code works correctly, and we don't have too many tests for the UI itself. To ensure the UI works correctly, we've set up a separate domain, beta.ohdear.app, that uses the code from the
redesign-2022 branch. Because our redesign didn't contain any changes to the DB, we could just let beta.ohdear.app use our production database.
This way, we didn't have to seed any dummy data but could test our redesign with the production data. We could just log in with our regular user accounts, see all sites, and check results from production using the new UI. This immensely helped catching bugs, as the best data to test is the production data.
To help with support, Oh Dear has an admin feature called impersonation. This allows us, as system owners, to log in as anyone else. We used this feature at beta.ohdear.app to look at the largest Oh Dear accounts. Again, when we saw UI bugs in those accounts, we also fixed them.
After we were sure that the most glaring UI redesign issues were all fixed, it was time to let some outsiders test it. We sent out a tweet asking who would like to help up beta test.
The @OhDearApp redesign is now technically complete.— Freek Van der Herten 🔭 (@freekmurze) September 16, 2022
We’re beta testing a bit more to fix all bugs. If you want access, mail us at email@example.com (you don’t need to have a subscription).
Now writing an extensive launch blog post, prepping PH page, etc…
🚀 Launch on 3/10 pic.twitter.com/a8e6A6fbdg
We got about 30 people that wanted to help us to test. They only reported a handful of issues. During this phase, we also used Flare to report any errors on the beta.ohdear.app. Almost no exceptions came in, which gave us confidence that the redesign was ready for prime time.
The tech stack of Oh Dear is a love letter to the Laravel and PHP community. The main application is built with Laravel 9 and runs on PHP 8.1. We use the latest version (at the time of writing); that's a common theme in everything I work on.
All of our checks are performed by queued jobs, which are handled by Laravel Horizon, a real power-house package.
We also use a ton of packages, of which a lot are homegrown at Spatie. Here they are in alphabetical order.
- dragonmantank/cron-expression: convert cron expressions to human readable strings
- laravel/cashier: handle incoming payments via Stripe
- laravel/jetstream: handling teams, user profiles, and authentication UI
- laravel/nova: an excellent admin panel, mainly used to help solve support problems
- lob/lob-php: the API for a cool service that we use to send welcome postcards to each new customer
- maatwebsite/excel: exporting our broken links and mixed content reports to CSV and excel
- mattiasgeniar/phpunit-query-count-assertions: we use this in our test suite to make sure some pieces of code don't make too many SQL queries
- ohdearapp/ohdear-php-sdk: we use our own SDK to ensure that the responses from our API are correct
- spatie/array-to-xml: the results of our status pages can be viewed as XML. Using this package, we can convert the PHP array with results to XML.
- spatie/commonmark-shiki-highlighter: highlighting code snippets on our blog
- spatie/crawler: this package powers the broken links and mixed content checks
- spatie/dns: fetches DNS information used in our DNS check
- spatie/eloquent-sortable: used to make specific DB models sortable, such as the sites displayed on a status page, doc pages, and faq items
- spatie/interactive-slack-notification-channel: our interactive Slack notifications (you can rerun or snooze a check in the Slack notification) are powered by this one.
- spatie/laravel-activitylog: we store who performed which operation on a team, site, or status page. Basically, we're using this to keep an audit log
- spatie/laravel-backup: this package can backup the database to S3.
- spatie/laravel-collection-macros: whenever I can make a collection chain operator more readable, I add a macro to this package. I don't immediately PR them to Laravel as most might be a bit opinionated
- spatie/laravel-feed: generates the RSS feed on our blog and status page
- spatie/laravel-flash: the most simple (and maybe best?) package to handle flash notifications in a Laravel app
- spatie/laravel-health: used to parse incoming results for our application check
- spatie/laravel-honeypot: to catch and stop requests by bots on various forms on our public website
- spatie/laravel-json-api-paginate: paginating results from our API according to the JSON-API
- spatie/laravel-login-link: this package adds a handy login link for developers in our local environment.
- spatie/laravel-markdown: we write our blog posts in Markdown. This package converts that HTML to Markdown.
- spatie/laravel-medialibrary: on our status pages, you can upload your only logo, favicon, ... This package handles storing those uploads and associating them to a status page model.
- spatie/laravel-menu: this package is used to render all menus and navigation items in our UI.
- spatie/laravel-query-builder: used to transform the query parameters of incoming API requests into SQL queries
spatie/laravel-queued-db-cleanup: some tables contain so much records that even Laravel's
MassPrunablefunctionality causes troubles. Our package can clean up massive amounts of old data using queued jobs.
- spatie/laravel-rdap: fetching information about domain names
- spatie/laravel-remote: very handy to execute artisan commands on the server without having to ssh into the server manually
- spatie/laravel-robots-middleware used by the broken links / mixed content crawler to interpret and respect a robots.txt file
- spatie/laravel-schedule-monitor: used to interpret incoming results for our scheduled jobs check
- spatie/laravel-short-schedule: this package allows us to run scheduled jobs at a sub-minute interval. We use this to determine if our incoming scheduled jobs endpoint is healthy at all times and temporarily stop notifications for that check when it is not.
- spatie/laravel-site-search: this is a cool one that powers the search on our doc pages. It will crawl all the docs pages and put them in Meilisearch. The search input is a Livewire-powered component that queries the Meilisearch index.
- spatie/laravel-slack-alerts: this package makes it easy to send messages to our internal Slack channel when noteworthy things happen: somebody creates a user account or team, or subscribes
- spatie/laravel-sluggable: generating slugs for all kinds of models. The slugs are used to make URLs to, for example, blog posts and FAQ items, more readable.
- spatie/laravel-stubs: provides opinionated stubs used when creating a new migration, controllers, ...
- spatie/laravel-support-bubble: we use this little package to render a support form on all pages. Submitted requests are sent to Freshdesk
spatie/laravel-tags: we use tags on our
- spatie/laravel-tail: this package allows tailing the application log, which is very handy for debugging
- spatie/laravel-url-signer: when performing an uptime check, the main Oh Dear application sends a signed HTTP request to one of our many satellite servers across the globe. The satellite servers then pings the website to be checked and reports back to the main app. This package signs requests to the satellite server, so it's sure the request comes from the main app. Laravel's built-in signing capabilities only support signed requests within a single app; the spatie package makes it easy to send signed requests between several apps
- spatie/laravel-validation-rules: whenever I create a validation rule that I want to use in several apps but is too opinionated for Laravel, I put it in this package. We use a couple of these rules in the Oh Dear codebase
- spatie/laravel-webhook-server: one of the ways Oh Dear can send notifications to you when something is wrong is by sending webhooks so that you can react in your app however you want. This package is used to power our webhooks to your app.
- spatie/pest-plugin-test-time": used to test time related functionality. And yes, the Oh Dear test suite is written in Pest.
- spatie/simple-excel: used to export all of our invoices to a CSV sent to our accountant. Soon, we'll refactor all usages of maatwebsite/excel in our codebase to spatie/simple-excel
- spatie/ssl-certificate: used to read information of an SSL certificate of a site
- wire-elements/spotlight: an excellent package that makes it easy to add a command input bar to a Laravel app. Using our command input bar, you can quickly go to the results of any site or status page, go to team management and much more.
Some cool numbers
To finish off, I'd like to share some numbers on Oh Dear at the time of writing this blog post.
In total, we performed 14 148 461 956 checks, yes, 14 billion.
We've sent out 5 710 663 notifications since we launched the service.
On average, we perform about 20 000 jobs per minute, 1 200 000 per hour.
For the most unstable website that we monitor (we're not going to shame them by mentioning the URL), we detected a whopping 55391 periods of downtime.
Since having added our scheduled jobs check on 24th September 2020, we had 555 782 234 incoming pings from scheduled jobs from all our clients combined.
A whopping 50% of all notifications get sent via mail, and 25% via Slack.
Our extensive test suite contains 859 tests written using Pest.
Over the years, I've written many blog posts on Oh Dear's internal working and how we optimized things. Here's a small selection:
- Strategies for decreasing the number of queries in a Laravel app
- Building complex form with Livewire in Oh Dear
- Why and how you should remove inactive users and teams
- How to customize Jetstream and Laravel Spark
- Making our Laravel test suite ready for parallel testing
Can't get enough? Here are all my blog posts on Oh Dear.
Wow, you've reached the end of this lengthy post. Congratulations! The Oh Dear redesign was 1,5 years in the making, and I'm very proud of our work.
Oh Dear started as a hobby project, but it has grown to something my co-founder Mattias, and I could live from. But don't worry, we like working respectively at Acheron and Spatie, and still consider that our main jobs. I'm delighted that working on Oh Dear still has a hobby feeling to it. No planning, no deadlines, ...
I genuinely think Oh Dear now has a world-class design and is the best-looking monitoring app available.
I want to thank:
- Steve and Dieter from Digital With You for delivering a kick-ass design
- my colleague at Spatie Seb for clean up our front end assets
- Nick for his good work implementing the design made by Digital With You
- Sean, for taking care of the Oh Dear support, and for his feedback and small improvements on the beta
- My co-founder Mattias for dotting the i's, crossing the t's, and pushing through with all of this!
I hope you'll enjoy Oh Dear as much as we did building it.