SolisReach
← Journal
Web Performance6 min read

Database query performance for content-heavy sites

Written by the SolisReach team

Frontend performance work gets most of the attention because it's the most visible, but a content-heavy site backed by a database can be doing everything right on the frontend and still feel slow because of inefficient queries happening on every request before any of that frontend optimization even gets a chance to matter.

N+1 queries are the most common culprit

A page that loads a list of items and then runs a separate query for each item's related data, instead of one efficient query that fetches everything together, can turn a page that should take 50 milliseconds into one that takes 500. This pattern is extremely common in sites built quickly without a database performance review, and it's usually fixable without major architectural changes once identified.

Missing indexes on frequently filtered columns

Any column a query regularly filters or sorts by, category, publish date, status, needs a database index, or the database ends up scanning every row to find matches. This becomes dramatically more noticeable as a site's content volume grows, which is why a site that felt fine at launch can degrade steadily as more content gets added over the following months.

Caching what doesn't need to be recalculated on every request

Content that changes infrequently, a homepage's featured articles, a sidebar's popular posts list, doesn't need a fresh database query on every single page load. Caching these results for a reasonable interval, minutes rather than seconds, removes repeated load from the database without meaningfully affecting content freshness for the average visitor.

How we actually find these problems

We enable query logging in a staging environment and review the slowest queries under realistic load, rather than guessing at what's likely to be slow. This consistently surfaces the actual bottleneck faster than reasoning about the schema abstractly, and it often turns up a surprising culprit that nobody would have flagged just by reading the code.

A specific fix and its measured impact

Adding a single missing index on a frequently filtered "published date" column on one client's content site cut average page generation time from around 800 milliseconds to under 100, a change that took less than an hour to implement once the missing index was identified through query logging.

How this problem tends to appear gradually, not suddenly

A site with 200 articles rarely shows a performance problem from missing indexes or N+1 queries, since the dataset is small enough that even inefficient queries complete quickly. The same inefficiencies become obvious once the site grows to several thousand pieces of content, which is why this issue often surfaces well after a site has been live and apparently fine for a long stretch.

Why this work is invisible to a non-technical stakeholder

Database performance work produces no visible design or content change, which makes it a hard sell to a stakeholder focused on what a site looks like. We frame it in terms of the actual visitor-facing symptom, slow page loads, rather than the technical cause, to help non-technical decision makers understand why it matters.

Database performance work produces no visible design or content change, which makes it a hard sell to a stakeholder focused on what a site looks like.

How we prevent this from recurring as a site keeps growing

We set up query performance monitoring as part of the handoff for any content-heavy site, so a new performance regression from a future feature or content growth gets flagged automatically rather than silently accumulating again until someone notices the site has become slow.

How we balance performance optimization against a small team's limited engineering capacity

Not every client has spare engineering time to implement every recommended fix immediately. We prioritize the highest-impact, lowest-effort fixes first, like a single missing index, and phase more involved architectural changes over a longer period, so a small team isn't asked to absorb a large amount of technical work all at once.

What monitoring we set up so a team knows when a problem is building, not just when it's already bad

Beyond point-in-time fixes, we set up ongoing slow-query logging with a defined threshold alert, so a gradually worsening query, one that's still technically fast today but degrading as content volume grows, gets flagged well before it becomes a genuinely visible performance problem for site visitors.

A broader principle we apply beyond just the specific fixes already covered

Most database performance problems we find share a common root cause: a query pattern that worked fine at a small data volume was never revisited as that volume grew by an order of magnitude or more. This isn't really a coding mistake at the time it was written, it's a natural consequence of building for today's data size without a specific plan for reviewing that decision as the site scales.

We recommend clients treat a database performance review as a scheduled, recurring practice tied to content or user growth milestones, not just something triggered reactively once a site already feels slow. A site that's grown by 5x since its last review is due for one regardless of whether anyone has yet noticed a performance problem, since by the time it's noticeable to visitors, it's usually been degrading quietly for a while already.

This proactive framing tends to land better with clients than a purely reactive one, since it positions the work as routine maintenance tied to their own growth and success, rather than as damage control for a problem that was allowed to develop unchecked.

How caching interacts with the database fixes covered here, and why order matters

Caching and query optimization address related but distinct problems, and doing them in the wrong order can hide a real issue rather than fix it. Aggressively caching a page that's slow because of an underlying N+1 query problem masks the symptom for cached requests while leaving the underlying query just as slow for the first, uncached visitor, or for any request that legitimately needs fresh data.

We fix the underlying query performance first, then layer caching on top as an additional optimization, rather than reaching for caching as the first response to a slow page. This ordering means the site performs reasonably well even in scenarios where caching isn't helping, a cache miss, a logged-in user viewing personalized content, rather than depending entirely on cache hits to mask a genuinely slow query underneath.

Start a project

Want this applied to your site?

We run a Core Web Vitals and SEO audit before quoting any performance marketing engagement, and we're happy to share what we'd find on yours.