← All case studies

Case study 03 — Online auction platform · Innova Technologies

Auction engine performance: finding the ceiling before the bidders did.

Innova's auction engine worked. What no one could answer was how many people could be inside it at once — and what would happen on the day a marquee sale drew a crowd. We instrumented the platform, ran it until it broke, fixed what broke, and ran it again. It now carries the full user mix at 2,000 concurrent users with every journey in the green.

2,000

Concurrent users across the full traffic mix, every journey responding inside target.

20x

Live bidding capacity, from the last clean run before to the last clean run after.

98.75% → 38%

Peak database CPU on the heaviest read path, under heavier load than before.

0

Journeys left in the red at the top of the test range.

Context

The platform was fine. Nobody knew where "fine" ended.

Innova runs a live online auction platform: buyers browse inventory, register for a sale, watch lots open, and bid against each other in real time. Traffic is not evenly distributed — it is flat for days and then arrives all at once, in the ninety seconds before a lot closes. The engine had never been tested against that shape of load. It had only ever been tested against the load it happened to receive.

The engagement was not a rescue. Nothing was on fire. The question was whether the platform could absorb the growth Innova was already selling into, and the only honest way to answer it was to generate the crowd artificially and watch what gave way first.

Organization
Innova Technologies, online auction platform operator
Scope
Auction engine: browse, registration, pre-bidding, live bidding
Systems
REST API tier, real-time WebSocket layer, SQL Server production database
Engagement
Baseline load testing, bottleneck diagnosis, remediation, re-test and sign-off

Our approach

Test the way the crowd actually arrives.

Synthetic load only tells the truth if it looks like real traffic. We modelled the test around Innova's own behaviour mix rather than hammering a single endpoint, then escalated it in four steps so we could see exactly where the curve turned.

Representative

Traffic split across six real journeys, weighted the way users actually move: live auction and bidding 30%, inventory 20%, item page 15%, upcoming auctions 15%, pre-bidding 10%, registration 10%.

Escalating

Four graduated runs at a 300-second ramp: 300, 500, 1,000 and 2,000 virtual users. The ramp matters as much as the ceiling.

Instrumented

Every API measured against a two-tier threshold: above 300ms flagged for optimization, above 1s treated as a defect. Database CPU captured on the same clock.

Repeatable

Apache JMeter for scripted journeys, Azure Load Testing for cloud-scale execution. The same suite produced the baseline and the sign-off.

What broke

The API dashboard was green. The bidders were being disconnected anyway.

The application-level runs found the ceiling quickly. At 300 virtual users the platform held. By 500, live auction and bidding had crossed into critical. At 2,000 — the load Innova wanted headroom for — every single journey was over a second, including pages that had looked healthy a moment earlier.

The interesting finding was underneath that. When we stress-tested the live auction on its own, the REST APIs behind it stayed green all the way through the test range. Judged on API response times alone, the live auction looked like the healthiest part of the platform. It was the WebSocket layer that was failing: connections were established without trouble, but initializing an auction and placing a bid — the two actions that constitute the product — were failing more than one time in ten from 90 concurrent users per minute upward.

WHAT THE DASHBOARD SAWBrowseRegisterEnter auctionBidREST tier: green at every load tested.The transport carrying the bids was never in the dashboard.WHAT THE BIDDER EXPERIENCEDEstablish connectionInitialize auctionBid on a lotOver 10% failure from 90 users/minute.

Two views of the same live auction. Response-code monitoring showed a healthy engine while bidders sat in front of a frozen lot.

  • Live bidding failed first and hardest. Auction initialization and bid placement held cleanly only to 30 users per minute; failures crossed 5% at 60 and exceeded 10% from 90 upward.
  • A single read path saturated the database. Under inventory search load, production SQL Server CPU climbed to 98.75% — leaving nothing in reserve for the auction itself.
  • The failure was correlated, not isolated. Once the database was pinned, unrelated journeys degraded together. At 2,000 users, six independent pages failed simultaneously because they shared one exhausted resource.
  • Every journey had a different ceiling. Search inventory turned at 180 users/minute, item pages at 300, upcoming auctions at 480. Without per-feature testing, the platform's real capacity was whichever number happened to be lowest.

What we changed

Four fixes, each one traceable to a specific curve.

01

Relieved the database on the hottest read path

Inventory search was the largest single consumer of database CPU and the reason unrelated journeys degraded in sympathy. Query and index work on that path took peak CPU from 98.75% to under 38% — measured under substantially heavier load than the original run.

02

Rebuilt the real-time layer to scale horizontally

The WebSocket tier could not hold state for a large concurrent audience on a single instance. Reworking connection handling and message distribution took clean live bidding from 30 users per minute to 600 — the difference between a small sale and a marquee one.

03

Trimmed what the heavy pages were asking for

Item pages were making more calls, and larger ones, than the view required. Consolidating and caching the supporting requests moved the item page from degrading at 300 users per minute to clean at 1,000.

04

Left the test suite behind

The JMeter scripts and Azure Load Testing configuration were handed over as an asset, not a deliverable. The next release can be measured against the same baseline instead of against an opinion.

How the testing was governed

  • Tests were run against production-representative infrastructure, not a scaled-down replica — the numbers describe the system Innova actually operates.
  • Before and after runs used identical scripts, journey weights and thresholds; only the code and configuration changed between them.
  • Every threshold was fixed before testing began, so no result was graded after the fact.
  • After-remediation runs were pushed well beyond the point of original failure specifically to establish headroom rather than confirm a pass.

Verified capacity

Every journey green, at every load we could generate.

The re-test ran the full traffic mix through all four escalating scenarios. Inventory, item pages, pre-bidding, upcoming auctions, registration and live bidding all responded within target at 300, 500, 1,000 and 2,000 concurrent users — including the 2,000-user run where, before remediation, all six had failed together.

Live bidding (initialize + bid)

Before30 users/min

After600 users/min

20x

Inventory search

Before150 users/min

After1,000 users/min

6.7x

Item page

Before270 users/min

After1,000 users/min

3.7x

Upcoming auctions

Before420 users/min

After1,000 users/min

2.4x

"After" figures are the highest load tested, not the point of failure — the platform did not break at the top of the new range.

Impact

Capacity you can put a number on.

Before this engagement, Innova's answer to "how many users can it take?" was an estimate. It is now a measured figure, produced by a repeatable suite the team still owns.

2,000

Concurrent users carried across the full journey mix

20x

Live bidding capacity increase

98.75% → 38%

Peak database CPU on the heaviest read path

6 / 6

Journeys inside target at maximum load, from 0 / 6

<5%

WebSocket failure rate at 600 users/minute, from >10% at 90

1 suite

Reusable load test asset retained by the client

Before

Capacity was an estimate. Live bidding failed above 90 users per minute and nobody knew, because the API tier looked healthy.

After

Full traffic mix green at 2,000 concurrent users, with the real-time layer verified separately at 600 users per minute.

Ongoing

The test suite ships with the platform. Every release can be measured against the same baseline before it reaches a live sale.

Take it with you

Get the full load test report as a PDF.

The complete write-up: the scenario design and traffic weights, the before-and-after matrices for every API, database CPU and thread-count traces, and the remediation detail behind each number. Useful if you need to take a capacity claim into an engineering or procurement review.

Questions first? contact@matechnologies.net

Full case study

Auction engine load test

Enter your work email and we will send the complete write-up — scenario design, before-and-after API matrices, infrastructure traces and remediation detail.

One document, no list. We use your email only to follow up on this case study.

Want to know where your own platform stops?