Reference

Cloud benchmark evidence

This page reports live multi-region measurements against Cloudflare Workers and R2. Results describe the tested data, routes, regions, and time period. They do not establish database-wide superiority over another system.

Current-layout benchmark

The 25 September 2026 run measured the released snapshot, trie, read-bundle, and secondary-index paths after decoded-envelope hardening.

Tested production commit:

aaaf60ab263dd0165dd89205f83f9e54e2638277

Raw artifacts:

SHA-256:

JSON EE93073994C8D7917D203865DEC31C433F9D3DF77C56F44AC032904CB6DA0219
CSV  76210F31306CE6E7BF0E22C67BC498EA593634E08F89AD5A188A0F3D1B526DB9

Method

Disposable Node 22 containers ran in seven Azure regions:

Azure caller regionCloudflare colo
East USIAD
West US 2PDX
North EuropeDUB
Southeast AsiaSIN
Japan EastNRT
Australia EastSYD
Brazil SouthGRU

Each caller used the production ThimbleDB browser read planner over HTTPS. Object retrieval, TDB1 decryption, bounded gzip decompression, caching, index planning, and result validation used the current package code. Writes ran inside the temporary Worker against R2.

The run used two independent replicates in every region and retained 3,808 measured operations. Warm-up operations are excluded.

This was not the production deployment. The Worker, R2 bucket, and Azure resource group were temporary and were deleted after evidence capture.

Data profiles

All profiles used the same deterministic JSON shape and two indexes:

  • equality index on category, covering title and lastModified
  • range index on lastModified, covering title and category
ProfileDocumentsDecoded snapshotSnapshot objectsSnapshot stored bytesTrie objectsTrie stored bytes
Small12851,53647,28112137,414
Medium5,0002,037,4204233,984276351,875
Large25,00010,245,37441,171,5102761,416,813

The object counts include HEAD, document data, and both secondary-index pages.

Cold point reads

Cold point-read p95 by collection size

ProfilePathp50p95SuccessNetwork readsNetwork bytesR2 readsR2 bytes
SmallSnapshot374.86 ms1,446.86 ms168/16822,94422,944
SmallTrie757.53 ms2,312.65 ms168/16841,73641,736
SmallSnapshot bundle371.89 ms1,253.23 ms168/168152,69922,944
SmallTrie bundle722.78 ms3,129.05 ms168/16813,95841,736
MediumSnapshot418.72 ms1,755.95 ms168/168288,032288,032
MediumTrie771.32 ms3,009.58 ms168/16842,74742,747
MediumSnapshot bundle509.54 ms1,452.58 ms168/16812,038,593288,032
MediumTrie bundle737.66 ms2,751.17 ms168/168113,25342,747
LargeSnapshot642.08 ms1,617.18 ms168/1682448,4622448,462
LargeTrie767.08 ms3,229.82 ms168/16844,69644,696
LargeSnapshot bundle fallback836.03 ms2,475.30 ms167/1683448,4624896,924
LargeTrie bundle719.78 ms2,685.03 ms168/168145,86844,696

Snapshot was the fastest direct point-read layout at every tested size. Compared with trie, snapshot p95 was:

  • 37.44 percent faster for 128 documents
  • 41.65 percent faster for 5,000 documents
  • 49.93 percent faster for 25,000 documents

Trie transferred far fewer bytes, but four sequential network requests cost more than downloading and decoding Snapshot in this workload.

Trie bundle reduced four network requests to one. It improved trie p95 by 8.59 percent at 5,000 documents and 16.87 percent at 25,000 documents. It was 35.30 percent slower at p95 for 128 documents, where bundle assembly and JSON transfer outweighed the saved round trips.

Snapshot bundles were not a useful general optimisation:

  • they transferred decoded JSON rather than the compressed TDB1 snapshot
  • the medium bundle transferred about 2.04 MiB instead of 88 KiB
  • the large bundle exceeded the 4 MiB decoded bundle limit and correctly fell back to individual object reads

One large snapshot bundle sample failed with a transport timeout. It remains in the raw evidence and is excluded from successful-operation percentiles.

Regional large point-read p95

Large-profile cold point-read p95 by region

RegionSnapshotTrieTrie bundleSnapshot bundle fallback
East US501.28 ms445.10 ms367.47 ms560.51 ms
West US 2512.22 ms437.38 ms409.05 ms604.50 ms
North Europe652.54 ms702.00 ms668.81 ms793.92 ms
Southeast Asia1,976.06 ms4,374.20 ms3,448.53 ms3,642.25 ms
Japan East928.12 ms834.41 ms878.64 ms1,137.97 ms
Australia East1,408.45 ms1,004.56 ms894.91 ms1,445.94 ms
Brazil South941.94 ms913.58 ms769.25 ms1,032.91 ms

Regional results do not produce one universal winner. Snapshot had the better pooled p95, while trie or trie bundle won in several individual regions. Southeast Asia had the highest tail latency for every point-read path.

Secondary indexes

Large-profile read p95 by operation

Covered equality

The query matched 0.5 percent of each collection and returned at most 25 documents entirely from the covering index.

ProfileSnapshot p50Snapshot p95Trie p50Trie p95Network reads
Small377.73 ms1,371.21 ms379.81 ms1,563.82 ms2
Medium465.04 ms1,886.27 ms428.14 ms1,123.80 ms2
Large804.16 ms1,691.96 ms798.53 ms2,061.05 ms2

Layout choice made little difference because both paths read one HEAD and the same logical index page.

Uncovered equality

The same index selected candidate IDs, then the client loaded complete documents.

ProfileSnapshot p50Snapshot p95Trie p50Trie p95Snapshot readsTrie reads
Small579.27 ms2,261.58 ms945.36 ms3,732.84 ms35
Medium1,080.95 ms3,475.87 ms1,118.78 ms6,308.08 ms336
Large17,994.23 ms30,700.95 ms1,996.24 ms8,929.58 ms3117

Large Snapshot behavior is a clear rejection boundary. It used only three network reads, but repeatedly handled a cached 10.25 MiB snapshot while materialising 125 candidates. The benchmark does not separately isolate structured-clone, lookup, filtering, and garbage-collection time, so it does not assign the delay to one browser-client operation.

At this size, Trie was much faster for the uncovered selective query even with 117 network reads. A covering index remained substantially faster than either full-document path:

  • 95.53 percent faster at p50 than the large-profile Snapshot uncovered query
  • 60.00 percent faster at p50 than the large-profile Trie uncovered query

Covered range

The range returned 25 documents from covering index fields.

ProfileSnapshot p50Snapshot p95Trie p50Trie p95Index candidates
Small384.38 ms1,990.83 ms374.21 ms1,583.73 ms39
Medium473.98 ms1,612.96 ms510.99 ms1,919.19 ms1,500
Large1,044.55 ms2,115.30 ms1,026.00 ms2,018.80 ms7,500

Current range planning selected every value above the lower bound before applying the upper bound, so the 25-document large result evaluated 7,500 index candidates. Covering fields still kept the operation to two network reads and avoided loading document pages.

Full scans

ProfileSnapshot p50Snapshot p95Snapshot successTrie p50Trie p95Trie readsTrie success
Small376.38 ms1,701.38 ms28/281,100.53 ms6,163.25 ms11928/28
Medium434.50 ms2,143.41 ms28/281,979.30 ms11,090.79 ms27427/28
Large645.52 ms1,086.59 ms28/282,007.04 ms7,354.85 ms27426/28

Snapshot p95 was 72.39 to 85.23 percent faster than trie. Three trie scan samples failed with client transport timeouts and remain in the evidence.

Snapshots remain the correct current layout for scan-heavy collections.

Writes

The write workload updated one document in the 25,000-document indexed collection. Each of seven regional callers used its own collection, so these measurements do not contain cross-region conflicts.

Layoutp50p95SuccessR2 readsR2 writesMean bytes writtenCAS retries
Snapshot5,596.32 ms16,754.83 ms112/11243810,6530
Trie6,438.56 ms20,177.48 ms112/11285366,2650

Snapshot wrote 121.33 percent more bytes, but was 13.08 percent faster at p50 and 16.96 percent faster at p95. With two global secondary indexes, object round trips outweighed lower Trie byte count in this test.

This does not mean snapshot writes scale indefinitely. Snapshot write bytes still grow with the collection. Current indexes materially change the write comparison and must be included in layout decisions.

Simultaneous multi-region writes

Seven callers started five snapshot updates and five trie updates against the same large collection generation in each of two replicates.

Large-profile write p95

Layoutp50p95 among successesSuccessMean CAS retriesMean R2 readsMean R2 writes
Snapshot11,332.98 ms72,483.54 ms66/70, 94.29%1.62110.4858.273
Trie14,356.41 ms85,319.01 ms69/70, 98.57%2.21725.73911.246

Four Snapshot failures were Cloudflare 503 responses after long requests. Trie had one R2 internal write error. Failed operations are not included in the latency percentiles.

Both layouts are poor fits for sustained globally contended writes. The retry protocol preserved successful updates, but latency and availability degraded far beyond a reasonable interactive target.

Envelope limit validation

Every one of the 14 regional read runs fetched a 16,336-byte gzip envelope whose decoded payload was 16,777,217 bytes. All 14 rejected it at the 16,777,216-byte limit.

This validates the hardened decompression path in the Cloudflare Worker runtime. The benchmark does not claim that the 16 MiB default is suitable for every application. It is the supported normal-object boundary for ThimbleDB’s small-app target.

Current recommendation

Most measured cold reads and every large write result exceed normal interactive latency targets. Current production use therefore depends on warm browser cache hits dominating user activity. Cold storage access should be treated as initial loading, recovery, or background work rather than a request-critical UI path.

Use snapshots for:

  • small and medium collections
  • full scans
  • reference data
  • low write rates
  • the lowest object-request count

Use tries when:

  • selective full-document queries would repeatedly process a large snapshot
  • lower transfer volume matters more than request count
  • collection growth makes snapshot rewrite bytes unacceptable
  • measured contention and latency remain within the application’s limits

Use covering indexes whenever a query can be satisfied from declared fields. The large covered equality query avoided the 8.9 to 30.7 second p95 measured for the corresponding uncovered paths.

Do not use either current layout for sustained multi-region writes to one collection root.

Do not use the current release for latency-sensitive applications that require sub-second cold reads or interactive large indexed writes.

Limitations

  • Azure regions approximate geography and do not represent residential last-mile networks.
  • Node 22 ran the production browser read planner, but the benchmark did not measure Chromium scheduling, IndexedDB, or rendering.
  • Authentication and key-grant latency were excluded.
  • One Cloudflare account and one R2 bucket placement were used.
  • Successful-operation percentiles exclude the explicitly reported failed operations.
  • Cloudflare and network conditions vary over time.
  • Costs were not measured.
  • These results compare ThimbleDB layouts with each other, not with another database.

Historical authenticated browser run

The 24 September 2026 artifacts remain available:

evidence/r2-browser-multiregion-trie-2026-09-24.json
evidence/r2-browser-multiregion-snapshot-2026-09-24.json

That run used Chromium 153, a production custom domain, real Entra session exchange, three Azure regions, a 128-product catalogue, and a 32-customer scan. It established:

  • warm in-memory snapshot p95 of 1.6 to 8.3 ms
  • snapshot cold-read improvement of 29 to 53 percent over trie
  • materially slower cold reads and external session creation

The historical browser measurements and the current temporary-Worker measurements use different workloads and should not be compared as a single time series.

This page is built from the repository source.

View or improve this page on GitHub