← All notes

EdTech

Results day is a load test you are not allowed to fail

Every student in the cohort loads the same page in the same ten minutes. Average traffic tells you nothing about the only moment that matters.

  • Invexa Technologies
  • 2 min read

Learning platforms have gentle traffic. A few hundred concurrent users, a smooth daily curve, comfortable headroom. Then results are published at 9am and every student, every parent, and half the staff hit one endpoint simultaneously.

The system that has been fine for a year falls over in ninety seconds.

The shape is a spike, not a curve

Ordinary capacity planning assumes load grows and you scale with it. Results day is different: it is a step function with no ramp. Autoscaling reacts in minutes; the spike is over in ten, and the failure happens in the first thirty seconds while new instances are still booting.

You cannot scale into it. You have to already be able to serve it.

Precompute the payload

At the moment of publication every student’s result is fixed. It will not change while they are reading it. So it should not be assembled per request.

Generate each student’s result document when results are finalised — before publication — and store it as a single row keyed by student. The request becomes one primary-key lookup returning a blob. No joins, no aggregation, no permission tree walked per request.

The expensive work happens once, an hour early, against a system nobody is using.

Publish by flipping a flag, not by writing data

The release itself must be instantaneous and reversible. A published_at on the assessment, checked at read. Setting it exposes precomputed rows that already exist; unsetting it hides them again if something is wrong.

Writing the results at publication time is the version that fails, because the write load and the read spike arrive together.

Queue the things that can wait

Notification emails, parent SMS, analytics rollups, PDF generation — none of that needs to happen in the request. Push it onto a queue and let it drain over the following hour. The student sees their result in 200ms; the PDF arrives when it arrives.

Test at the real number

Load test with the actual cohort size in the actual window. Not 10% and extrapolate — the failure modes at 5,000 concurrent are connection pool exhaustion and cache stampede, and neither appears at 500. If you cannot generate that load, at minimum verify the read path is a single indexed lookup, because that is the property that makes the spike survivable.

Next step

Have a project in mind?

A 30-minute call is usually enough to know whether we are the right team for it. If we are not, we will say so.

Start a project

Replies within one working day