Technical Guide

Database Performance Optimization for Growing Businesses

Technical
Apr 05, 20264 min readBy Cortex Team
Database Performance Optimization for Growing Businesses

The Performance Crisis Nobody Expects

Your app runs beautifully with 100 users. Then you hit 1,000 users and suddenly every query takes 5 seconds. Your database isn't broken — it's just not optimised.

This is where most Malaysian startups get blindsided. They don't budget for database optimisation because they don't realise it's needed until the problem is already hurting revenue.

The frustrating part? Almost every case we've been called into was fixable in days, not months. The work isn't hard. It's just invisible until it's urgent.

Why It Sneaks Up on You

Database performance doesn't degrade in a straight line. It falls off a cliff.

With 1,000 rows, a badly written query scans all of them and finishes in 2 milliseconds. Nobody notices. With 500,000 rows, that same query scans all of them and takes 4 seconds. Same code, same logic — the only thing that changed is your success.

That's why "it was fine last quarter" is such a common sentence in these conversations. It genuinely was.

Three Performance Killers

1. Missing indexes

An unindexed column is like searching a library without a catalogue. The book exists, but you have to walk every shelf.

If you're filtering, joining, or sorting on a column repeatedly — and you're — it needs an index. Most databases don't create them for you beyond the primary key. You have to ask.

The usual suspects in a Malaysian SME app: customer_id on the orders table, created_at on anything you report on by date, status on any queue or workflow table, and whatever column your search box hits.

A word of caution: indexes aren't free. Each one speeds up reads and slightly slows down writes, and takes disk space. Index what you actually query, not every column.

2. N+1 queries

You fetch a customer record. Then you run a query for their orders. Then another query for each order's items.

One page load becomes 100 database calls. Multiply by 1,000 concurrent users and you've saturated your database with work that could have been three queries.

This one is almost always a side effect of an ORM being convenient. The framework makes order.items look like a property when it's actually a round trip to the database inside a loop. Most ORMs have an eager-loading option that fixes it in one line — once someone notices.

3. Bad query design

Joining five tables when you need two. Fetching 10,000 rows to display 20. Sorting in application code instead of letting the database do it. Running SELECT * when you need three columns out of forty.

The fix is usually straightforward once you know which query is the problem. Finding it's the actual work.

The Optimisation Process

  1. Measure. Turn on slow query logging. Every major database has it. Let it run for a few days under real traffic and you'll have a ranked list of what's actually hurting — which is frequently not what the team assumed.
  2. Analyse. Run the query plan on your worst offenders. It'll tell you whether the database is using an index or scanning the whole table.
  3. Fix. Add indexes, restructure the query, or adjust the schema. Change one thing at a time so you know what worked.
  4. Verify. Re-run against production-sized data. Optimisations that look brilliant against 500 test rows sometimes do nothing at scale.
  5. Monitor. Set an alert on query time so the next regression finds you rather than the other way round.

The whole cycle takes a few days for a typical application.

Things That Aren't Really Optimisation

Two shortcuts get reached for early and usually shouldn't be:

Upgrading the server. Doubling your database instance size costs money every month, forever, and typically buys you 2x on a problem that indexing would have improved by 50x. Sometimes you genuinely do need more hardware — just make sure it isn't papering over an unindexed column.

Adding a cache. Caching is a legitimate tool, but caching a slow query gives you a fast wrong answer when the data changes, plus a new class of bug. Make the query fast first, then cache if you still need to.

When to Do This Work

Don't optimise a database on day one. You don't yet know your access patterns, and you'll index the wrong things.

Do it when any of these are true:

  • Your largest table is past a few hundred thousand rows
  • Page loads have noticeably slowed over the last few months
  • Your cloud database bill is climbing faster than your user count
  • You're planning a campaign or launch that will multiply traffic

That last one matters most. Optimising before a spike is a project. Optimising during one is an incident.

The ROI Is Obvious

Optimising a typical SME database costs RM5,000 - RM15,000. The result is usually queries that run 10-100x faster, which means you serve more users on cheaper infrastructure and your team stops firefighting.

That's not just a technical win — it's a smaller monthly bill and a product that doesn't frustrate the customers you worked hard to get.

Seeing your app slow down as you grow? Send us the symptoms — a slow query log and an afternoon usually tells us exactly where the problem is.

Ready to apply these insights?

Our team can help you implement these strategies and solve your specific challenges.

Schedule a Consultation

See how we implement this

Found this helpful?

Explore more guides and insights in our knowledge hub, or talk to our team about your specific needs.

Chat on WhatsApp