BioProject → run¶
Needs: a BioProject accession Feeds: run → files Routes: 5 measured, all within 0.4% of each other once two archive caps are worked around.
The direction with the most competing implementations. Its "clear winner" was mostly two caps.
Routes¶
| Route | Provider | Requests | Reads |
|---|---|---|---|
ena_filereport |
ENA portal | 1 | filereport?result=read_run |
sra_be_direct_cgi |
SRA backend | 2 | esearch db=sra [GPRJ] → sra-db-be.cgi |
sra_be_elink |
SRA backend | 3 | esearch db=bioproject → ELink → sra-db-be.cgi |
efetch_direct |
E-utilities | 2 | esearch db=sra [GPRJ] → efetch rettype=runinfo |
efetch_elink |
E-utilities | 3 | esearch db=bioproject → ELink → efetch |
Measured behaviour¶
Counted at the unique-run level over the 12,755 BioProjects in the reprocessed table
(reprocessed-prj). That qualifier matters: the 2026-05 sra_be result files held 824,216
rows but only 754,277 distinct runs.
| Route | Unique runs | Empty | Failed | ENA's runs it lacks | Runs ENA lacks | Surveyed |
|---|---|---|---|---|---|---|
efetch_elink |
786,586 | 22 | 0 | 162 | 2,812 | 2026-10-24 to 26 |
sra_be_elink |
785,656 | 22 | 0 | 851 | 2,571 | 2026-10-24 to 26 |
efetch_direct |
784,976 | 23 | 0 | 1,270 | 2,310 | 2026-10-24 to 26 |
sra_be_direct_cgi |
784,935 | 22 | 0 | 1,262 | 2,261 | 2026-10-24 to 26 |
ena_filereport |
783,936 | 23 | 0 | — | — | 2026-09-15 |
- Every NCBI route is within 0.4% of ENA. The differences in both directions are fractions of a percent. Six weeks separate ENA's census from the NCBI re-survey, and runs released in between are on the NCBI side of that gap.
- No failure is left. Some projects failed a first pass and answered on retry: 2 on
sra_be_direct_cgi, 4 onsra_be_elink, 2 onefetch_directand 3 onefetch_elink. Every retry was a transport error: read timeouts, dropped connections and 502s. PRJNA772116, with 73,888 runs, answeredsra_be_elinkonly on its fourth pass. - ELink and
[GPRJ]find different experiments, and each is wrong once.efetch_elinkreturns runsefetch_directdoes not, and never the reverse:- 1,100 of them, in 2 projects, belong to the project.
[GPRJ]misses them, as with PRJNA66167's 411. - 607, in 22 projects, belong to a sibling under the same umbrella. ELink adds them, as with PRJNA1033389's
- The resolver marks them UNCONFIRMED, because ENA does not hold them for the project.
- 1,100 of them, in 2 projects, belong to the project.
The bare accession, searched without a field¶
The maintainer's notebook searches db=sra for PRJNA940674 with no field, where
efetch_direct asks for PRJNA940674[GPRJ]. Surveyed as a route on 2026-10-26 over the
same 3,000 projects (bioproject->run:esearch_sra_runinfo):
- The same answer. It returned 162,808 distinct runs, against
[GPRJ]'s 162,854. The differences in both directions are 14 and 60 runs, which is drift between two survey days. - The same miss. It returns PRJNA66167's same 5,499 runs, missing the 411 that
[GPRJ]misses. NCBI evidently reads a bare project accession as that field. - No other projects' runs. It returns none of the sibling runs ELink adds.
It is therefore not declared as a route here, nor towards experiment, study or BioSample,
where it would repeat efetch_direct's request with a different spelling. Towards sample and
GEO sample, where no route existed, it is one of the promoted routes
(promoted from BioProject). Its verdicts are exported under
data/surveys/sample_3000@reprocessed-prj/.
What the 2026-05 numbers were¶
| Route | Unique runs, 2026-05-12 | Failed | What capped it |
|---|---|---|---|
sra_be_elink |
754,332 | 33 | the history form stops at 5,000 runs |
sra_be_direct_cgi |
754,277 | 15 | the same |
efetch_elink |
674,186 | 30 | one EFetch stops at 10,000 records |
efetch_direct |
673,157 | 14 | the same |
On those numbers this page said ENA holds 111,665 runs efetch never returns. That was a
true set difference, over runs, from one survey. It described two archive caps, not the
routes. Measuring why is what found them.
How the re-survey was protected¶
Large answers misbehave without an error, so the routes now refuse three things a client would otherwise record as the answer:
- A capped
sra-db-behistory. The route asks for the project by accession instead. - An empty answer to a history ESearch counted. Under load,
sra-db-beanswered PRJNA772116, with 73,888 runs, with an empty 200. - A body cut off mid-row. PRJEB14362's 46,468 runs came back as 15,265 and as 23,748 rows, each ending in a short row, with HTTP 200.
Each raises a retryable failure, and a project that still fails is recorded FAILED, never EMPTY or short. In the re-survey every large project answered whole.
Recommendation¶
Use ena_filereport. One request, as complete as any route, no failures across 12,755
projects, and it answers for every issuing archive — unlike the NCBI routes, which
only reliably resolve NCBI-issued accessions.
ranked() now puts it first on cost, not on yield. All five routes sit in one yield band and
fail nothing, so the order is ENA (one request), then efetch_direct and sra_be_direct_cgi
(two), then efetch_elink and sra_be_elink (three), each pair by route id. In the default
union mode every route is asked anyway, and the runs ENA lacks come from the NCBI routes.
The 23 projects ENA reports as empty are withdrawn, private or unreleased. BioProject → BioSample reports 25 through the same endpoint: two projects have runs in ENA but no BioSample on any of them, so they resolve here and are empty there. Five of them are the BioProjects of the same GEO series that resolved to nothing in the GEO census, so two independent routes over two different corpora agree about which data is not released.