Software architecture problems rarely arrive as one big outage. They arrive as small, steady changes: a page that takes a little longer each month, a release that needs a hotfix, estimates that keep getting padded. Each one is easy to explain away. Together they say the system you launched with no longer fits the business you have become.
Each of these signs shows up in a number you can already collect. This piece pairs five signs with the measure that tells you whether you have an architecture limit or an ordinary bad week, and ends with the order we would fix things in.
Speed also has a price. In April 2026 Shopify published an analysis of actively selling stores: for every 100 milliseconds slower a store loaded its main content, conversion tended to be about 3.5% lower. Shopify itself calls this a correlation, not proof of cause, and it covers online stores, so read it as a sense of scale.
The five signs and what to measure
Start with the instruments. The four golden signals from Google’s Site Reliability Engineering book are latency, traffic, errors and saturation. For delivery speed, DORA defines five measures, including change lead time and change fail rate. Here is how they map to the signs:
| Sign | What you see | What to measure |
|---|---|---|
| Pages slow down as data grows | Response times creep up, traffic flat | Latency per page over months, slowest queries |
| Busy days cause trouble | Failures during sales or campaigns | Saturation and error rate at peak |
| Small changes take weeks | Estimates keep growing | Change lead time, change fail rate |
| Everything waits on one component | One slow part slows everything | Latency and errors per dependency |
| Costs grow faster than users | The cloud or hosting bill outpaces growth | Cost per customer or per transaction |
Four of those terms in plain words:
- Saturation is how full your busiest resource is: processor, memory or database connections.
- The 99th percentile is the response time that 99 out of 100 requests come in under. It shows how bad the slow ones get.
- Change lead time is how long a finished change waits before customers get it.
- Change fail rate is the share of releases that need an urgent fix.
None of these needs a new tool. Most of the numbers are already in your cloud or hosting dashboard (your cloud provider’s console or your host’s control panel), your database or your deployment history, and cost comes from your bill. The rest of this piece takes the signs one at a time.
Pages get slower as data grows
When response times climb month after month and traffic hasn’t, look at the data layer first. That is common, not universal, so measure before you decide.
Your database can show you where the time goes. PostgreSQL’s pg_stat_statements module records how many times each SQL statement ran and the total and average time it took. It has to be switched on, which needs a server restart. Other databases have their own equivalents.
Sort by total time, not by the slowest single query. These illustrative numbers show why:
| Query | Time per run | Runs per day | Database time per day |
|---|---|---|---|
| A | 5 milliseconds | 2,000,000 | about 2.8 hours |
| B | 2 seconds | 50 | under 2 minutes |
Sorting by total time puts A first, even though each run is quick. A is what keeps your database busy all day. B is still worth fixing if customers wait on it, but it is not what is loading the database.
In our view the fix usually starts at the top of that list: add an index, ask for less data, or move a heavy report off the database your customers use.
Busy days cause trouble
A system that is fine on a quiet Tuesday but struggles during a sale is showing you its limit. Two things to check, in this order:
- How full it gets. Systems often slow down before they reach 100% (the SRE book makes this point). Track the 99th percentile of response time over a short window. A rising number is often an early sign that you are nearing the limit.
- What your software does when something is slow. Retries add load to a server that may already be struggling, and can keep the load high after the original problem is fixed. An Amazon engineering article on timeouts and retries recommends limiting retries, waiting longer between them, adding randomness so clients don’t all retry at once, and retrying at one layer only.
Retrying at every layer multiplies the load. These numbers are illustrative: if each layer tries up to three times, the number of attempts grows like this as the request moves down the chain.
Retrying at one layer keeps it at three. So a busy-day failure can be a small overload that the retries made worse, which is worth checking before you buy bigger servers. To rehearse a busy day, see our guide to getting your app ready for a traffic spike.
Small changes take weeks
When a simple feature gets a three-week estimate, or every release breaks something unrelated, the code may be tangled. Parts that should be independent depend on each other in ways nobody fully remembers.
Two numbers show it: change lead time and change fail rate, both defined above and both tracked by DORA. Our reading is that tangled code makes both worse. Changes ship slower, and more of them go wrong.
Record both for a quarter. If lead time is long and the fail rate is high, pick the kind of change that hurts most and trace what it touches. If one small change reaches into many modules, that suggests a boundary is in the wrong place.
Everything waits on one component
Many products have one part that everything else leans on: an order job, a partner integration, a PDF service. When it slows down, everything that calls it slows down too.
There are two defences:
- Set a timeout on every call to it, based on measured latency, so one slow part can’t hold up the whole product. The same Amazon article gives this advice.
- Put it behind a queue with its own retries and its own scaling. In our view this takes the most pressure off.
Measure latency and errors for each dependency first, so you know which one it is.
Costs grow faster than users
If your cloud or hosting bill is growing faster than your customer base, it is worth checking whether the system is doing work it doesn’t need to. The way to see it is a unit cost: what you spend per customer, per transaction or per order. The FinOps Foundation’s unit economics page lists examples: “per million authorized users, per transaction, per customer, or per case resolved.” Pick one that fits your product and chart it every month.
- Unit cost is flat: a bigger bill just means you grew.
- Unit cost is climbing: find the largest line item and ask what changed. In our view the usual suspects are servers sized for a peak that happens twice a year, the same result recomputed instead of cached, and data moved around for no reason.
AWS’s cost guidance describes right-sizing as “an iterative process”, triggered by changes in usage. It adds that right-sizing can be a one-off if the effort outweighs the savings over the life of the workload. Cost and speed problems often share causes, so in our view a fix for one tends to help the other.
What to do about it
Put the five measures in place before you change any code. In order:
- Record a baseline. Collect the table’s measures for four to six weeks, including at least one busy period.
- Rank the signs by business impact. A slow checkout usually matters more than a slow admin page.
- Fix the cheapest causes first. Query tuning, caching and moving heavy work into background jobs cost less than restructuring code in our view, and your measures will show quickly whether they worked.
- Isolate the one component everything waits on, with timeouts and limited retries.
- Re-architect a specific component only if the numbers show it is the limit. Make it a targeted decision backed by measurements, not a reaction to general frustration with the codebase. For a bigger move, see rewriting or modernizing. For a second opinion on the numbers, our performance and scalability work is the place.
Pick the one sign that costs you most this month, find its measure in the table, and write down today’s number. Check it again in four weeks. If it is moving the wrong way, you have a target for the first fix, and a baseline to prove the fix worked.
Sources
- Google: Site Reliability Engineering, Chapter 6, Monitoring Distributed Systems
- DORA: Software delivery performance metrics, last updated 5 January 2026
- PostgreSQL documentation: pg_stat_statements
- Amazon Builders’ Library: Timeouts, retries and backoff with jitter, 5 December 2019
- Shopify: Store speed and conversion, 27 April 2026
- FinOps Foundation: Unit Economics capability
- AWS Well-Architected Cost Optimization Pillar: Select the correct resource type, size, and number
Frequently asked questions
How do I tell an architecture problem from a slow week?
Look at trends over months, not one bad day. Latency that climbs with the size of your data while traffic stays flat points at the data layer. Failures only at peak times point at limits under load. Long lead times and a high share of releases needing a fix point at tangled code. A single spike with a known cause usually isn't an architecture problem. This is our reading of the signs, so confirm it against your own numbers.
What should I monitor first?
The four golden signals from Google's Site Reliability Engineering book: latency, traffic, errors and saturation. Latency is the time it takes to service a request. Traffic is how much demand the system is under. Errors are the rate of requests that fail. Saturation is how full your most constrained resource is. The book advises tracking the latency of failed requests separately from successful ones.
What are DORA metrics?
Five measures of software delivery published by the DORA research programme. Change lead time is the time from a change being committed to version control to being deployed in production. Deployment frequency is how often you deploy. Failed deployment recovery time is how long it takes to recover from a failed deployment. Change fail rate is the share of deployments that need immediate intervention. Deployment rework rate is the share of unplanned deployments made because of a production incident.
How do I know if my cloud or hosting bill is growing too fast?
Compare it with something the business cares about. The FinOps Foundation suggests tracking technology cost against revenue, or per transaction, per customer or per million users. Pick one unit, chart it monthly, and look at the trend. A bill that rises while the unit cost stays flat is growth. A bill that rises because the unit cost is climbing is the thing to investigate.
Do I need to rewrite the system?
Usually not as a first step. Measure, fix the cheapest causes first, and only re-architect a specific component when the numbers show it is the limit. That is our view, and it is the reason the last section of this article is a short sequence of steps and not a project plan.



