During my internship at Brigham and Women’s Hospital, I worked with the pharmacology team to fix their painfully slow genomic analysis pipeline. Researchers were waiting 2-3 days for results, which was killing their productivity and frustrating everyone involved.
The Problem
The team was analyzing 5TB+ of multi-omics data - RNA sequencing, protein expression, metabolomics, plus clinical metadata. Their pipeline was a collection of bash scripts that:
- Processed everything sequentially (one sample at a time)
- Used text files for massive joins
- Requested way more cluster resources than needed (500GB memory for 50GB jobs)
- Could only run on the ERIS cluster, no local testing possible
Between the inefficient code and cluster queue times, researchers waited 48-72 hours just to find out if their analysis worked. If it failed, that’s another 2-3 days down the drain.
What I Did
First, I profiled the existing pipeline to understand where time was being wasted. Turns out, most of the “computation time” was actually:
- Waiting in queue due to overestimated resource requests
- Reading/writing massive text files repeatedly
- Processing samples one by one instead of in parallel
I rebuilt the pipeline using PySpark and switched the storage format to Parquet:
- Parquet files: 60% smaller than text files, way faster for column-based queries
- Parallel processing: Partitioned by sample ID so multiple samples process simultaneously
- Right-sized resources: Profiled actual memory usage and requested appropriate amounts
- Local testing: Set up Jupyter notebooks so researchers could test locally before cluster submission
The Results
The improvements were dramatic:
- Processing time: 48-72 hours → 15 minutes
- Queue wait time: 2-6 hours → 5-10 minutes
- Storage needs: Reduced by 60%
- Researcher productivity: From 2-3 analyses per week to 10-15
The 15-minute runtime includes all the joins, transformations, and statistical calculations. The speedup came from:
- Parallel processing (biggest win)
- Columnar storage format (Parquet)
- Eliminating redundant I/O operations
- Actually using the cluster’s capabilities
What Made This Work
The key insight was that this wasn’t really a “big data” problem - it was a “badly organized data” problem. The cluster had plenty of power; the pipeline just wasn’t using it properly.
I also learned that scientists don’t care about fancy features - they want reliability and speed. So I kept the interface simple, wrote clear documentation, and made sure they could modify the pipeline themselves after I left.
Technical Details
- Data: 1.3TB of genomic and clinical data
- Cluster: Harvard Medical School’s ERIS HPC cluster
- Old stack: Bash scripts + text files + sequential processing
- New stack: PySpark + Parquet + parallel processing + Jupyter
- Optimization: Proper resource allocation, partition strategy, columnar storage
By the end of my internship, the team could iterate on analyses in real-time instead of waiting days. They were exploring hypotheses they’d previously avoided because the computational cost was too high.
Note: Specific code and implementation details remain confidential per BWH/Harvard Medical School policies.