Fast enough for a conversation
"The spreadsheet has 100,000 rows. I have one question. Why am I waiting?"

An AI assistant working with your data does not ask one big question. It asks twenty small ones: how many rows, which regions, what happened in March, does this column join to that one. If each answer takes five seconds, the conversation dies. If each takes fifty milliseconds, it feels like talking to someone who has the spreadsheet open in front of them.
So we measured. Not on a laptop with the fans going, on the small cloud machine that actually runs tableski.io, with the other services running next to it, and with the queries going through the real HTTPS endpoint an AI client would use.
The setup
A generated sales table with nine columns: id, day, region, product, customer, quantity, unit price, discount, amount. Three versions: 100,000 rows as an Excel workbook (4.8 MB), the same rows as CSV (5 MB), and a million rows as CSV (53 MB). A small products table for joins. The questions an assistant would really ask: count, a group-by with two aggregates, a filter with sort and limit, a join with a group-by, a month series, and basic statistics. Each question forty times, two at a time.
What one question costs
| Data | Question | Typical | 95 out of 100 under |
|---|---|---|---|
| 100,000 rows, Excel | count everything | 17 ms | 21 ms |
| sales by region, two aggregates | 24 ms | 42 ms | |
| filter, sort, top 50 | 21 ms | 26 ms | |
| join with products, group by category | 34 ms | 40 ms | |
| 100,000 rows, CSV | sales by region | 48 ms | 58 ms |
| join with products | 59 ms | 65 ms | |
| 1,000,000 rows, CSV | count everything | 181 ms | 203 ms |
| sales by region | 287 ms | 413 ms | |
| join with products | 411 ms | 440 ms |
Excel is faster than CSV here, which surprises people. A workbook is decoded once, when it is uploaded, into typed columns held in memory. A CSV is streamed from disk on every question, because streaming is what makes a 53 MB file cheap to hold. Both are quick; the workbook is quicker.
Add the network between you and the server. From Europe to the current data centre that is a tenth of a second or so per question. An assistant asking about a normal spreadsheet gets its answer in well under half a second, end to end. A million-row file takes about half a second to one second.
The first question after an upload
The very first query builds the tenant's tables. For the 100,000-row CSV that took 70 to 100 milliseconds; for the workbook, half a second, because the decoding happens then. After that the tables stay warm while they are being used, and every question pays only the numbers above.
Many questions at once
Two clients at a time gave the numbers in the table. Six clients at once on the 100,000-row table: typical latency rose to 120 to 170 milliseconds, the 95th percentile to about 240, and the service kept answering 35 to 47 questions per second. More clients means each waits a little longer; the total work done per second stays where it is. Nobody typing questions by hand will notice another person on the same machine.
The comparison you came for
How is this normally done? Most Excel tools for AI assistants open the workbook on every request, read cells with a Python library, and let the model do the arithmetic. We timed that path on the same machine and the same 100,000-row workbook, honest and unhurried:
| Way of answering "sales by region" | Time per question |
|---|---|
| Open the workbook with openpyxl in read-only mode, walk the rows, sum | 4.63 s |
pandas read_excel, then groupby | 6.27 s |
pandas read_csv of the CSV version, then groupby | 0.10 s |
| tableski, same workbook, same question | 0.024 s |
190xa group-by over 100,000 Excel rows: 4.63 seconds with the open-the-file-each-time approach, 24 milliseconds with tableski
Where does it come from? Not from magic. Two decisions. The workbook is decoded once, not on every question, and the question is executed by a real query engine, Apache DataFusion, in Rust, over typed columns, rather than by a script walking cells. pandas after loading is fast too, about 12 milliseconds for the group-by; the difference is that nobody keeps the DataFrame alive between an assistant's questions. tableski does exactly that, per user, with the tables dropped again when they go quiet.
Fair print: the Python numbers are openpyxl 3.1 and pandas 3.0 on the same two-core machine, single run each, reading the file once per question, which is what the per-request tools do. Load the file once and pandas is as quick as we are for the arithmetic; the point is who does the loading and when.
What we did not measure yet
Concurrency beyond six clients, workbooks with many sheets, and the trader path with live data are for another post. The data set, the scripts and the raw results are in our notes, and the free plan is the same engine on the same machine: upload a file and ask it something.