Phil Ewels
05/06/2026, 8:14 AMbbmap clumpify. The overall concept is fairly simple - if we sort / group the raw reads in FastQ files then we can achieve better gzip compression rates and save disk space.
It struck me that TrimGalore would be a great place to do this. We're already writing new FastQ files here, so we can do this optimisation in-flight and avoid having an additional copy of FastQ files in the work dir / scratch.
I've had a play with this yesterday / last night and tried a bunch of different implementation approaches. My favourite is to do it all in-memory, as long as we give TrimGalore enough memory to fit the raw data (it'll still work under this, it just kicks out the bins sooner so is less efficient).
Disk space savings vary massively by data type, but on low complexity libraries it's fairly significant:
• Long read: basically 0% savings and super slow. Don't do this.
• WGS: Diverse, pretty minimal savings (5-10% from memory)
• RNA-seq PE: 29% smaller
• ChIP-seq SE (28.6M reads): 24.0% smaller
• ATAC-seq PE: 51.0% smaller (best so far — Tn5 bias creates redundancy)
• Ribo-seq PE: 44.2% smaller
I'm doing some final cleanup and testing now before opening a PR, but I think this sounds pretty promising: 1/3rd to 1/2 disk space footprint after running TrimGalore with zero data changes (PE files are kept in sync) and only minimal run-time slow down.Jonathan Manning
05/06/2026, 8:21 AMFelix Krueger
05/06/2026, 8:26 AMLooked at squish — three gotchas:
1. Loads all reads into memory (README says so). For 84M PE reads that's ~30 GB RAM. Not the streaming approach you described — that'd be a hypothetical future version.
2. Single-file only, no paired-end correspondence. R1 and R2 would get shuffled independently and lose pair alignment, which breaks basically every downstream tool. Means we couldn't even run it as a post-trim_galore archival step on PE data without re-implementing pairing.
3. The "30%" is the top of a 3-35% range — their own README demo example gets ~10%. So gains depend a lot on input redundancy.
Porting the idea properly into TG would mean a from-scratch streaming + PE-aware Rust iimpl + byte-identity matrix work for the reordered output. Could be a fun opt-in --small-gzflag for v2.2 post-GA, but probably not worth chasing pre-GA given the modest expected wins.Jonathan Manning
05/06/2026, 8:27 AMPhil Ewels
05/06/2026, 8:28 AMHow much more memory?Need final round of benchmarks to answer this properly, but I think it's ~the size of the input files. So if you have 2x 10GB FastQ files, it'll need 20GB-ish memory.
Phil Ewels
05/06/2026, 8:29 AMFelix Krueger
05/06/2026, 8:29 AMPhil Ewels
05/06/2026, 8:30 AMJonathan Manning
05/06/2026, 8:30 AMPhil Ewels
05/06/2026, 8:31 AMJonathan Manning
05/06/2026, 8:31 AMPhil Ewels
05/06/2026, 8:31 AMPhil Ewels
05/06/2026, 8:32 AMFelix Krueger
05/06/2026, 8:32 AMJonathan Manning
05/06/2026, 8:34 AMJonathan Manning
05/06/2026, 8:35 AMJonathan Manning
05/06/2026, 8:41 AMMatthias Zepper
05/06/2026, 8:46 AMFelix Krueger
05/06/2026, 8:48 AMFelix Krueger
05/06/2026, 8:50 AMPhil Ewels
05/06/2026, 8:51 AMJonathan Manning
05/06/2026, 8:52 AMPhil Ewels
05/06/2026, 8:52 AMPhil Ewels
05/06/2026, 8:52 AMFelix Krueger
05/06/2026, 8:52 AM--high_compression to achieve higher compression, but taking longer to generateJonathan Manning
05/06/2026, 8:54 AMFelix Krueger
05/06/2026, 8:55 AMPhil Ewels
05/06/2026, 8:56 AM--clumpify or --clumpify <int> : clumps reads. If an integer is used, compresses to that level (like --high_compression, which is why I removed that)
• --memory if specified, tunes the clumping to that. Bigger the better, up to the point of the input filesizes.
Thebudget controls the total bin-buffer footprint regardless of how big the input is. With the default --memory 4G, peak RSS will be roughly 4 GB + ~200 MB baseline = ~4.2 GB, no matter whether the input is 100 MB or 100 GB. Records stream through fixed-size bin buffers; once a bin fills, it flushes to a worker for compression and the buffer is reused.--memory
What input size does affect is compression quality: you get the best results when memory is comparable to the uncompressed input size, because then bins can hold most/all reads sharing a minimizer in one gzip member instead of fragmenting across multiple flushes.
For your 10 GB compressed file (~40 GB uncompressed):
• Default `--memory 4G`: works fine, ~4.2 GB peak RSS, but compression is suboptimal — bins flush mid-stream and same-prefix reads split across gzip members.
• `--memory 16G`: ~16 GB peak RSS, better compression. The bins are large enough to hold a meaningful fraction of each minimizer's reads.
• `--memory 40G+`: ~40+ GB peak RSS, near-optimal compression. Bins likely hold all their records to EOF, single flush per bin (matches what bbmap clumpify and squish achieve).
Phil Ewels
05/06/2026, 8:57 AMBut I want to get the rnaseq release out ASAPNo need to hold the release I think. It's purely an optimisation / addition, so can just add in the extra flag at a later stage if desired
Matthias Zepper
05/06/2026, 8:57 AMPhil Ewels
05/06/2026, 8:59 AMBut I want to get the rnaseq release out ASAPCould even leave this as a user-configurable flag, needing no changes to the pipeline at all. • Default: no clumpify, go for maximum speed, don't care about filesizes • Opt in via config flags: Clumpify, fractionally slower with more memory usage, smaller file sizes. I hope that the benchmarks get to a point where it's a sensible default, but need to play more before I can convince myself of that.
Phil Ewels
05/06/2026, 9:02 AMUse some bitpacked ProtoBuf protocol with streamingThis doesn't work with distributed cloud computing unfortunately. But yeah, using an alternative compression method for intermediate files within a pipeline is an interesting idea 👍🏻
Phil Ewels
05/06/2026, 9:03 AMMatthias Zepper
05/06/2026, 9:12 AMAlso side note: some people use TrimGalore outside of Nextflow pipelines. Jus' saying.. 👀 😅I am not saying you should drop FastQ for those who want it. Just that optimizing it around arbitrary constraints like Gzip is a poor idea.
This doesn't work with distributed cloud computing unfortunately. But yeah, using an alternative compression method for intermediate files within a pipeline is an interesting idea 👍🏻Depends on Firewall settings, but I do not think it is entirely impossible - but admittedly a bigger undertaking. Iroh has all the building blocks potentially...
Matthias Zepper
05/06/2026, 9:13 AMJonathan Manning
05/06/2026, 9:14 AMPhil Ewels
05/06/2026, 4:15 PMPhil Ewels
05/06/2026, 4:15 PMPhil Ewels
05/06/2026, 4:16 PMPhil Ewels
05/06/2026, 4:16 PMPhil Ewels
05/06/2026, 4:17 PMFelix Krueger
05/06/2026, 6:23 PMPhil Ewels
05/06/2026, 7:50 PM1. scRNA-seq 10x got larger by 6.2% at default L1. The previous docs table showed −13% at compression 6. My hypothesis: 10x R1 (28-byte cell barcode + UMI) is highly redundant and benefits from sorting; R2 (variable cDNA) follows R1's order to preserve pair lockstep, ending up in nearly random order vs the natural flowcell-cluster ordering of the input. At L1 the R2 disruption appears to outweigh the R1 win....straaange 🤯
Phil Ewels
05/06/2026, 7:50 PMPhil Ewels
05/06/2026, 8:23 PMFelix Krueger
05/06/2026, 8:37 PMPhil Ewels
05/06/2026, 8:54 PMFelix Krueger
05/07/2026, 9:34 AMFelix Krueger
05/07/2026, 9:39 AMFelix Krueger
05/07/2026, 1:18 PMPhil Ewels
05/07/2026, 5:00 PM--clumpify approach more valuable: the clumpy read order is maintained in the STAR alignment. Aligned reads are streamed into the BAM in order, and the BAM files use gzip compression internally. So by having clumpy FastQ output files from trimming, we also get a decent file size saving in aligned BAMs from the downstream steps! Means it's no longer just intermediate files, so quite a bit more valuable.Phil Ewels
05/07/2026, 5:01 PM