Sequences, FASTA & FASTQ Explained

Two text formats hold most of the world's sequence data. By the end of this lesson you'll be able to read both - and know exactly what every line means.

🟢 Beginner ⏱️ ~45 min 🐍 Python 🌐 Runs free in Colab

Before you start

You can read a little Python and run code in a notebook. New here? Do the Introduction first, or the Python setup.

Learning objectives

By the end of this lesson you will be able to: recognise a FASTA record from its > header line, read the four-line structure of a FASTQ record and what its quality line means, tell the two formats apart at a glance, and open and inspect either format as plain text.

Why these two formats matter

When a sequencing machine reads DNA or RNA, or when you download a gene or genome, the data almost always arrives as plain text in one of two formats: FASTA or FASTQ. They're the front door to nearly every analysis. The good news: both are simple, human-readable text - you can open them in any editor and understand them once you know the pattern.

FASTA - sequences with a label

FASTA is the simplest. Each record is just two parts: a header line starting with > (the name/description), followed by the sequence itself on one or more lines.

>gene1 human insulin (example)
ATGGCCCTGTGGATGCGCCTCCTGCCCCTGCTGGCGCTGCTG
GCCCTCTGGGGACCTGACCCAGCCGCAGCCTTTGTGAACCAA

That's it. A file can hold one record or millions, each starting with its own > header. FASTA is used for genes, genomes, proteins - any sequence where you don't need quality information.

The > is your friend

Because every record starts with >, counting sequences is as easy as counting header lines - exactly the grep -c ">" trick from the Bash project. One symbol, huge convenience.

FASTQ - sequences with quality

Sequencing machines aren't perfect - each base is read with a certain confidence. FASTQ captures that. Every record is exactly four lines:

@read1                          # 1. ID line, starts with @
ATGCGTACGTTAGCCGTA             # 2. the sequence
+                              # 3. a separator (just a +)
IIIIIIIHHHHHGGGFFF             # 4. one quality score per base

Line 4 has one character for each base in line 2, encoding how confident the machine was about that base. Those symbols look cryptic, but they map to numbers.

Anatomy of one FASTQ record 1 @read1 Identifier - starts with @ 2 ATGCGTACGTTAGCCGTA The DNA / RNA sequence 3 + Separator (just a +) 4 IIIIIIIHHHHHGGGFFF Quality - one score per base
Four lines per record. Lines 2 and 4 are always the same length - one quality score for every base.

Decode the jargon: Phred quality scores

Each quality character represents a Phred score - a number saying how likely the base is wrong. A score of 30 means a 1-in-1,000 chance of error (99.9% confident); 40 means 1-in-10,000. The characters are just those numbers shifted into printable symbols. You rarely read them by eye - tools like FastQC summarize them for you - but now you know what line 4 is.

Hands-on: read both formats

Let's actually parse them with Biopython (you installed it in the foundations track; in Colab, run !pip install biopython first).

▶ Code along

Open a notebook and run each block.

Open a blank Colab →

First, create a small FASTA file right from Python and read it back:

from Bio import SeqIO

# write a tiny FASTA file
with open("demo.fasta", "w") as f:
    f.write(">gene1 insulin\n")
    f.write("ATGGCCCTGTGGATGCGCCTCCTG\n")
    f.write(">gene2 hemoglobin\n")
    f.write("ATGGTGCATCTGACTCCTGAGGAG\n")

# read every record
for record in SeqIO.parse("demo.fasta", "fasta"):
    print(record.id, "|", len(record.seq), "bases |", record.seq)

SeqIO.parse hands you one record at a time, each with an .id (the header) and a .seq (the sequence). That single pattern reads a 2-line file or a 2-million-line file the same way.

Now a FASTQ record - note we also get quality scores:

with open("demo.fastq", "w") as f:
    f.write("@read1\nATGCGTACGT\n+\nIIIIIHHHHH\n")

rec = next(SeqIO.parse("demo.fastq", "fastq"))
print("Sequence:", rec.seq)
print("Quality scores:", rec.letter_annotations["phred_quality"])

Biopython decoded those quality characters into the actual numbers for you. You're now reading both of the formats that start almost every bioinformatics pipeline.

Check your understanding

How do you count the number of sequences in a FASTA file?
Count the header lines - every record starts with >. From the command line that's grep -c ">" file.fasta; in Python, count the records from SeqIO.parse.
What's the key difference between FASTA and FASTQ?
FASTQ adds per-base quality scores. FASTA is just header + sequence (2 parts); FASTQ is 4 lines per record (ID, sequence, +, quality). Use FASTQ for raw sequencing reads, FASTA for finished sequences.
A Phred score of 20 - is that good?
It means a 1-in-100 chance the base is wrong (99% confident). Decent, but most analyses prefer 30+ (99.9%). You'll learn to read these summaries in the quality-control lesson later.
In a FASTQ record, what does line 3 (the line with just a +) do?
Line 3 is a separator, just a +, sitting between the sequence (line 2) and the quality line (line 4). It carries no data of its own.
In a FASTQ record, how does the length of the quality line compare to the sequence line?
Lines 2 and 4 are always the same length because there is exactly one quality character for every base in the sequence.
Next in Track 1

The file-format alphabet soup: SAM/BAM, VCF, GFF, BED →