How Qinsio processes 50,000 rows
in under 5 seconds
Everything runs inside your browser. No server. No upload. This page explains exactly how — the data structures, the algorithms, and the architectural decisions that make it fast.
Architecture overview
Two threads, five pipeline stages, zero server round-trips.
- Renders progress bar
- Accepts file drops
- Shows column mapping UI
- Triggers browser download
- Parses CSV / XLSX
- Normalises every cell
- Builds hash map, finds duplicates
- Detects mismatches
- Serialises + compresses XLSX output
The processing pipeline
Five stages, each executed once per run, each designed to minimise repeated work.
Browser-native file parsing
Your file is read directly via the FileReader API — no upload, no network request. CSV files are parsed with PapaParse's streaming tokeniser. XLSX files are parsed with SheetJS. Both produce an identical internal row format.
Single-pass typed normalization
Every cell is classified once: number, date, boolean, or string. Dates are parsed to UTC timestamps. Numbers are stored as floats. Whitespace is trimmed. This typed representation is locked in memory and reused for every subsequent step — there is no re-parsing.
O(n) hash-map deduplication
A composite key is built for each row by joining all its typed cell values. That key is inserted into a JavaScript Map. A Map lookup is O(1), so the full deduplication pass over n rows is O(n) — not the O(n²) of a naive pairwise comparison. For 50,000 rows: 50,000 hash operations instead of 2.5 billion comparisons.
Key-join mismatch detection
For two-file comparison, rows from both files are indexed by their shared key columns into two Maps. A single linear scan finds rows missing in B, rows missing in A, and rows present in both with changed values — all in O(n + m) time.
Compressed XLSX written in the worker
The output workbook (Clean Data, Duplicates, Invalid Rows, Executive Summary) is serialised with compression:true inside the Web Worker, then transferred to the main thread as a transferable ArrayBuffer — zero copying. Compression reduces a 50k-row file by ~3.5× before the browser even offers the download.
Why hash maps beat pairwise comparison
The single biggest performance decision in the engine.
50,000 rows → 2.5 billion comparisons. A browser tab running this would freeze for minutes or crash entirely.
50,000 rows → 50,000 hash operations. Each row is touched once. Duplicates naturally land in the same bucket.
| Row count | Pairwise O(n²) | Hash map O(n) |
|---|---|---|
| 1,000 | 1,000,000 | 1,000 |
| 10,000 | 100,000,000 | 10,000 |
| 50,000 | 2,500,000,000 | 50,000 |
Key design decisions
Every choice is deliberate and performance-motivated.
Web Worker thread isolation
All processing runs in a dedicated background thread. The main thread — which drives your UI — is never touched during computation. You can scroll, resize, or click while 50,000 rows are being hashed.
Two-phase pipeline
Phase 1 parses and normalises your file so you can configure column mappings in the UI. Phase 2 runs detection on the already-normalised data. The expensive file I/O and cell parsing happens exactly once.
Throttled progress reporting
The worker posts progress messages only every 2,000 rows and only when the percentage actually advances. Unrestricted postMessage() calls would dominate runtime on large files.
Exact matching — no probabilistic guesswork
Duplicates are found by deterministic row hashing. Mismatches are found by exact key equality. There is no fuzzy matching, no ML model, no thresholds to tune. The result is always reproducible and auditable.
Privacy is not a trade-off — it is a performance feature
Running entirely in the browser eliminates the biggest bottleneck in web applications: the network.
- ✗Upload file (slow)
- ✗Server processes
- ✗Download result
- ✗Server stores copy
- ✓File stays on your machine
- ✓Worker thread processes
- ✓Result ready instantly
- ✓Nothing stored anywhere
- →0 network round-trips
- →No upload wait time
- →No server costs
- →No data breach risk
Guarantees that don't require trust
These aren't policies you have to read or promises you have to believe. They follow directly from how the software is built — browser-only, no server, deterministic algorithms.
- ✓Your files never leave your browser
- ✓No account required
- ✓No AI guesses
- ✓No internet required after loading
- ✓Every result is deterministic
- ✓Output can be audited manually
Why we didn't use AI
Many spreadsheet tools now advertise AI. We intentionally didn't.
Finding duplicate rows doesn't require a language model. It requires deterministic algorithms. A hash map finds every duplicate, every time, in linear time — with zero probability of a hallucinated result.
That's why every Qinsio result is repeatable. The same input always produces the same output. You can verify it yourself by running the same file twice.
For accounting and finance work, determinism isn't a nice-to-have. It's a requirement.
- ✗Probabilistic output
- ✗Different results on re-run
- ✗Unexplainable decisions
- ✗Requires server + API calls
- ✗Can hallucinate matches
- ✓Deterministic output
- ✓Identical results every run
- ✓Fully traceable row hashes
- ✓Runs 100% offline
- ✓Zero false positives
See it in action
Drop a CSV or XLSX file and watch the pipeline run. Up to 50,000 rows, entirely in your browser.
Try it now