In the world of software development, we often draw hard lines. Developers write code; QAs try to break it. Developers worry about how it’s built; QAs worry about if it’s built correctly.
But this division has a cost. And nowhere is that cost more obvious than in the all-too-common bug ticket: “The app is slow.”
Let’s be honest. We’ve all written it. We’ve also been on the receiving end of the developer’s sigh when they read it. Why? Because “it’s slow” is a symptom, not a diagnosis. It’s not reproducible, it’s not specific, and it forces the developer into a blindfolded guessing game.
The hard truth is that in a modern, agile team, “that’s not my job” is a dangerous phrase. If you, as a QA professional, want to graduate from just finding bugs to preventing them, you need to speak the same language as your developers.
And when it comes to performance, that language is Big O notation.
The Gap Between “Slow” and “Why”
Most of our work as QAs is focused on the what. What happens when I click this? What happens when I enter this data? We validate functional requirements. But performance is a non-functional requirement that has a massive, direct impact on the user experience.
An app that’s functionally perfect but unusably slow is a failed product.
This is where understanding algorithmic efficiency becomes a QA superpower. It’s the difference between reporting:
- The Vague Report: “The user profile page is slow to load.”
- The Actionable Report: “The user profile page load time is increasing exponentially. With 10 users in the database, it loads in 200ms. With 100 users, it takes 4 seconds. This suggests the query might be an $O(n^2)$ operation. I suggest we review any loops related to data fetching, especially around the ‘friends list’ feature.”
Which of these two reports do you think gets taken seriously? Which one builds respect between QA and Dev? Which one actually helps fix the problem?
So, What is Big O (And Why Isn’t It a Math Test)?
Don’t let the $O(n)$ scare you. You don’t need a computer science degree (though, as someone with one, I can tell you this is one of the most practical parts).
Big O is simply a way to describe how the runtime or memory usage of a piece of code scales as the amount of input data (n) grows.
Think of it this way:
- $O(1)$ (Constant Time): The best. It takes the same amount of time regardless of the data size. (e.g., looking up a value in a hash map or dictionary by its key).
- $O(log n)$ (Logarithmic Time): Excellent. The time it takes grows very slowly. (e.g., finding a name in a phone book using binary search—you tear the book in half each time).
- $O(n)$ (Linear Time): Good. The time itA takes grows in a direct line with the data. 100 items take 10x longer than 10 items. (e.g., finding a name in a phone book by reading every single name from start to finish).
- $O(n^2)$ (Quadratic Time): The Danger Zone. This is our enemy. The time it takes explodes exponentially. If 10 items take 1 second, 100 items might take 100 seconds. (e.g., finding a name in a phone book by taking each name and comparing it, one by one, to every other name in the book).
When an application is “slow,” it’s almost always because a developer, often accidentally, introduced an $O(n^2)$ operation—a “nested loop”—where a linear $O(n)$ or logarithmic $O(log n)$ one would have done the job.
Where QA Meets the Algorithm: Two Battlegrounds
Your job isn’t to find the exact Big O notation. Your job is to spot the pattern. You are perfectly positioned to do this, because you control the “n” (the data) during testing.
1. The API Endpoint and the User Experience
This is the most common culprit. A developer builds a new GET /api/orders endpoint. They test it on their local machine with 5 orders in their database. It returns instantly. They merge it.
You, as the QA, are testing in the staging environment. You’re doing load testing, or maybe you’re just testing a user account that has a long history. You find that this endpoint is taking 10, 15, or 30 seconds to respond. The “loading” spinner just keeps spinning. The user gets frustrated and leaves.
A developer sees one item. You see the system.
By understanding Big O, you know how to test this. You don’t just test with 5 orders. You test with 1. Then 10. Then 100. Then 1,000. You measure the response time at each step. If the time is growing linearly, it’s probably fine ($O(n)$). If it’s exploding… you’ve found an $O(n^2)$ bug.
You can now go to the developer and say, “The GET /api/orders endpoint looks like it’s using a nested loop. It’s fast for 10 items but takes 15 seconds for 500. Can we check if we’re doing a separate database query inside the ‘for’ loop instead of a single JOIN?”
You’ve just saved days of work and prevented a production catastrophe.
2. Our Own Automation Scripts
This is the one we don’t like to talk about. Sometimes, we are the source of the slowness.
We write automation tests. We run them in the CI/CD pipeline. The pipeline gets slower, and slower, and slower. Builds take 45 minutes instead of 5. Developers start complaining (rightfully) that the QA-gate is too slow and it’s blocking their work.
Why? Because our tests are $O(n^2)$.
Imagine a test script for creating a new user. To ensure the username is unique, the script first queries the entire database, gets a list of all 50,000 existing users, and then loops through that list in the test code to check for a match.
That’s a simple test that just became a performance nightmare. As the database grows, your test suite grinds to a halt.
A QA who understands Big O would see this and say, “This is inefficient. Let’s do a direct SELECT COUNT(*) query for that one username, or better yet, let’s just try to create the user and assert that we get the expected ‘username already exists’ 400-level error from the API.”
It’s Not About Being a Developer. It’s About Being a Better Tester.
Look, you don’t need to go back to college or start doing LeetCode problems. This isn’t about learning to write a merge sort algorithm.
It’s about respect for your craft. It’s about personal growth. It’s about being a true engineer in quality, not just a manual clicker.
Understanding the concept of algorithmic efficiency does three things:
- It transforms your bug reports from vague complaints into precise, actionable data.
- It bridges the communication gap with developers, earning you technical respect.
- It makes you a better tester by giving you a mental model to design performance and load tests that find critical, user-impacting bugs before they hit production.
The next time you see a spinning wheel, don’t just write “it’s slow.” Ask yourself: “What is ‘n’ here? And what happens when I make ‘n’ 100 times bigger?”
That one question is the first step to thinking in Big O. And it’s the step that separates a good QA from a great one.