1–2 spots available for Q2 · Claim yours

How to Fix Your Slow Website Without Rebuilding It

A real case study of how I cut API response times from 3 seconds to 300ms at Cuez — without rebuilding the product. Step-by-step diagnostic walkthrough for non-technical founders, with a checklist you can use today.

By Adriano Junior

The trap most founders walk into

Your website is slow. Your customers know it. And someone on your team has probably already said the words you were dreading: we need to rebuild the whole thing.

I hear this a lot. A founder calls because their web application takes three or four seconds to respond. The developer says the codebase is a mess and the only path forward is starting from scratch. Six figures. Six months. Maybe more.

After 16 years and 250+ projects, here is what I have learned about website performance optimization: most slow websites do not need a rebuild. They need a diagnosis. The problem is almost never "the whole thing." It is usually three to five specific issues hiding in plain sight, and fixing them takes weeks instead of months.

I am going to walk through how I did this for a real client. Cuez by Tinkerlist runs a SaaS platform for broadcast and live-event production. Their API took 3 seconds to respond. I got it down to 300ms — 10x faster — with about 40% less infrastructure cost. No rebuild. The full story is in the Cuez API optimization case study.

This is the detective story.


TL;DR

A slow website rarely needs a full rebuild. At Cuez by Tinkerlist, I cut API response times from 3 seconds to 300ms — 10x faster — with around 40% infrastructure cost reduction, by running a full codebase scan and fixing five specific things: dead libraries, custom code that should have been framework built-ins, database queries with missing indexes and N+1 patterns, no caching layer, and a tangled dependency graph. Total time: weeks, not months. Total cost: a fraction of a rebuild. The diagnostic process below works for any web application running on a maintained stack.


Table of contents

  1. The "rebuild" trap (and why I usually argue against it)
  2. The Cuez case study: 3 seconds to 300ms
  3. Step 1: the codebase scan
  4. Step 2: removing dead weight
  5. Step 3: replacing custom code with built-ins
  6. Step 4: fixing the database
  7. Step 5: untangling dependencies
  8. The results (and what they meant for the business)
  9. The diagnostic checklist: is your site fixable?
  10. What a fix costs vs. what a rebuild costs
  11. Reflecting on what makes optimization stick
  12. FAQ
  13. Next steps

The "rebuild" trap (and why I usually argue against it)

When a web application is slow, the instinct is to start over. Fresh code, new framework, clean architecture. It sounds logical. In my experience it is usually wrong.

Here is why rebuilds tend to fail:

They take longer than promised. A four-month rebuild stretches to eight or twelve. The old system had hidden complexity nobody documented, and rebuilding means rediscovering every edge case the hard way.

They cost more than the budget. $100K becomes $200K. The new system has to do everything the old one did, plus the new features that justified the work in the first place.

They introduce new bugs. The current system, slow as it is, works. Real users have hammered it for years. A rebuild resets the QA clock to zero.

The real problem survives the rebuild. This is the one that gets me. If the team does not understand why the old system was slow, they will repeat the same mistakes in the new one. I have seen companies rebuild and end up back where they started 18 months later.

The alternative is what I think of as surgical optimization. Find the specific things causing the slowness and fix them. Faster, cheaper, lower risk. And it forces the team to actually understand the system, which is what makes the fixes stick.

If you want a wider-angle take on speed and revenue, my website speed optimization guide walks through the math.


The Cuez case study: 3 seconds to 300ms

Cuez is a SaaS product by Tinkerlist. Television producers and live-event managers use it to run their shows — scripts, rundowns, timing, media. It is a real-time tool. If a live broadcast tool lags, the show falls apart.

When I joined the team, the loudest complaint from users was speed. The API was averaging 3 seconds per response. For a tool used during live television, that is not a quirk. That is a problem you cannot ship around.

The development team had already discussed a full rebuild. New framework, new architecture, six-plus months. During that time the existing product would still be slow, and the team would be split between maintaining the old system and shipping the new one.

I suggested a different order of operations: give me a few weeks to investigate the existing codebase first. If the problems are fixable, I fix them. If the codebase is genuinely beyond saving, the team can still rebuild — but they will at least know what went wrong, so they do not repeat it.

They agreed. Here is what I found.


Step 1: the codebase scan

A codebase scan is like a home inspection before you decide whether to renovate or tear the house down. You walk every room, check the foundation, look at the plumbing, and figure out what is actually broken versus what just looks tired.

I spent the first week reading code. Not writing it. Reading it. Looking for the patterns that experienced engineers learn to spot.

Here is the analogy I use with founders: imagine you run a restaurant and the kitchen is slow. Before you gut it and rebuild, you watch the cooks for a week. You notice:

  • Three blenders on the counter, but two are broken and nobody uses them. They just take up space.
  • The head chef insists on making his own ketchup from scratch. The bottled version is identical and takes zero time.
  • Every time someone orders a steak, the cook walks to the freezer, checks inventory, walks back, starts cooking, then walks to the freezer again to check a different item. The same trip, twice.
  • The pantry has 47 spice jars but most dishes use 5 of them. The rest expired in 2019.

That is what I found in the Cuez codebase. Not a broken kitchen. A kitchen full of unnecessary stuff, redundant processes, and inefficient routines.


Step 2: removing dead weight

The first thing I did was audit every code library the project depended on. A library is a pre-built package of code — date formatting, validation, file handling, things developers reach for to avoid writing common functionality from scratch.

The Cuez project had accumulated libraries over years. Some were added by developers who had left long ago. Some were outdated, with maintainers who had stopped shipping updates, which meant they were slower and less secure than newer alternatives. Some were simply unused. Installed once for a feature that was later removed, but the library itself was never cleaned up.

This matters for performance because every library adds weight. When the server processes a request, it loads all of these into memory. Unused libraries sit there consuming resources, like 30 browser tabs open in the background. Each one is small. Together they slow everything down.

I removed every library that met one of these criteria:

  1. Unused. Installed but never referenced anywhere in the actual code.
  2. Outdated. No longer maintained, with known performance issues.
  3. Redundant. Doing something that another library, or the framework itself, already handled.

The result was a leaner application that started up faster and consumed less memory per request. By itself this did not solve the 3-second problem. But it set the stage for everything else.


Step 3: replacing custom code with built-ins

This is the homemade-ketchup problem.

Laravel — the PHP framework Cuez was built on — has built-in tools for common tasks. Caching, job queues, data serialization, authentication. These tools are optimized by a large open-source community. Fast, well-tested, maintained by hundreds of contributors.

But over the years, previous developers at Cuez had written custom versions of some of these tools. Sometimes because the built-in did not exist when the code was first written. Sometimes because a developer did not know the built-in existed. Sometimes because someone preferred their own approach. None of these reasons are villainous. They just compound over time.

Custom code rarely keeps up with framework improvements. Laravel's caching system has been refined over dozens of releases by people whose full-time job is making it fast. A custom caching layer written three years ago by a single developer? It works. It is not going to match that level of optimization.

I identified several areas where custom implementations could be replaced with Laravel built-ins:

  • Data serialization. Converting database records into the format the API sends to users. Switched to Laravel's native API resource classes.
  • Query building. Replaced raw SQL strings with Laravel's query builder, which automatically optimizes a lot of common patterns.
  • Response caching. Replaced a homegrown caching layer with Laravel's built-in cache backed by Redis.

Each replacement was a targeted swap. The behavior stayed the same. The performance improved because the new code was simply better optimized.


Step 4: fixing the database

This was the biggest single fix. If library cleanup was organizing the pantry, and the framework swap was switching to bottled ketchup, this step was repairing the broken refrigerator. The thing actually causing most of the delay.

The problem is something developers call N+1 queries. Plain-language version:

A user opens their dashboard. The screen needs to show 50 shows, each with its producer name and schedule. The efficient way to load this data is one trip to the database: "Give me all 50 shows with their producer names and schedules." One question. One answer.

The N+1 way is: "Give me the list of 50 shows." Then, for each show: "Who is the producer of show #1?" "What is the schedule for show #1?" "Who is the producer of show #2?" And on, and on. That is 1 query for the list plus 100 more for the details. 101 round-trips instead of 1.

Each round-trip to the database costs time. Typically 5 to 50 milliseconds. Multiply by 101 and you get 500ms to 5 seconds just waiting for the database. That alone can explain a 3-second response time.

I refactored the critical API endpoints, about 15 of them, focusing on the ones that handled most of the traffic. Each was rewritten to use proper joins and eager loading. Instead of 100+ database queries per request, most endpoints made 2 or 3.

Then I added database indexes. An index is like a table of contents for your database. Without one, the database scans every row in the table to find what it is looking for, like reading an entire book to find one paragraph. With an index, it jumps straight to the right page. Adding indexes to the most frequently queried columns dropped individual query times from 400ms to under 50ms.

Google's web.dev guide on database performance puts it well: every byte and every round trip you can avoid is one fewer thing standing between your user and a working app.


Step 5: untangling dependencies

The last step was reducing the web of connections between different parts of the system. Over time, features had become entangled. Changing one part of the code could unexpectedly affect another, and the system was doing more work per request than it needed to because of these hidden connections.

I restructured the code to make boundaries between features clearer. Each API endpoint loaded only the code it actually needed, instead of pulling in the entire application's logic. This is the software equivalent of making sure that when you order a salad, the kitchen does not also fire up the grill, preheat the oven, and warm up the fryer just because they all happen to live in the same building.

Combined with the caching layer from Step 3, where frequently requested data was stored in Redis so the server did not recalculate it every time, the system was now doing dramatically less work per request.


The results (and what they meant for the business)

Here is the before and after:

Metric Before After Change
Average API response time 3,000ms 300ms 10x faster
Database queries per request 100+ 2–3 ~97% fewer
Infrastructure cost Baseline ~40% lower Lower hosting bill
Concurrent user capacity Limited ~10x improvement Room to grow

The business impact went past the speed numbers.

Infrastructure costs dropped about 40%. Fewer database queries means less compute. The server was doing 97% less database work per request, which translated directly to a smaller monthly hosting bill.

The platform could carry more users. Before optimization, heavy traffic periods made things slower. After optimization, the same servers supported roughly 10 times more concurrent users, which meant the sales team could grow the customer base without worrying about the platform falling over.

User satisfaction climbed immediately. When a tool responds in 300ms instead of 3 seconds, people notice. The team stopped getting speed complaints. For a product used during live television production, that is not a small quality-of-life upgrade.

Total time to fix: a few weeks of focused work, spread across investigation and implementation.

Compare that to the rebuild option: 6+ months, during which the existing product would have stayed slow, the team would have been split between maintaining the old system and building the new one, and there would have been no guarantee the new system would perform any better without doing this exact diagnostic work first.

The pattern is similar to what I describe in the Imohub real-estate portal case study: 120k+ properties, sub-500ms query response, 70% infrastructure cost reduction. Surgical work beats rebuilds in real-world budgets.


The diagnostic checklist: is your site fixable?

Not every slow website can be fixed without a rebuild. Most can. Here is how to tell.

Signs your site needs optimization (not a rebuild)

  • It was fast at launch and has slowed gradually over time
  • Performance degrades under load (more users = slower)
  • Some pages are fast, others are slow
  • The core features still work correctly — they are just slow
  • The technology stack is still actively maintained (Laravel, React, Node.js, NestJS, Next.js)

Signs the site might actually need a rebuild

  • The framework or language has been abandoned (no security updates)
  • The original developers are gone and nobody understands the code
  • Business requirements have shifted so far that the current architecture cannot support them
  • You have already tried optimization and it did not move the needle

Five questions to ask your developer

  1. "How many database queries does our main page make?" If the answer is over 50, you probably have N+1 problems.
  2. "Are we using a caching layer?" If the answer is no, that is usually a quick win.
  3. "When was the last time we audited our dependencies?" If nobody remembers, there is dead weight.
  4. "Are we using the framework's built-in tools, or did we write custom versions?" Custom is not bad. It is a flag worth investigating.
  5. "What does our application performance monitoring show?" If you do not have APM, that is step one. You cannot fix what you cannot measure. My guide to measuring website performance covers the tooling.

For a stricter, numbers-first approach to keeping the wins, see my piece on performance budgets for founders.


What a fix costs vs. what a rebuild costs

I am a consultant. Honest numbers, then.

Approach Typical cost Timeline Risk Downtime
Performance audit + optimization $5,000 – $25,000 2–6 weeks Low None (live system)
Partial refactor (hot paths only) $15,000 – $50,000 1–3 months Medium Minimal
Full rebuild $80,000 – $300,000+ 4–12 months High Significant

The optimization approach has a second advantage on top of cost. You get results incrementally. After the first week of work at Cuez, response times dropped from 3 seconds to about 1.5. The team and users felt the improvement straight away, which built confidence that the approach was working.

A rebuild gives you nothing until it is done. You are investing for months before you see any return. Industry data from McKinsey's research on large software programs shows that 17% of large IT projects go so badly they threaten the existence of the company. The optimization path avoids most of that downside.

For my clients, I usually start with a focused performance audit similar to what I described in Steps 1 and 2. It produces a clear report of what is wrong and what each fix will cost. You make a decision based on data, not guesswork. Book a free strategy call.


Reflecting on what makes optimization stick

The technical work is the easy part. What is harder, and what determines whether the wins last, is the discipline that follows.

Every codebase tends back toward entropy. Libraries get added under deadline pressure. Custom code accumulates because it feels faster than reading the framework docs. Database schemas drift. Six months after an optimization, you can be staring at the same kind of slowdown if nobody is watching for it.

The teams I work with who keep their gains do three things. They monitor what they care about (real-user metrics, p95 response times, database query counts). They set performance budgets and treat them like product requirements, not nice-to-haves. And they invest a small amount of engineering time per quarter on cleanup work, which is not glamorous but pays for itself.

The Cuez fix held because the team built habits around it. That is the part of the work I cannot do for you in eight weeks. What I can do is leave you with a system that is fast, a clear map of why, and the operating rhythm that keeps it that way.


FAQ

How do I know if my website is actually slow?

Run your site through Google PageSpeed Insights (free). If your performance score is below 50, or your Largest Contentful Paint is above 4 seconds, your site has a measurable speed problem. Also check your analytics for bounce rate. If more than 50% of mobile visitors leave before the page loads, speed is likely the cause. My website speed optimization guide explains how to read the metrics.

How long does a performance optimization take?

Most optimization projects take 2 to 6 weeks. The first week is diagnostic — reading code, profiling queries, identifying bottlenecks. The rest is implementation. Simple fixes like adding caching or fixing obvious N+1 queries show results within days. Deeper structural work takes longer but rarely passes 6 weeks for a typical web application.

Will optimization break anything on my site?

The risk is much lower than a rebuild. Each change is targeted and testable. I work on one issue at a time, deploy, verify, then move on. If something breaks, you roll back one small change instead of an entire system. At Cuez we deployed optimizations incrementally with zero downtime and no user-facing bugs.

What if optimization does not work and I still need a rebuild?

Then you rebuild — but you rebuild smarter. The diagnostic work is never wasted. If the audit shows the architecture genuinely cannot be optimized, you now have a detailed map of what went wrong. That map becomes the blueprint for the rebuild, and you avoid repeating the same mistakes. In my experience, a large majority of "we need a rebuild" situations turn out to be fixable with optimization first.

Can I do this myself, or do I need to hire someone?

If you have a developer on staff, they can handle the basics: run a query profiler, check for missing indexes, audit unused dependencies. The checklist above is a starting point. For deeper work, like restructuring queries across 15+ endpoints, replacing custom code with framework built-ins, or implementing a caching strategy, you usually need someone who has done it before. Pattern recognition is what makes the work take weeks instead of months. My custom web application service and fractional CTO retainer both cover this kind of engagement.

What is the ROI of website performance optimization?

It depends on your traffic and conversion model, but the math is straightforward. The often-cited Akamai and Cloudflare research suggests every 1-second improvement in load time can lift conversions by around 7%. If your site does $50,000/month in revenue and you cut load time by 2 seconds, that is roughly a 14% conversion lift — about $7,000/month, or $84,000/year. The Cuez optimization cost a fraction of what a rebuild would have, and the impact was visible within weeks.

Does an optimization fix work for any framework, not just Laravel?

Yes. The principles apply to React, Next.js, Vue, NestJS, Express, and most maintained frameworks. Every codebase accumulates unused dependencies. Every database can be queried more efficiently. The methodology — audit, remove, replace, optimize — is portable. My API integration article shows the same pattern in a different setting.


Next steps

If your website or web application is slow, here is what I recommend, in order:

  1. Measure first. Run Google PageSpeed Insights on your key pages. Write down the scores. If you have application performance monitoring (New Relic, Datadog, Vercel Analytics, Laravel Telescope), pull average response times and slowest endpoints.
  2. Ask the five diagnostic questions. Your team should be able to answer them inside a day or two.
  3. Do not default to "rebuild." If your stack is modern, your core features work, and the slowness developed over time, optimization is almost always the right first move.
  4. Consider a professional audit. I do exactly this kind of work. I will audit your application, identify the bottlenecks, and give you a clear report with costs and timelines for each fix before you commit to anything.

For the wider story on speed and revenue, read my website speed optimization guide. If your performance problems are tied to a growing application that needs architectural guidance, my fractional CTO service is probably the right fit. And if you are choosing between a custom web application build and an off-the-shelf SaaS tool, see custom web app vs SaaS.

Related Articles

All posts