# GTF: Gene Annotation Files

> The role of GTF files in RNA-seq alignment and quantification, their nine-column structure, gene_id and transcript_id attributes, differences from GFF3, and practical cautions.

After aligning short sequences, or reads, from RNA-seq to a genome, you need a **table of gene locations** to count which gene each read belongs to. That table is usually a **GTF (Gene Transfer Format)** file. GTF is a tab-delimited annotation format based on the GFF version 2 family with conventions added for gene and transcript information.

In one line:

```text
GTF = an annotation file marking the locations of genes, transcripts, and exons on genome coordinates
```

## Where is it used?

GTF is not read data. It is a **reference annotation**. A typical analysis pipeline uses it like this:

```text
FASTQ → alignment (STAR/HISAT2) → BAM
                                  ↓
                             GTF annotation
                                  ↓
                       read count / TPM by gene
```

Common uses:

| Stage | Role of GTF |
| --- | --- |
| Building a genome index | Lets an aligner such as STAR know splice-junction information in advance |
| Counting reads | Lets `featureCounts` and `HTSeq-count` assign reads to genes or exons |
| Quantifying transcripts | Lets RSEM, StringTie, and similar tools interpret transcript structure |
| Interpreting results | Links gene IDs, gene names, and transcript IDs to coordinates |

## Structure of one GTF line

GTF is a tab-delimited text file. Each line represents one feature and always contains **nine columns**.

```text
chr1  HAVANA  exon  11869  12227  .  +  .  gene_id "ENSG00000223972"; transcript_id "ENST00000456328"; gene_name "DDX11L1";
```

| Column | Name | Meaning |
| --- | --- | --- |
| 1 | seqname | Chromosome or contig name, such as `chr1`, `1`, or `GL000...` |
| 2 | source | Annotation source, such as `HAVANA` or `ENSEMBL` |
| 3 | feature | Feature type, such as `gene`, `transcript`, `exon`, `CDS`, or `UTR` |
| 4 | start | Start coordinate |
| 5 | end | End coordinate |
| 6 | score | Score, or `.` if absent |
| 7 | strand | Strand: `+`, `-`, or `.` |
| 8 | frame / phase | CDS frame, or phase. Usually `.` outside protein-coding regions |
| 9 | attributes | Additional information separated by semicolons |

## Coordinate rules

GTF coordinates are **1-based inclusive**.

```text
start = 11869
end   = 12227
```

This means the region includes both endpoints, from base 11869 through base 12227.

Take care with these differences:

| Format | Coordinate rule |
| --- | --- |
| GTF / GFF / VCF | 1-based |
| BED | 0-based, half-open |

Mixing BED and GTF files commonly produces one-base coordinate errors.

## attributes: the most important ninth column

The ninth column is the part of GTF that analysis tools read most often.

```text
gene_id "ENSG00000141510";
transcript_id "ENST00000269305";
gene_name "TP53";
gene_biotype "protein_coding";
```

Key attributes:

| Attribute | Meaning |
| --- | --- |
| `gene_id` | Unique gene ID, usually the most stable analytical unit |
| `transcript_id` | Transcript isoform ID. Often absent from `gene` lines and present on `transcript`, `exon`, and `CDS` lines |
| `gene_name` | Human-readable gene symbol, such as `TP53` or `MDM2` |
| `gene_biotype` / `gene_type` | Gene type such as protein_coding, lncRNA, or pseudogene. Ensembl mainly uses `gene_biotype`; GENCODE mainly uses `gene_type` |
| `exon_number` | Order of the exon within the transcript |

Where possible, storing data by **`gene_id` rather than `gene_name`** is safer. Gene symbols can change or be duplicated, while identifiers such as Ensembl gene IDs are more stable.

:::note[Attribute names differ slightly by source]
Columns 1 through 8 of GTF are fairly consistent, but detailed keys in the ninth-column `attributes` can differ among annotation providers. For example, GENCODE uses `gene_type` and `transcript_type`, while Ensembl dumps use names such as `gene_biotype`. Check which attribute your tool option uses for grouping.
:::

## Feature types

Common features include:

| feature | Meaning |
| --- | --- |
| `gene` | Entire gene region |
| `transcript` | One transcript isoform |
| `exon` | An exon forming part of a transcript |
| `CDS` | Coding sequence translated into protein |
| `UTR` | Untranslated 5' or 3' region |
| `start_codon`, `stop_codon` | Start and stop codons |

RNA-seq read counting usually aggregates `exon` features at the gene level. That is why `featureCounts` is often used with `-t exon -g gene_id`.

```bash
featureCounts \
  -a annotation.gtf \
  -t exon \
  -g gene_id \
  -o counts.txt \
  aligned.bam
```

Meaning:

| Option | Meaning |
| --- | --- |
| `-a annotation.gtf` | GTF annotation to use |
| `-t exon` | Count only exon lines |
| `-g gene_id` | Group exons with the same gene_id to produce counts by gene |

## Differences between GTF and GFF3

GTF and GFF3 are both gene-annotation formats. They look similar, but the syntax of the ninth column differs.

| Field | GTF | GFF3 |
| --- | --- | --- |
| Ninth column | `gene_id "X"; transcript_id "Y";` | `ID=exon1;Parent=transcript1` |
| Representing hierarchy | Linked through `gene_id` and `transcript_id` attributes | Explicit parent-child relationships through `ID` and `Parent` |

GFF3 uses reserved attributes such as `ID` and `Parent` to represent the gene → transcript → exon hierarchy more explicitly. GTF usually groups features belonging to the same gene or transcript through repeated `gene_id` and `transcript_id` values on each line.

Tools expect different formats. Even tools such as `featureCounts` that support multiple annotation formats need explicit instructions for which feature to count (`-t`) and which attribute to group by (`-g`).

## Where to obtain GTF files

Human-genome analyses mainly use these annotations.

| Source | Characteristics |
| --- | --- |
| GENCODE | High-quality annotation used very widely for human and mouse RNA-seq |
| Ensembl | Supports many species and matches Ensembl gene and transcript IDs well |
| RefSeq | NCBI-based annotation, common in clinical and legacy pipelines |

The important requirement is that **the FASTA genome and GTF annotation use the same build**.

```text
Good:       GRCh38 genome FASTA + GRCh38 GTF
Dangerous:  GRCh37 genome FASTA + GRCh38 GTF
```

## Practical cautions

### 1. Chromosome names must match

If the genome FASTA uses `chr1` but the GTF uses `1`, a tool may not recognize them as the same chromosome.

```text
FASTA: >chr1
GTF:   1  HAVANA  exon ...
```

This can produce nearly zero counts or warnings while building an index. Always check whether the `chr` prefix is present.

### 2. Record the annotation version

Even within GRCh38, gene models can differ among annotation versions such as GENCODE v39, v44, and v46. Record the version with the results for reproducibility.

```text
genome: GRCh38
annotation: GENCODE v46
```

GENCODE and Ensembl continue to update, so saying only "we used GRCh38" is insufficient. Where possible, record **genome build, annotation source, and release number** together in papers, notebooks, and result tables.

### 3. Handle gene_id version suffixes

Ensembl IDs can include a version.

```text
ENSG00000141510.18
```

Other databases often store the same ID without the suffix, as `ENSG00000141510`. When joining external data, decide whether to retain or remove version suffixes such as `.18`.

### 4. Do not rely only on gene_name

`gene_name` is easy for people to read but weak as an analytical key.

- Historical names can change
- The same symbol can appear at multiple locations
- Duplicates become more likely when pseudogenes and lncRNAs are included

A safer pattern is to key internal analysis tables by `gene_id` and attach `gene_name` only at the final interpretation stage.

## Small example

This example shows one gene with one transcript and two exons.

```text
chr1  source  gene        1000  5000  .  +  .  gene_id "GENE1"; gene_name "ABC1";
chr1  source  transcript  1000  5000  .  +  .  gene_id "GENE1"; transcript_id "TX1";
chr1  source  exon        1000  1200  .  +  .  gene_id "GENE1"; transcript_id "TX1"; exon_number "1";
chr1  source  exon        3000  5000  .  +  .  gene_id "GENE1"; transcript_id "TX1"; exon_number "2";
```

When counting against this GTF, reads that overlap exon 1 or exon 2 are added to the count for `GENE1`.

## One-line cheat sheet

```text
GTF is a "gene map on a genome."
RNA-seq uses it to assign BAM reads to genes and exons.
Coordinates are 1-based inclusive; key attributes are gene_id and transcript_id.
The genome FASTA and GTF must use the same build and chromosome names.
```

See the [Data Formats Reference](/en/reference/data-formats/) and [Turning Raw Counts into Comparable Values](/en/lessons/rna-seq-quantification/) for related material.

## References

- [Ensembl: GFF/GTF File Format](https://www.ensembl.org/info/website/upload/gff.html): the nine GFF/GTF columns, 1-based inclusive coordinates, and the attribute column.
- [GENCODE: Data format](https://www.gencodegenes.org/pages/data_format.html): GENCODE GTF column definitions and attributes including `gene_id`, `transcript_id`, `gene_type`, and `exon_number`.
- [Sequence Ontology: GFF3 specification](https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md): GFF3 `ID`, `Parent`, and `tag=value` attribute syntax and hierarchy representation.
- [Subread/featureCounts User Guide](https://subread.sourceforge.net/SubreadUsersGuide.pdf): read-summarization options for `featureCounts -a annotation.gtf -t exon -g gene_id`.
- Liao Y, Smyth GK, Shi W. **featureCounts: an efficient general purpose program for assigning sequence reads to genomic features.** *Bioinformatics* (2014). DOI: [10.1093/bioinformatics/btt656](https://doi.org/10.1093/bioinformatics/btt656)