The short answer: saving items is not a worry. It kept pace at 8,857 items per second for 15 minutes straight, and the job it was writing into grew from ten thousand items to 11,811,050 items along the way without slowing down. A full team of 100 people scanning one item every 5 seconds produces about 20 items per second, so the machine had hundreds of times more room than the job needed.
Items recorded per second
8,857
held steady for 15 minutes without slowing down
Items written in that run
8,016,350
every one checked against the system afterwards
How slow a save felt
25 ms
slowest single save was 110 ms
Jobs fully checked
73
every save counted and confirmed
"9 out of 10" is how we describe waiting times honestly: it is the wait that nine people out of ten experienced, so one unusually slow moment does not distort the picture.
1. Saving items
Change the settings below to match a real shift.
How many items does each save carry?
Where are people working?
How many people are saving at the same time?
2. Does it get slower as the job fills up?
Here is the same four-person test repeated as the job filled with more and more items. Every bar is the same length.
Items recorded per second. Four people saving at once, 50 items per save, repeated as the job filled up.
Filling the job up did not slow it down. The first of these tests wrote into a job holding 328,350 items. The last one wrote into a job already holding 3,794,700 items and still managed 8,857 items per second — within 2% of the very first one. That last test ran for 15 minutes, and afterwards the job held 11,811,050 items.
This is the answer to "will writing speed last?" On this machine, for this kind of job, yes: the saving side has room to grow for a long time before it becomes a problem. The wider run of tests behind this section started from a job holding only 10,000 items.
3. When people watch progress or look at reports
This side is only used by managers, so the realistic crowd is one to four people. Here is what it does.
How many items have been counted?
What are they looking at?
How many people are looking at once?
For a job of 100,000 items with four people looking at once:
| What they are looking at | Wait | How many screens a second |
|---|---|---|
| Scrolling the record list | 68 milliseconds | 73.1 a second |
| The "needs review" list | 287 milliseconds | 18.9 a second |
| Running the totals | 190 milliseconds | 31.8 a second |
| Comparing counted to expected | 203 milliseconds | 29.7 a second |
Worth knowing: the heavy screens use a lot of memory — about 2.4 GB with one person looking, rising to about 4.1 GB when thirty-two people hit the same screen at once, which pushed waits out to about 2.0 seconds. Nobody opens thirty-two of those at the same time in real life, but it does mean our current 1 GB memory setting is smaller than the app can reach, so we should raise it. The plain record list does not behave this way: its memory is set by the app starting up, not by the number of people. Full printed reports are not measured here at all, because you have already said waiting 10–20 minutes for those is perfectly fine.
4. What this means for what we buy
- Do not buy a bigger machine yet. The saving side is not short of capacity on the machine we already own. Spending on hardware before fixing the code would buy nothing we need.
- Give the app more memory. The current 1 GB is below what we saw used in a busy report. Moving to 2 GB is a low-risk comfort step; anything higher should wait for the next check.
- Database size: 8 GB to 16 GB is a reasonable starting point. We have not yet proved which is better, because our test database was sharing memory with other things. One focused check would settle it.
- Our weakest spot is code, not hardware. When several people upload to the same job, they queue behind each other instead of working side by side. Spreading people across separate jobs doubles the speed. Shortening that queue would help most — and it is a code change, not a purchase.
- Uploads take turns on purpose. That is how we stop a job being closed while someone is still writing to it. So it is a safeguard, not a fault.
5. What we have not checked yet
Being straight about the edges of this test, because they affect what we should not promise yet.
- A very long shift. We ran 15 minutes, not a full eight-hour day.
- Shops with huge product lists. Our test shop had about a thousand products and every scan matched. A shop with tens of thousands of product codes is untested.
- Everyone reconnecting at once. If a whole team comes back from a dead spot in the warehouse at the same moment. Worked out with maths rather than tested: 49,500 items would take about 6 seconds of machine time at the measured speed, while a full team of 100 scanning steadily produces only 20 items per second. We should test it rather than trust the maths.
- Jobs with very many locations on the floor. Our test job had a single location.
- Several customers at once. Everything here was one organisation.
- Report printing and bulk file imports competing with people counting.
- Our production cloud setup. These numbers come from our own laptop, not the servers customers use.
6. How to trust this
- Nothing was taken on trust. After every test we went back to the stored data and counted what was actually written: totals, quantity, and that each item appeared exactly once. All 19,576,985 items matched. The "9 out of 10" figures come from the app's own timings, not our stopwatch.
- Everything was genuinely measured, never estimated, using a standard load-testing tool against the real system over a real network connection.
- The test data was kept separate from the development database and deleted afterwards. Nothing about the development or customer environment was changed.
- Honest limits of the load — the load we applied was harsher than reality: people here upload back to back with no pause, whereas a real scanner pauses between items. Concurrency here is not the same as headcount.
- We found and fixed a fault in our own test partway through: in the first full run, devices were accidentally sharing an identity, which produced duplicated items. The check caught it, the run was rejected and redone. Those first results were discarded rather than quietly kept.
- One unrelated issue noticed: three billing audit notes were refused by the system during setup. Buying and permissions still worked correctly. Logged for separate investigation; nothing in this performance result depends on it.
Run reference 3b360c6c · version 20261008-baseline-write-read · generated from the measured result files in tests/performance/20261008-baseline-write-read/reports/. Every figure on this page comes from those files; none are typed in by hand.