Witnes started from a real problem that I faced in a previous company.
While working there, we had setup a variety of metrics to measure our frontend and backend performance. Albeit not perfect, our frontend metrics said that we had okay results, the Web vitals were within acceptable range for us, FCP and LCP were also agreeable.
At the same time, we received reports from customers that the product was extremely slow at times, and we eventually managed to reproduce it in-house but the disconnect between these testimonials and our metrics was the real issue.
The Disconnect Between Metrics and Reality
At first the complaints were taken with a slight skepticism, not that they did not occur but their frequency was questioned. Our metrics were very clear — for P95 and P99 we did see values indicating a poor experience, but that’s almost 5%, it could not match the frequency of complaints. Taking into account these two facts, we had to assume that the issue would be on the client side, either due to some firewall of theirs, connection issues, etc. In hindsight I would say this was not the best course of action but at the time we had many big fish to fry.
A while later we managed to see this issue also from a coworker and there it was obvious — we would see pages after pages within a session take 10 seconds if not more to load. And we had no idea why. Was it their connection? Our servers? Something in the frontend? We were watching it happen and still couldn’t tell. That’s when I went on a hunt to find the ghosts hiding under the bed.
The Complexity of Performance Measurement
As I mentioned earlier, we had a setup that allowed us to measure our frontend and our backend. I must say this was more complex than I had thought it would be. We used Prometheus metrics for our backend and a third party analytics tool for frontend. Getting into the whole world of performance measurement has a relatively steep learning curve — just getting your head wrapped around what percentile metrics represent and how buckets work in Prometheus is complex enough before you even start actually observing specific metrics.
Frontend is a beast on its own, tons of acronyms to remember, dissecting the normal page load and almost always giving you half the truth.
Nevertheless, I spent almost a week looking at this from different angles. Could it be the API being occasionally slow? Could it be our frontend host having hiccups? Was it after or during a deployment or a long running process? Many questions but they all ended in the same result: “Yes we have issues, but not nearly as often as our customers tell us”.
Due to time constrains I more or less gave up. We would have to skip this for later and then we would need to see it happening live to debug the issue, which personally I think is one of the worst cases.
The Birth of Witnes
As I have parted ways from my previous employment, I had time on my hands and — unfortunately or fortunately — I am a person who doesn’t really like leaving such mysteries unsolved. Although I never fully identified the root cause, I wanted to make a setup that would allow me to diagnose this in the future.
This is how the first idea of Witnes came to be — can I build a JS script that will tell me for any page its performance and who was the culprit?
It seems you can — to a reasonable extent of course. Witnes now tracks every page you add our little tracker on, gathers all the info we believe are necessary and gives you an overview of each individual page load with 4 vital pillars: Frontend App, Backend API, Network Connection (when available) and Payload.
The goal is that for any given time a visitor engages with your platform you will be able to see how it was perceived by the user and why.
Why Traditional Metrics Failed
However even after all this, the real question is: why were the metrics not showing the truth, and if those metrics didn’t, why would Witnes succeed?
The truth is that we were looking at the wrong metrics.
Traditionally the web started with what we call Multi-Page Applications (MPAs) — essentially 1 URL is 1 page and is accompanied by some JavaScript. The world evolved however and we introduced Single Page Applications (SPAs), which essentially mimic URL navigation but everything happens via JavaScript. You “download” the app when visiting the main page and the rest are just re-renders.
However, there is also a mix of both. MPAs using SPA-like JavaScript frameworks, which essentially means each URL is a new SPA — the heavy lifting is not done in the server to deliver HTML, but instead it delivers a JavaScript package that then builds the app (grossly simplified).
Most analytics platforms and the industry standard metrics are still not up to date with these setups. They measure half the story — the part where a server delivers the payload — but what happens after with the JavaScript bundle is not usually taken into consideration. In addition, concepts like skeletons, loading pages, and deferred content loading — all made to enhance the user experience — skew the results of frontend analytics as they are not actually measured.
This was the other part of Witnes that made the difference. Analytics made for these complex setups, for the majority of modern frameworks (albeit we still have not invested in further analytics for concepts like frontend islands, etc.).
Making Sense of It All
Now the image is getting clearer. We know we are measuring every page load, we know we are taking more metrics into consideration to fit the modern web — but there is one more burden. Understanding all these and making sense of the different values, and on top, our own custom metrics like TrackerBaselineTtfbMs (we measure the speed delivery of our own tracker and use it as a baseline for other downloads, allowing us to evaluate the user’s network performance).
That is why we added one more pillar: User Experience.
We do our best to calculate how the user’s experience was for every page load and compare it historically (based on your data retention plan). In addition we have separated the info into 2 layers:
- The overview — a more user-friendly page that we believe anyone in the company should be able to visit and understand. It provides an overview of the experience and who we believe might be the best indicator of a performance degradation.
- The deep dive — more focused towards developers, where customers can observe the waterfall of network requests and see what is going on, with the help of our different hints.
What’s Next
Witnes was built because the tools we had weren’t telling the full story — not because they were bad, but because the web moved faster than they did. SPAs, deferred loading, JavaScript bundles doing the heavy lifting after the server is done — none of that was in scope when these metrics were designed.
The goal is simple: anyone in your company should be able to open Witnes, look at a user session, and understand what happened. No percentile algebra, no Prometheus queries, no Network tab archaeology.
If you have a performance mystery you can’t solve, we want to dig into it together.
If you just want to see what your site actually looks like to your users — the trial is free, two lines of code, data in minutes.