QAreMed
MenuClose

Guide

Performance testing a patient portal at peak load

Peak load on a patient portal arrives as a step at a moment somebody else picked: a results release, an open enrolment window, an appointment drop, an outage in the clinic. Model each event on its own clock, treat chart assembly as the expensive request, and hunt the partially rendered record, which returns HTTP 200 and still loses data.

Written for
For a CTO
Last revised
10 September 2026

What makes peak load on a patient portal different from load on any other web product?

The peak has an owner, and the owner is rarely you. Four events put a step into a portal's traffic, and each one is scheduled by a system or a person outside the engineering team.

  • A results release. A batch of laboratory results is posted to patient records and a notification goes out with it. Everybody who receives one opens the same view in a short window.
  • An open enrolment window. A date fixed by a plan year drives sign-in and document upload for a fixed number of days.
  • An appointment drop. New slots are published, and the patients who wanted them arrive at the same second.
  • An outage somewhere else. A clinic telephone system or a call centre goes down, and the portal becomes the only route to a clinician.

None of these is a growth curve. A curve gives you months to provision against it. An event gives you the interval between the notification going out and the first request arriving, which is why a portal can carry steady traffic for months and fail on the first morning an event lands on it.

The second difference is where the work happens. A retail page assembles itself from stores you own. A portal view of a clinical record assembles itself from a certified API in an electronic health record system that belongs to a hospital or a vendor, and the criterion that puts it there is 45 CFR 170.315(e)(1), View, download, and transmit to 3rd party, which is the portal-facing capability in the ONC Health IT Certification Program criteria. What breaks in a patient portal covers the functional side of that boundary. This page is about what it does under a step.

Where does the number you are testing against come from?

From the organisation that ships the portal, because no rule supplies one. The HIPAA Security Rule names no testing technique at all: reading 45 CFR 164.302 through 164.318 in full, there is no reference to load testing, penetration testing, vulnerability scanning, static analysis, code review or test environments. Its general requirement at section 164.306(a)(1) asks that the confidentiality, integrity and availability of electronic protected health information be ensured, and stops there.

That makes the target yours to set, and it makes the justification a written artefact somewhere else in the file. Two addressable implementation specifications of the contingency plan standard are where a load figure gets its source. section 164.308(a)(7)(ii)(E), Applications and data criticality analysis, is where a portal is ranked against the other applications an organisation runs. section 164.308(a)(7)(ii)(D), Testing and revision procedures, asks for procedures for periodic testing and revision of contingency plans. Three parts of the same standard are Required instead of addressable: the data backup plan at (a)(7)(ii)(A), the disaster recovery plan at (a)(7)(ii)(B) and the emergency mode operation plan at (a)(7)(ii)(C). The emergency mode plan is the one a portal peak collides with, because the fourth event in the list above is somebody else's emergency mode becoming your traffic.

Two more clauses accept the output. section 164.308(a)(1)(ii)(A) Risk analysis is Required and asks for an accurate and thorough assessment of risks to availability, which is the same word the peak threatens. section 164.308(a)(8) Evaluation is a Required standard and asks for a periodic technical and nontechnical evaluation. A peak run with a dated report is technical evidence for both, which is set out further in what the HIPAA Security Rule can be tested against.

Testing that peak does not need real patients in it. We do not need production PHI to test. Environments run on synthetic and de-identified data. A peak run is one of the easier cases for that, because the load generator cares about the shape and the size of a record and not about whose record it is; the positions behind it are set out under how we work with protected health information.

Which request is the expensive one?

The one that assembles a chart. A portal view of a problem list, medications, allergies and recent results is a set of reads against profiles in a certified API, and 45 CFR 170.315(g)(10)(i)(A) requires the server to respond to a request for a single patient's data with every data element indicated as "mandatory" and "must support" by the standards it adopts, including the mandatory capabilities described in the US Core Server CapabilityStatement. One patient opening one screen fans out into several of those.

Transport is the smaller part of the cost on the far side. The FHIR R4 specification says so in its own words on validation: "Validation, particularly full validation including terminology, can be quite computationally demanding. This can impose unacceptable time delays in a production system." A server that validates on the way out has a per-request cost that scales with the size of the record, so a patient with a long history is a heavier request than one enrolled recently. Populate the generator accordingly. The conformance machinery behind that response is covered in FHIR R4 conformance testing requirements.

Three other populations share that endpoint, and a peak model that leaves them out understates what the server is doing.

Three populations sharing a patient portal's certified FHIR API at peak, each traced to the 45 CFR Part 170 provision it comes from.
Who else is on the APIWhere it comes from
Bulk export of multiple patients as a group45 CFR 170.315(g)(10)(i)(B), responding according to the standards at 45 CFR 170.215(a), (b)(1) and (d)
Third party applications the patient connected45 CFR 170.404(b)(1)(ii), which requires a Certified API Developer to register and enable applications for production use within five business days of verifying an API User's authenticity
Directory consumers reading service base URLs45 CFR 170.404(b)(2), which requires service base URLs to be published as FHIR Endpoint and Organization resources in a Bundle and reviewed quarterly

An application registered under that rule polls on its own schedule and knows nothing about your results release. The tests that establish whether the integration works at all are a separate exercise, described in how an EHR integration is tested; a peak run assumes those passed and asks what the same path costs when the whole notified population walks it at once.

In what order does a peak run go?

  1. Write the event catalogue. For each event record the trigger, who owns the clock, which patients receive it, and the first screen they open.
  2. Ask the owner of each event for its population. Take the figure from the notification system that sends it. Do not estimate it.
  3. Trace the first screen to its reads. List every profile the screen needs.
  4. Build the record mix. Include long histories, empty records, and records that hold data the portal must render but did not create.
  5. Instrument the boundary. Measure the certified API call separately from the portal response.
  6. Run one event at a time first. A mixed run hides which event caused a failure.
  7. Run the collision case. Start a bulk export while a results release is in progress.
  8. Repeat the run with the session timer active. See the fourth question at the foot of this page.
  9. Re-run the catalogue when the API version changes on either side.

Step 9 has a schedule attached to it that a portal team does not control. The version of US Core named in the regulation for the certified API criterion is one thing, and newer versions become available separately through the Standards Version Advancement Process, which ran a 2026 cycle usable from 29 August 2026. A server that moves to a newer approved version changes what it returns, and a response that carries more elements is a heavier response.

What counts as a failure when the page still returns 200?

A chart that rendered without everything in it. FHIR R4 makes OperationOutcome Normative from v4.0.0 and lists five circumstances of use, one of which is "as part of a search's Bundle response containing information about the search". A degraded server can therefore return a valid Bundle, a 200 status and an OperationOutcome saying the search was incomplete. The specification's own guidance to implementers points the same way: "an implementation should be conservative in its sending behavior, and liberal in its receiving behavior." A liberal client renders what arrived. Under load, what arrived is short.

The assertion in a portal peak test therefore sits on the content of the screen. A status code and a render time both pass while this failure happens. Three checks belong in the run:

  • Compare the rendered medication list, allergy list and result set against the fixture the generator seeded. A missing row at high concurrency is the defect.
  • Assert that an OperationOutcome inside a Bundle reaches the patient as a visible statement that the record is incomplete.
  • Assert the same for a timeout on one read inside a multi read screen.

The accessibility criteria that govern those messages are ordinary Level A and AA criteria that only fail when the system is slow. 4.1.3 Status Messages is Level AA and is one of the twelve Level A and AA criteria added in WCAG 2.1. 3.3.1 Error Identification is Level A. 2.2.1 Timing Adjustable is Level A and becomes live the moment a session timer competes with a slow chart assembly. A spinner that never resolves and announces nothing fails a criterion the portal already claims, which is why an accessibility run on an idle system misses this class entirely; the version and level questions behind that claim are set out in the WCAG 2.1 Level AA requirements.

Two more subsystems change the arithmetic. Audit controls at section 164.312(b) require mechanisms that record and examine activity in information systems containing or using electronic protected health information, so every one of those reads writes a record, and the audit store is under the same peak as the portal. Automatic access time-out is a certification criterion in its own right at 45 CFR 170.315(d)(5). Test both with the load on, because both are usually tested with a single user and a stopwatch.

What does the run hand over?

Five records, each tied to something that already exists in the organisation's file.

The five records a patient portal peak load test run hands over, each with the question it answers.
RecordWhat it answers
The event catalogueWhich peaks exist, who schedules each one, and how many people each reaches
A per-event report with the run date, the record mix and the concurrency usedWhat was measured, under which conditions, so a later run is comparable
The boundary measurementHow much of the response time belongs to the certified API and how much to the portal
The partial render defect listWhich screens lost clinical content while returning a success status
The collision run resultWhat happens when a bulk export and a patient peak overlap

Those feed the risk analysis at 45 CFR 164.308(a)(1)(ii)(A) and the periodic evaluation at 45 CFR 164.308(a)(8) as technical evidence with a date on it. Compliance stays with the organisation that ships the portal. The run produces the measurements and the artefacts it is assessed with.

Which parts of a peak result mislead you?

A percentile taken over a mixed workload misleads first. Chart assembly and a static content page in the same bucket produce a 95th percentile that describes neither. Split the workload by screen before reading anything.

A green synthetic monitor misleads next. If it reads the capabilities endpoint, it exercised the one interaction every FHIR server is required to support and nothing a patient uses.

A run against a stubbed API. The stub returns the shape and skips the validation, the terminology lookup and the record size, which is where the cost was.

A run with audit logging disabled in the test environment. The write path under section 164.312(b) is part of the load, and switching it off in the rig moves the bottleneck somewhere it will not be in production.

A single event run presented as a capacity statement. The events in the catalogue overlap in real weeks, and the collision run is the one that produces the number worth quoting.

What do buyers ask about this?

Does any rule set a response time for a patient portal?
Not in the HIPAA Security Rule. Reading 45 CFR 164.302 through 164.318 in full, the rule names no testing technique and no threshold, and its general requirement at 164.306(a)(1) asks only that the confidentiality, integrity and availability of electronic protected health information be ensured. The number is the organisation's own service level. What it is measured against is written down elsewhere: the applications and data criticality analysis at 164.308(a)(7)(ii)(E) and the emergency mode operation plan at 164.308(a)(7)(ii)(C).
Can we load test against a stubbed EHR instead of the real API?
A stub answers the request the portal sends and skips the work the certified server does behind it. 45 CFR 170.315(g)(10)(i)(A) requires a response carrying every data element marked "mandatory" and "must support" by the standards it adopts, and the FHIR specification warns that "validation, particularly full validation including terminology, can be quite computationally demanding" and "can impose unacceptable time delays in a production system". A stub reproduces the shape of the answer and none of that cost, so it tells you about your own front end only.
Our uptime monitor is green through the peak. Why did patients see blank charts?
A monitor usually reads the cheapest endpoint on the server. The FHIR R4 specification states that "the only interaction that servers are required to support is the capabilities interaction itself", reached at GET [base]/metadata, and that interaction touches no patient data. A search that partially succeeds returns a Bundle, and FHIR R4 lists an OperationOutcome carried "as part of a search's Bundle response containing information about the search" as one of its five circumstances of use. A portal that ignores that element renders a short chart with no warning on it.
Do session timeouts have to be tested as part of a peak run?
They change behaviour under load, so yes. Automatic access time-out is its own ONC certification criterion at 45 CFR 170.315(d)(5), and automatic logoff at 45 CFR 164.312(a)(2)(iii) is an addressable implementation specification of the HIPAA access control standard. When a chart takes longer to assemble than usual, a patient sits on a loading state while the timer runs, and a timer that fires mid-assembly produces a sign-out that looks to the patient like data loss.

Which product types does this apply to?

Which of our services test it?

What does validating your product actually involve?

Answer four questions about your markets, your product type and its integrations. You get the standards that reach you, the artefacts each one asks you to produce, and which of them a test supplier delivers.