10x Genomics datasets are collections of sequencing reads and processed matrices produced by Chromium single-cell and spatial assays, distributed as FASTQ files, BAM alignments, and count matrices in Matrix Market (MTX) or HDF5 format, with metadata in CSV and per-experiment JSON. A typical Chromium single-cell run returns three linked files: a filtered feature-barcode matrix (cells by genes), a barcodes list, and a features list; these arrive as either an MTX triplet or a single HDF5 (.h5) file. Understanding which file holds counts, which holds coordinates, and which holds QC metrics is the prerequisite for every downstream analysis.
How 10x Data Is Generated and Why Format Matters
Every 10x assay rests on a droplet or spot barcode. In Chromium single-cell RNA-seq, a gel bead carries millions of identical oligonucleotides. Each molecule contains a 16-nucleotide 10x barcode, a 12-nucleotide unique molecular identifier (UMI), and a poly-dT primer. A cell and one bead are co-encapsulated in an oil droplet; the cell lyses, mRNA is reverse-transcribed, and every transcript gets tagged with the same barcode and a distinct UMI. Sequencing then reads the barcode, the UMI, and the transcript.
The barcode identifies which cell a read came from. The UMI identifies which original mRNA molecule it came from, so PCR duplicates collapse into one count. In plain terms: barcodes label cells, and UMIs count molecules.
This mechanism explains the file structure. Raw reads must carry the barcode, so they exist as FASTQ with a companion barcode read. After alignment, barcodes become columns and features become rows, which produces a sparse matrix. Because a single cell expresses only roughly 1,000 to 5,000 of ~20,000 protein-coding genes, the matrix is mostly zeros, typically 90-95 percent empty. Sparse storage is therefore mandatory; a dense matrix of 10,000 cells by 20,000 genes would need 1.6 GB as 64-bit floats versus a few hundred MB in MTX.
Spatial assays change one term. Visium spots are 55 micrometers in diameter and sit on a 100-micrometer center-to-center grid, roughly 4,992 spots per 6.5 mm capture area. Each spot carries a known barcode, so its count vector maps to a fixed x-y coordinate. The counts still live in a matrix, but a separate positions file attaches geometry.
The number that ties raw data to processed data is sequencing saturation. 10x reports it per library, and it equals 1 minus (unique UMIs divided by total reads). A well-saturated single-cell library reaches roughly 70-90 percent; below about 50 percent, additional sequencing still recovers new molecules, and re-sequencing is usually cheaper than re-running the experiment.
The File Formats Decoded
The single-cell pipeline (Cell Ranger) emits a standardized directory. The table below compares the principal output formats and when each applies.
| Format | Extension | What it holds | Typical size (10k cells) | Best used for |
|---|---|---|---|---|
| Matrix Market triplet | .mtx + .tsv | Sparse integer counts | 200-600 MB | R/Seurat, scanpy, portability |
| HDF5 | .h5 | Counts plus feature and barcode metadata | 150-500 MB | Python/h5py, Cell Ranger secondary use |
| AnnData | .h5ad | Counts, embeddings, annotations | 300 MB-2 GB | Scanpy workflows, archival |
| BAM | .bam | Aligned reads with barcode tags (CB, UB) | 20-80 GB | Re-quantification, variant calling |
| FASTQ | .fastq.gz | Raw reads (I1, R1, R2) | 15-60 GB | Re-alignment in Cell Ranger or STARsolo |
| Loupe Browser file | .cloupe | Indexed counts for visualization | 100-400 MB | Non-coder exploration |
| Feature reference | .csv.gz | Gene IDs, names, biotypes | 5-15 MB | Alignment and annotation |
| Metrics summary | .csv | Per-library QC (saturation, reads) | <1 MB | Batch QC and pass/fail |
HDF5 stores data hierarchically, like folders inside one file: /matrix/data holds nonzero counts, /matrix/indices and /matrix/indptr encode sparse positions, and /matrix/shape gives dimensions. Matrix Market instead writes one line per nonzero value as row, column, value, preceded by a two-line header. HDF5 reads faster and packs metadata; MTX is human-readable and platform-neutral.
The barcodes file lists column names, usually 16-nucleotide sequences such as AAACCTGAGAAACCAT-1, where the trailing -1 designates library 1. The features file lists row names as Ensembl gene ID plus symbol plus biotype. Mismatch between these lists and the matrix is the single most common cause of failed imports.
Quantified Context: What a Real Dataset Looks Like
A mid-sized experiment clarifies the numbers. Take four Chromium single-cell libraries, each targeting 10,000 cells, on a NovaSeq X. Each library yields roughly 40,000 reads per cell, or 400 million reads, and about 30-45 GB of gzipped FASTQ. Alignment produces BAM files near 2-3 GB per library after compression. Cell Ranger takes roughly 4-8 hours per library on 16 cores and 64 GB RAM.
The filtered matrix keeps only barcodes passing the cell-calling threshold, which Cell Ranger sets via an empty-droplet model. A 10,000-cell library then yields a matrix of 10,000 columns and ~20,000-36,000 rows (depending on reference), with 30-60 million nonzero entries. Median genes detected per cell typically lands at 1,500-3,000 for peripheral blood mononuclear cells and 2,000-4,000 for solid tissue after dissociation.
The unfiltered (raw) matrix is far larger: it retains all ~700,000 to 1,000,000 observed barcodes, of which under 2 percent are real cells. This is the key asymmetry. The raw matrix may be 5-10 times the size of the filtered one, and most of it is ambient RNA from lysed cells. Choosing filtered versus raw is a real decision, not a formality.
Reconcile the thresholds in one place: a library is worth re-sequencing if saturation is under about 50 percent, and a barcode is called a cell if its UMI count exceeds the empty-droplet cutoff, which in practice sits near 500-1,000 UMIs for standard 3' chemistry but varies with cell type and loading.
Variations and Edge Cases Across Assays
Not every dataset looks like standard 3' gene expression. The format shifts by assay, and treating them identically causes silent errors.
Single-cell ATAC-seq does not count genes. Its matrix rows are genomic peaks (typically 100,000-300,000 per experiment) and its columns are cells. The values are fragment counts per peak, and the .h5 carries a different feature type. A key edge case: ATAC data also ships a fragments file (.tsv.gz) listing every cut site as chromosome, start, end, barcode, and count. Downstream tools such as ArchR and Signac expect the fragments file, not the matrix, for peak calling.
Single-cell immune profiling (5' chemistry) adds V(D)J contigs as a separate contig annotation CSV, plus a clonotype file. The gene-expression matrix excludes the rearranged loci, so clonotype analysis requires the companion files. Multiome assays produce two matrices (RNA and ATAC) from one barcode space, and the barcodes must be matched across the two.
Spatial formats diverge most. Visium returns a spatial folder containing scalefactors_json.json (pixel-to-micrometer conversion, usually ~0.17 for standard capture) and tissue_positions.csv with pixel and array coordinates per spot. Xenium in situ data returns a transcripts.parquet file with per-molecule x-y coordinates and a cells.parquet with cell boundaries, not a classic count matrix. Each of these needs its own reader.
A useful non-obvious caveat: the .cloupe file is a visualization index, not an analysis input. Tools that accept it will often re-derive counts and lose custom annotations. Treat it as read-only.
Common Misconceptions and a Practical Workflow
The most persistent misconception is that the .h5 file is "the raw data." It is processed and filtered just like the MTX triplet; raw reads live only in FASTQ. A second is that MTX and HDF5 can be swapped freely — they encode the same numbers but different metadata schemas, and a naive converter drops feature biotypes. A third is that UMI counts equal transcripts; they equal captured molecules, and capture efficiency varies from roughly 10 to 30 percent by chemistry, so absolute counts are not comparable across kits without normalization.
Red flags when you open a dataset:
- Column count in barcodes.tsv does not match the matrix width (import will silently transpose or drop cells).
- Saturation in metrics_summary.csv under 50 percent (under-sequenced; re-run before analysis).
- Median UMIs per cell under 500 (likely empty droplets or degraded input).
- Feature list built from a different reference genome than the BAM (gene IDs will not map).
- Raw matrix used without empty-droplet filtering (ambient RNA inflates every cluster).
- Visium scalefactors missing (spot coordinates will be in the wrong units).
What to actually do, in order:
- Verify file integrity: confirm barcodes, features, and matrix dimensions agree before importing.
- Read metrics_summary.csv first and log saturation, reads per cell, and median genes per cell.
- Choose filtered matrices for expression analysis and raw matrices only for ambient-RNA or doublet work.
- Convert to AnnData or Seurat once, archive the original triplet or .h5 untouched, and record the reference version used.
- Keep the BAM and fragments files for any re-quantification or variant need; do not discard them after matrix generation.
- For spatial data, load the tissue positions and scale factors alongside counts so geometry is never lost.
A Short Timeline of Format Evolution
10x has changed its default outputs over time, and older public datasets often carry legacy formats. The timeline below tracks the shifts a modern analyst will encounter.
| Year | Milestone | Practical consequence |
|---|---|---|
| 2015 | Chromium launched; Matrix Market triplets standard | .mtx remains the interchange baseline |
| 2016 | Cell Ranger 1.x; .h5 introduced | Two parallel processed outputs begin |
| 2019 | Visium spatial datasets released | Position and scalefactor files added |
| 2020 | AnnData/.h5ad adopted widely by scanpy | Single-file analysis object becomes common |
| 2021 | Multiome and ATAC standardized | Per-modality matrices with shared barcodes |
| 2022 | Xenium in situ data | Parquet transcripts replace matrix-first design |
| 2024 | Cell Ranger 8.x; larger references | Higher row counts in features files |
| 2026 | Cloud-hosted datasets and standardized manifests | Dataset discovery via manifest, not file bundles |
The direction is consistent: from a sparse matrix as the center of the universe toward a bundle of modality-specific files tied together by a barcode or coordinate key. Public 10x datasets now number in the thousands and span every major assay, but the older ones still arrive as MTX triplets.
Limitations and What the Formats Cannot Tell You
The formats capture counts and geometry; they do not capture biology directly. A filtered matrix has already discarded information — empty droplets, ambient RNA, and low-quality cells — and that loss is irreversible without the raw matrix or BAM. Cross-dataset comparison is limited because chemistries differ in capture efficiency, and the same gene may show a two- to threefold count difference for technical reasons alone.
Spatial resolution is a hard constraint. Visium's 55-micrometer spots capture 1-10 cells each, so a spot count is a mixture, not a single cell; single-cell spatial resolution requires Xenium-class assays, which return their own coordinate files. Finally, the formats say nothing about batch. Two libraries run on different days can differ more than two conditions, and no file field automatically corrects it. Format understanding gets you to clean counts; experimental design determines whether those counts mean anything.
Anyone working with 10x data should be fluent in three files before anything else: the sparse count matrix, the barcode-feature pairing, and the metrics summary. Master those, and the rest of the 10x ecosystem — from Chromium to Visium to Xenium — becomes a set of variations on one well-defined theme.