← BLOGHOME↗

Sep 16, 2025 · 4 min read · Production, Reliability, and Scale

When the Services Were Healthy but the Workflow Was Slow

Every health check was green, but an important workflow was too slow for the users. The services were available, but that didn’t mean the operation was usable.

On an enterprise platform at Softcraft, we had a period when the application was technically available. The services were running. Health endpoints returned successfully. The database accepted connections, and infrastructure dashboards didn’t show a complete outage. Users were still struggling with an important workflow because requests had become slow and inconsistent during heavier periods. According to the uptime metric, the system was healthy. For the people waiting for this workflow, it wasn’t.

What Users Could Actually Do

Infrastructure availability matters. A service that’s not running can’t help anyone. But a running service is only the first layer of reliability. If an API responds after the user already tried again, the response may be successful but useless. If one step in a workflow continues timing out, the rest of the platform being healthy doesn’t solve the user’s problem. If data is old, a fast page can still lead to the wrong decision. “Is the system up?” wasn’t enough. We also needed to know if people could complete the operation the system existed to support.

The Complete Workflow

The workflow crossed application code, database queries, and internal integrations. Each component looked acceptable when viewed separately. The problem appeared in their combined behavior under real usage. A slower query increased the time a request held resources. Concurrent requests added pressure. A dependent call contributed additional variation. No single component had failed completely, so no binary health check could explain the experience. We needed measurements that followed the business operation: end-to-end latency, error rates for the specific workflow, and behavior during the periods when users reported problems. Once we looked at the operation instead of only the infrastructure, the priorities became clearer.

We compared the faster and slower executions instead of looking only at a daily average. The slow requests were concentrated in periods with more concurrent work and in cases that loaded a larger history. That connected the user reports to specific database and integration behavior. Without separating those requests, the normal traffic made the average look acceptable and the problem seemed less consistent than it really was.

Support reports helped us identify which part of the workflow users considered blocked. An API request might eventually finish, but if the next screen depended on it, a long delay stopped the person from continuing. That context affected which latency we considered acceptable. The technical timeout was not the same as the point where the product had already become unusable.

The Signals We Were Missing

Technical metrics are most useful when they connect to something the user is trying to do. CPU usage can help explain a slowdown, but it doesn’t tell us whether a case was registered successfully. Queue depth matters, while the age of the oldest business operation may communicate the urgency more clearly. An average response time can look healthy while a smaller group of users experiences severe delays. We started paying attention to the slowest requests in critical workflows alongside the broad averages. We also connected technical failures with operation identifiers so support reports could lead to evidence instead of guesses. Infrastructure monitoring remained in place and we added the missing view of whether an important operation was usable. If a core workflow is consistently timing out, calling the platform fully operational creates confusion even if every service process is running. We started defining service objectives around successful operations and acceptable latency as well as process uptime.

We added a view of the workflow latency by range instead of one average number and tracked how many operations completed inside the time users normally expected. The service could stay available while that percentage dropped, which gave us a degradation signal before the error rate changed significantly. After improvements, the same view showed whether the slowest group was getting better rather than hiding behind faster requests.

Our dashboards correctly showed that the processes were running, the database accepted connections and the infrastructure hadn’t failed completely. They had no measurement for the part users were complaining about. After we added the complete workflow, the reports from users and the technical data described the same slowdown.