Hardware Requirements
Based on the load test from 2026-08-03 (see bench_results_summary.md in the project root):
5074 documents, 35197 stock operations over 1 year, real processing code and rollback, reports
over HTTP. The test ran on a single specific machine — part of the conclusions are measured,
part is reasoned extrapolation. That split is made explicit below.
Test machine
Intel Core i7-4810MQ (2013, mobile, 2.8GHz), 15GB RAM, SATA SSD (Kingston SA400).
Not top-of-the-line, not new hardware. The benchmark database weighs 10MB at the tested
data volume — even the default innodb_buffer_pool_size=128MB (left untuned) holds it with
room to spare.
Scenario 1 — everything on the user's own machine (local server)
What actually affects speed
RAM — barely matters at this scale. 10MB per year of work → extrapolated: 10 years of
history ≈ 100MB, 50 years ≈ 500MB. Any machine with 2GB+ RAM will cache the entire working
database after the first access. RAM isn't the bottleneck here, the real question is "does the
system have enough to run at all" (OS + MySQL + PHP + browser at once on one machine).
Disk — likely the main factor, though SSD vs HDD wasn't compared directly (no permission to
drop the OS cache in the test environment). The reasoning: processing a document makes several
targeted updates to the stock-balance table line by line — random writes, not sequential. On an
HDD (~10ms seek), a 3-line document is already 30+ms just for head positioning, before any
CPU/SQL work. On an SSD, the same operation is microseconds. The test held a steady ~6-10ms per
rollback with no degradation on an ordinary SATA SSD.
CPU — low requirements. A 2013 mobile i7 handles the heaviest report (1.2s for 35k
operations) without strain — PHP is single-threaded per request, SQL queries are simple indexed
lookups, not computationally heavy. A modern budget CPU (Celeron/Pentium N-series 2020+, a $150
mini-PC) matches or beats this i7 in per-core performance.
Minimum threshold — local installation
| Component | Minimum | Comment |
|---|---|---|
| Disk | SSD, mandatory (even a cheap SATA one) | HDD wasn't tested, but structurally should badly hurt document processing (random writes). Not recommended for a working system. |
| RAM | 4GB | Not because of database requirements (it's tiny) — but because OS+MySQL+PHP+browser running at once genuinely need this minimum. 2GB is the edge where swapping starts under normal use. |
| CPU | Any x86_64 dual-core from ~2015+, 2GHz+ | Not a CPU-bound workload at this data scale. |
| Network | not tested | A local network isn't an issue; remote access over the internet — see Scenario 2. |
Conclusion: for a data volume comparable to what was tested (thousands of documents a year,
tens of thousands of operations), practically any modern computer with an SSD will handle it —
including "old" 2013-2015 hardware, as long as it has an SSD. The one hard rule: no HDD.
Scenario 2 — external (hosting/VPS) server
The local test does NOT cover this scenario directly — factors show up here that simply don't
exist when everything runs on one machine. Some of the points below aren't measurements but
structural risks worth checking with a dedicated load test before a real production launch.
What changes compared to a local install
-
Real multi-user contention. The whole point of an external server is access for several
operators at once. The local test was strictly sequential (a single "user") — row locking on
the stock-balance table / documents table when multiple documents are processed against the
same lots at the same time wasn't tested at all. This is the main unknown factor — without
a dedicated test with parallel requests, there's no way to promise that 5-10 concurrent
operators will perform as fast as the sequential test showed. -
Network latency. Every UI action is an HTTP request. Reports in full mode return heavy
payloads (up to ~1.5MB of HTML for a year of Stock Turnover) — on a slow or distant
connection that's a noticeable delay on top of server-side generation time. Locally this was
zero; on an external server it depends on the client's geography and provider. -
A production web server is mandatory. The test used PHP's built-in dev server — it's
single-threaded and NOT meant for real, let alone internet-facing, use. An external server
needs a real stack (nginx/Apache + PHP-FPM with a worker pool) — otherwise even 2-3
concurrent requests will queue up. -
Security when exposed to the internet. Locally, risk is confined to one machine. An
external server requires: HTTPS/TLS mandatory (the report auth token is currently passed as
a URL query parameter — acceptable only under TLS, otherwise it's visible in proxy logs and
browser history), a firewall, and blocked external access to local config files and logs. -
Memory under concurrency. Every PHP-FPM worker and every MySQL connection holds its own
memory — with N concurrent users, the RAM requirement grows with N, instead of staying flat
as in the single-user local test. The N at which this becomes noticeable wasn't measured. -
Reliability and backups — responsibility shifts. On a personal machine, the person
themselves watches over power and disk health. On an external server, the host is expected to
provide that (SLA), but database backups remain the project's own responsibility regardless —
see the rule "a disk copy of IMS2 must include a SQL dump of the database."
Minimum threshold — external server (VPS/hosting)
Given that the actual workload (per the local test data) is very light — the constraints here
are driven by concurrent access and web-server requirements, not data volume:
| Component | Minimum | Comment |
|---|---|---|
| CPU | 2 vCPU | More is for growing concurrent-user counts, not data volume. |
| RAM | 2-4GB | A higher bar than local: a PHP-FPM pool + MySQL + OS on a dedicated server with no browser — but with headroom for concurrency. |
| Disk | SSD/NVMe (default on all modern VPS providers) | Same argument as local — only stricter, since on a server the disk is shared across all concurrent operations. |
| Network | HTTPS mandatory, 10Mbps+ | Because of the token passed in report URLs and the size of heavy report HTML responses. |
| Web server | nginx/Apache + PHP-FPM, NOT the PHP dev server | A single-threaded dev server can't hold up under parallel requests. |
Concurrency test (2026-08-03) — settled empirically
This question was initially open (see history below) — it was checked separately, through
nginx + PHP-FPM (not the dev server), with the worker pool and CPU physically capped to 2 cores
— an honest simulation of a 2 vCPU VPS, not the full 8-core test machine. The load was the
heaviest endpoint from the "operation time growth" section (Stock Document Turnover, full mode,
a full year), with concurrent requests fired via curl_multi (a stand-in for ab/wrk, which
aren't available on the system without sudo).
| Concurrency | Requests/sec | Latency avg / p95 | Errors |
|---|---|---|---|
| 1 | 0.70 | 1.4s / 1.6s | 0 |
| 5 | 2.63 | 1.7s / 2.3s | 0 |
| 10 | 2.98 | 2.9s / 3.6s | 0 |
| 20 | 3.03 | 5.7s / 7.0s | 0 |
Result: throughput plateaus at ~3 requests/sec already at concurrency 10 (the 4-worker pool
saturates) — further load growth doesn't produce errors, only a growing wait queue (latency up
to ~7s at 20 concurrent requests all hitting the single heaviest report). 0% errors at every
level — degradation is graceful (queueing), not failure.
This is an artificial worst case — every "client" hits the SINGLEST heaviest report at once.
Real-world load from 5-20 companies is almost always a mix of light operations (processing a
document, ~10ms) and occasional heavy reports, not 20 identical heavy requests fired together.
Conclusion: 2 vCPU / 4GB is enough even in this worst-case scenario.
Caveat: the test is a taskset-based simulation on the local machine, not a real VPS
(virtualization, noisy neighbors, real network — other factors apply there). Before a real
launch it's worth repeating the same test (scripts/bench_concurrency.php) on the actual
purchased VPS — the same 10 minutes, but on the target hardware.
Scale — an important caveat
IMS2 is a closed system for a single organization (a warehouse/business), not a public service.
This isn't about thousands or even hundreds of concurrent users — the realistic range for this
class of system is a handful, at most the first few dozen concurrent operators (warehouse
staff, cashiers, an accountant, a manager). The recommendations above (2 vCPU, 2-4GB RAM) are
sized for that scale, not internet-scale traffic. The open question about concurrency is
"can the system handle 10-20 concurrent operators without degrading," not a question of
horizontal scaling for thousands of clients. If the real number of concurrent users is known in
advance (say, no more than 5-10), the minimums in the table above can be considered sufficient
without an additional test — contention risk doesn't spike sharply, it grows gradually as
concurrent writes to the same warehouse lots approach the dozens.