Open-source performance benchmark

How much faster is the same query with TTL caching?

We ran 100,000 identical listRows calls against a 10,000-row table, then turned on ttl: 300 and ran them again. Scroll to see what changed.

avg speedup
2.12×
end to end
latency cut
52.7%
off every request
p95 tail
1.83×
tighter tail
throughput
2.12×
requests / second
no cache13.626 ms
ttl cache6.440 ms
01 · scale

Your traffic. Your savings.

Drag the slider to extrapolate the measured averages across more or fewer requests. Only the 100,000-request data point is observed. Every other value is a linear projection and is labeled as such.
requestsmeasured
100.0k
measured
10010k100k10M
no cache · total time
22.7 min
measured
ttl cache · total time
10.7 min
measured
time you get back
12.0 min
measured

measured. Numbers above are the totals the benchmark reported for the actual 100,000-request run.

02 · distribution

Not just the average.

Hover a percentile to isolate the row. Click to pin it and read the callout on the right. Click again to release.
percentilelatencyspeedup
no cachettl cache· bars scaled to the slowest observed value (118.957 ms)
callouthover or click
Hover any row in the table to inspect that percentile. Click to pin the detail while you read.
03 · live race

Press play. Watch the gap open.

Each dot is a simulated request, drawn from the measured latency distribution. The two lanes fire at their own observed rates, so the cache lane finishes while the no-cache lane is still running. Time is compressed 3× for viewing.
requests
no cache
0 / 200
0.00ms avg · live
0 ms119 ms
ttl cache
0 / 200
0.00ms avg · live
0 ms119 ms
no cache
0%
ttl cache
0%
observed speedup
04 · wall clock

Twelve minutes back in your pocket.

The same 100,000 requests took less than half the time when the cache was warm.
no cachephase runtime
22m43.3s
for 100,000 listRows calls
ttl cachephase runtime
10m44.5s
for 100,000 listRows calls
saved
11m 58.8s
or 52.7% of the no-cache runtime, gone.
0:00saved 11:5822:43
05 · how we measured

Nothing fancy.

The whole benchmark lives in a single repo. Setup script, generator, runner, markdown report writer. Clone it, point it at your own Appwrite instance, and you will get your own numbers in under forty minutes.
step 01

seed a realistic table

10,000 rows of product data across 15 typed columns: text, enums, floats, integers, booleans, emails, urls, datetimes, ips, and tag arrays. Seeded with a deterministic PRNG keyed on the row index.

step 02

pick a realistic query

Filter by category, threshold on rating, order by reviewCount, limit 25. A categorical filter, numeric threshold, sort, and limit — the shape caching is designed to help.

step 03

run it twice

Phase one issues 100,000 calls with ttl = 0. Phase two issues the same 100,000 calls with ttl = 300. One connection, sequential, timed with performance.now().

step 04

measure everything

Per-request latency, sorted into min, p50, p90, p95, p99, and max. Total wall clock. Requests per second. Then the deltas.

the whole trick

One parameter.

Enabling the cache is adding a single field to your existing listRows call. The SDK, endpoint, and query stay the same.

server-nodejs· cache on
const rows = await tablesDB.listRows({
    databaseId: '<DATABASE_ID>',
    tableId: '<TABLE_ID>',
    queries: [
        Query.equal('category', 'electronics'),
        Query.greaterThan('rating', 3.5),
        Query.orderDesc('reviewCount'),
        Query.limit(25)
    ],
    ttl: 300
});
06 · raw numbers

Every metric, in one grid.

Lifted verbatim from the report the benchmark wrote to results/2026-04-20_23-56-24.md.
total wall
no cache22m 43.4s
ttl cache10m 44.5s
deltasaved 11m 58.8s
avg / request
no cache13.626 ms
ttl cache6.440 ms
delta2.12× faster
min
no cache10.783 ms
ttl cache4.146 ms
delta2.60× faster
p50
no cache13.187 ms
ttl cache6.108 ms
delta2.16× faster
p90
no cache15.173 ms
ttl cache7.862 ms
delta1.93× faster
p95
no cache16.450 ms
ttl cache8.966 ms
delta1.83× faster
p99
no cache21.303 ms
ttl cache12.527 ms
delta1.70× faster
max
no cache118.957 ms
ttl cache75.173 ms
delta1.58× faster
requests / sec
no cache73
ttl cache155
delta2.12× faster