Let’s cause scalability problem with performance antipatterns

David Mosyan
2 min readAug 27, 2023

A performance antipattern is a common practice that is likely to cause scalability problems when an application is under pressure. Antipatterns can cause decreased response time, high latency, slow I/O calls, and other performance issues.

Many factors can cause an antipattern to occur. Sometimes an application inherits a design that worked on-premises but doesn’t scale in the cloud. Or, an application might start with a clean design, but as new features are added, one or more of these antipatterns can appear.

Removing antipatterns can improve performance efficiency. But removal isn’t a straight-forward task, because sometimes the problem only manifests under certain circumstances. Instrumentation and logging are key to finding the root cause, but you also have to know what to look for.

Here is a common scenario: An application behaves well during performance testing. It’s released to production and begins to handle real workloads. At that point, it starts to perform poorly — rejecting user requests, stalling, or throwing exceptions. The development team is then faced with two questions:

  • Why didn’t this behavior show up during testing?
  • How do we fix it?

The answer to the first question is straightforward. It’s difficult to simulate real users in a test environment, along with their behavior patterns and the volumes of work they might perform. The only completely sure way to understand how a system behaves under load is to observe it in production.

Based on the engagements with Microsoft Azure customers, Microsoft team identified some of the most common performance issues that customers see in production. Some of these antipatterns may seem obvious when you read the descriptions, but they occur more often than you might think.

Catalog of antipatterns

Busy Database — Offloading too much processing to a data store.

Busy Front End — Moving resource-intensive tasks onto background threads.

Chatty I/O — Continually sending many small network requests.

Extraneous Fetching — Retrieving more data than is needed, resulting in unnecessary I/O.

Improper Instantiation — Repeatedly creating and destroying objects that are designed to be shared and reused.

Monolithic Persistence — Using the same data store for data with very different usage patterns.

No Caching — Failing to cache data.

Noisy Neighbor — A single tenant uses a disproportionate amount of the resources.

Retry Storm — Retrying failed requests to a server too often.

Synchronous I/O — Blocking the calling thread while I/O completes.

For more information check out the sources.

Thanks for reading.

Sources:
https://learn.microsoft.com/en-us/azure/well-architected/scalability/optimize-sustain
https://learn.microsoft.com/en-us/azure/architecture/antipatterns/#catalog-of-antipatterns

--

--