Engine

Built to query biology at terabyte scale

BioQ answers over 5.74 billion metagenomic proteins and 149 million UniProt records without loading them into a database. These are the techniques behind it, with the numbers we measured.

5.74Bmetagenomic proteins you can fetch by ID
107 GBof indexes in front of 1.15 TB of source data
1.5M×faster “no Pfam domain” answers: 35.6 min to 1.4 ms
230 q/sat 64 concurrent users, median 165 ms

Most tools look up what is registered. BioQ asks for what meets a condition.

Portals and BLAST-style tools answer “show me X” and “what resembles X”. Discovery questions are conditions across datasets, so the engine joins its layers for you.

Lookup

Show me UniProt P04637

Sequences similar to mine

Proteins sampled from soil

Condition

Assemblies that contain protein A but not protein B

Large soil protein families with no known domain

Every database that knows this ID, and every one that never looked

What it takes to do it yourself

Six real questions, timed both ways. Download times use transfer rates we measured from the public archives; your connection may differ.

Fetch one metagenomic protein by ID, out of 5.74 billion
Yourself≈3 h

Download 1.11 TB, then scan 46,303 unsorted row groups.

BioQ0.17 s

One request. 0.17 s for a cluster representative; up to 14.5 s cold for other members.

64K×
Which Pfam domains does this protein carry, or none?
Yourself≈7.5 h

Download 117.6 GB, then build a 66 GB forward index (74 min).

BioQ40 ms

One request, about 40 ms over the internet.

678K×
Assemblies with protein A where protein B is absent
Yourself≈2.4 h

Download 26.1 GB of unseekable gzip, then decompress 112 GB for every question.

BioQ≤1.5 s

One request reads one 5 MB block.

6K×
The sequence of one UniProt TrEMBL record
Yourself≈2.3 h

Download 40.6 GB, then decompress everything before the record.

BioQ76 s

76 s the first time at that depth; every repeat is served from cache.

110×
Bases at a coordinate, in 544,891 RefSeq sequences
Yourself≈1 h

Download 11.9 GB, then build BGZF and FASTA indexes (19 min).

BioQ0.07 s

One request; 1.7 ms inside the engine.

51K×
Which databases know this identifier, and which never looked?
Yourself≈3.3 h

Pull ≈1.2 TB of archives to check them one by one.

BioQ0.12–0.48 s

One request asks nine layers at once.

25K×

Bars use a log scale from 1 millisecond to 10 hours.

Five layers between you and 1.15 TB

Where you work

Same answers everywhere
Web appREST APIResearch agentMCP · Claude · ChatGPT

Gateway

Who can ask, and how much
Google · email sign-inAPI keysDaily quotasParameter validationResponse scrubbing

Engine

20 of 22 layers live
/whereis/search/lookup/domains/cooccur/depmap/affinity/interaction/dna+12

Indexes we build

≈107 GB, checked against the source
parquet footer indexseekable C2 storeBGZF + .gzi/.fai32 MB co-occurrence blocksTrEMBL offset indexPfam forward + invertedMMseqs2 k-mer index

Public sources

Read in place, never copied whole
UniProtMGnifyPfamPDBAlphaFold DBChEMBLDrugCentralGtoPdbClinVarSTRINGBioGRIDDepMapRefSeqGRCh38GRCm39

Six indexing decisions that make it fast

The file’s own footer is the index

1.11 TB of parquet already stores min and max IDs for all 46,303 row groups. That 827 MB footer becomes a 2 MB index.

Before1.11 TB
After25.5 MB

A layout built for many readers

128.7 M representative sequences rewritten into a seekable store: each lookup moves 46 KB instead of up to 242 MB.

Before42.9 s
After168 ms

Random access inside gzip

Plain gzip must be decompressed from the start. Rewritten as BGZF with a block index, any coordinate is one seek.

Before1.40 s
After1.7 ms

One block per question

A 26 GB gzip that could not be seeked became 5,773 independent blocks, with zero records lost and a 404 KB index.

Before715 ms
After13.2 ms

Both directions, packed tight

Pfam protein→domain and domain→protein indexes over 4.62 billion pairs, repacked from 66 GB to 18 GB.

Before35.6 min
After1.4 ms

Indexes written with the data

A sparse index bolted on later took over an hour; written during the build it is free. 102,074 small files packed into four.

Before6,829 ms
After374 ms

Homology search that remembers

MMseqs2 with a pre-built k-mer index. Every result is cached under a fingerprint of the sequence, the parameters and the database version, so a repeat returns instantly and still says when it was computed.

8.8–10 s

first search over the internet

0.04 s

the same search again

Positive controls

QueryE-valueIdentity
HIV reverse transcriptase1.3×10⁻¹³36.7%
Human hemoglobin α1.1×10⁻¹¹99.0%
E. coli β-lactamase2.6×10⁻³³50.0%

Why we index deliberately

A k-mer index runs 20–46× the size of its database. Swiss-Prot (575,748 sequences) is live; larger corpora are being indexed.

DB1.59 GB
Index73 GB

One question, every layer, honest answers

/whereis asks nine layers in parallel, each with its own deadline, and reports what each one actually did. Over the internet it answers in 0.12–0.48 s.

GET /api/v1/whereis?id=MGYP000000149140found
MGnify C2Found1.05 ms
MGnify proteinsFound2,017 ms
MGnify assembliesFound103 ms
Pfam domainsSearched, absent0.13 ms
UniProt TrEMBLNot applicable
Pfam domain indexNot applicable
StructuresNot applicable
BindingNot applicable
ClinVarNot applicable

Claims need independent evidence

An association needs at least three assemblies from different collection runs. Every answer carries the verdict.

testable · ≥3weak · <3no claim · 1 run

No ratio without a universe

The same overlap reads 1.000 or 212.5 depending on the universe. The engine refuses to guess it.

Guessed1.000
Stated212.5

Faster under load

On the seekable store, median latency improves as concurrency rises, with zero failures.

Queries per second

1×5.4 q/s
32×138.9 q/s
64×230.2 q/s

Median latency

1×179 ms
32×168 ms
64×165 ms

Before it serves, the engine must answer five real questions

  1. KRAS: top dependent lineage is pancreas
  2. TP53–MDM2 interaction scores at least 700
  3. SARS-CoV-2 spike bases come back from RefSeq
  4. A hemoglobin search finds its homolog
  5. A negative control proves absence

Silent wrong answers we found, measured and designed out

395,688

A windowed search missed 395,688 sequences and answered “not found”.

Every row group is now checked; regression test passes 4 of 4.

89.2%

With 2 of 19 TrEMBL shards loaded, 89.2% of records would have looked absent.

Coverage is reported; absence is never assumed.

+1

An off-by-one shifted every protein’s domains by a row while all totals matched.

Builders self-check; readers verify lengths at load.

∅ = ∅

A verifier recorded “match” when both sides were empty.

Verifiers must find something before they compare.

212.5×

A real 212.5× enrichment was reported as 1.000.

No ratio unless the universe is stated.

7.8×

AlphaFold “residues” were atom counts, 7.8× too high.

Rebuilt from Cα records; 4 of 4 controls pass.

Five rules every layer follows

  1. Provenance on every answer.
  2. An index is checked against its source, never against itself.
  3. A partial load answers 503 with a reason, never a silent “none”.
  4. Builds assert their totals.
  5. Not done without a positive control.

The test suite catches 13 of 13 deliberately broken contracts.

In pilot

Next: semantic search with protein language models

We embedded all 575,748 Swiss-Prot proteins with ESM-2 (650M) in 47.6 minutes on one GPU and measured it against MMseqs2 on remote homologs.

Pairs MMseqs2 cannot align

MMseqs240.7%
ESM-246.9%

Pairs MMseqs2 can align

MMseqs286.8%
ESM-278.2%

They complement each other, so the plan is MMseqs2 first, then ESM-2 re-ranking. Not live yet.

See it answer your question

Free accounts get the full engine: every layer, the agent and the API.

Start freeAPI