Lab / Open methodology

Month-end reports across five million records

5,000,000 orders summarized: 1.22 min → 175.5 ms. Synthetic lab; median of 10 runs. Open code and raw data.

CompletedSMBEnterprisePartners

Unindexed month-end reporttoSame report + covering index

SQLite 3.46 LAB MEASUREMENT

500 customer balances from 5 million orders.

Run the same open-order balance report. Business rules and engine stay the same; the access path that scans the whole table per customer changes.

Business effect

Repeated month-end checks take less time and CPU work. The team can move from waiting for a report to reviewing its balances.

BEFOREUnindexed month-end report
MODERNIZEDSame report + covering index
Order records5,000,000
100,000Recorded loads only5,000,000
20× speed
SAME TASK · SAME DATA10 runs · median
01

Unindexed month-end report

Scan the entire order table again for each customer balance.

1 m 13.11 s
CPU time
1 m 13.1 s
02

Same report + covering index

The same SQL finds amounts using customer and status keys.

175.502 ms
CPU time
175.473 ms
03

Index + grouped-query control

An alternative that groups orders once; every result is retained, faster or slower.

254.653 ms
CPU time
254.617 ms

Bars start at zero and share the same time scale across implementations.

Completion time reduced99.8%Time difference: 1 m 12.93 sOriginal → modernized implementation
What changed?

Add a composite index covering customer, order status and amount. SQL text is identical before and after. Measure a grouped-query alternative as a separate control.

All load points and measurements
100,000 · Order records
ImplementationMedian durationCPU time
Unindexed month-end report1.435 s1.435 s
Same report + covering index3.833 ms3.835 ms
Index + grouped-query control5.507 ms5.509 ms
1,000,000 · Order records
ImplementationMedian durationCPU time
Unindexed month-end report14.751 s14.749 s
Same report + covering index36.498 ms36.504 ms
Index + grouped-query control52.952 ms52.941 ms
5,000,000 · Order records
ImplementationMedian durationCPU time
Unindexed month-end report1 m 13.11 s1 m 13.1 s
Same report + covering index175.502 ms175.473 ms
Index + grouped-query control254.653 ms254.617 ms
CPU cost at your workload

Compare the recorded CPU time at your own monthly volume.

One batch run = 5,000,000 Order records.

CPU time reduced / month202.5564 hours

Processing cost difference / month—Calculated after you enter a unit price.

Lab CPU time × your volume and unit price. This is not a hosting bill forecast; idle capacity, networking, storage, licences and migration are excluded.

Try it yourself

Replay the recorded lab results side by side.

As the workload grows

Duration by workload

  • Before
  • After

Duration by workload (ms)

020,00040,00060,00080,000100,0001,000,0005,000,00073,106.21 ms175.5 ms

Select a data point

020,00040,00060,00080,000100,0005,000,000175.5 ms

Select a data point

Order recordsMarkers: measured points
Show as a table
Duration by workload
Order recordsBeforeAfter
100,0001,434.97 ms3.83 ms
1,000,00014,751.16 ms36.5 ms
5,000,00073,106.21 ms175.5 ms

How we measured

Environment, protocol and technical analysis

Environment and data

Environment
Apple M3; Docker Linux arm64, 2-CPU quota, 1 GiB memory; PHP 8.4.26 / SQLite 3.46.1.
Dataset
500 customers, 100,000 / 1,000,000 / 5,000,000 orders. Identical rows streamed into two databases; complete 500-row results match independent PHP and Python totals.
Tools
PHP 8.4.26 · SQLite 3.46.1 · hrtime / getrusage · native arm64 Docker · independent Python oracle
Repetitions
3 sizes × 3 queries × 10 repetitions, plus 18 warmups. All 108 observations and every customer balance are published.
Open raw measurement data ↗

500 customer balances from 5 million orders.

Run the same open-order balance report. Business rules and engine stay the same; the access path that scans the whole table per customer changes.

Open-order totals for 500 customers using deterministic synthetic integer cents. Three sizes and three arms fixed before measurement. Identical SQL before/after indexing plus a grouped-query control. Two warmups then ten repetitions with rotating arm order. All 500 output rows match an independent oracle every time. Reads exclude loading, index construction and validation; two new in-memory databases per size, warm repetitions. Write workload and monetary billing effects were not measured.

Inspect the measurement script ↗

What changes for the business?

Repeated month-end checks take less time and CPU work. The team can move from waiting for a report to reviewing its balances.

Change and scope

Add a composite index covering customer, order status and amount. SQL text is identical before and after. Measure a grouped-query alternative as a separate control.

500 customers; 100 thousand, 1 million and 5 million synthetic orders. SQLite 3.46.1, warm in-memory data and identical hardware. Read time excludes loading and index construction; setup time and storage overhead are published separately.

Every query at every measured size

Orders Unindexed Same query, indexed Grouped-query control
100,000 1.435 s 0.004 s 0.006 s
1,000,000 14.751 s 0.036 s 0.053 s
5,000,000 73.106 s 0.176 s 0.255 s

Index setup and storage cost

At 5 million records the index allocated 100,130,816 additional bytes. The single construction observation was 4.086 seconds. These are separate from the median read time. An index also changes the write workload, which this experiment does not measure. Query plans and every setup observation.

Where to start in your system

Identify the slow operation, data volume and peak workload. Establish its baseline, change the code and access pattern, then compare the same result.

What we did

  1. Business rule and data

    AIPrepared the synthetic workflow, tests and measurement automation.

    VerificationPublished code and raw outputs are available for review; this is not a client project.

  2. Implementation change

    AIAdd a composite index covering customer, order status and amount. SQL text is identical before and after. Measure a grouped-query alternative as a separate control.

    VerificationOutput equivalence was independently checked; every repetition is retained.