TSV File Documentation


Summary

A Tab-Separated Values file (.tsv) is a plain-text table in which each line is a row and columns are separated by the TAB character (byte 0x09), instead of the commas a CSV uses. It is registered with IANA as the media type text/tab-separated-values and opens in any spreadsheet (Excel, Google Sheets, LibreOffice Calc) or text editor. Because tabs rarely occur inside data, a TSV avoids the quoting and decimal-comma problems that break CSVs. To turn one into a workbook, open it and Save As .xlsx.

Technical details

FeatureValue
Full nameTab-Separated Values
File extension.tsv (also .tab)
MIME typetext/tab-separated-values
Format typePlain-text tabular data (tab-delimited)
DelimiterHorizontal TAB, byte 0x09
DeveloperNo single owner; media type registered by the University of Minnesota Gopher team
IntroducedTab-delimited text since the 1980s; IANA media type registered June 1993
StandardIANA text/tab-separated-values registration
Open standardYes
Magic numberNone (plain text; optional UTF-8 BOM EF BB BF)
EncodingNot declared in-file; UTF-8 is the modern norm
Record separatorNewline (LF or CR/LF)
QuotingNone — tabs and newlines are not permitted inside a field
Header rowFirst line names the fields (per the IANA spec)
Sibling formatCSV (comma-delimited, RFC 4180)
Related extensions.csv, .txt, .tab, .xlsx, .ods
Specificationiana.org/assignments/media-types/text/tab-separated-values
Structure at a glance

A TSV is plain text with no file signature. Each line is one record, ended by a newline (LF or CR/LF); within a line, fields are separated by a single horizontal TAB character (0x09). Under the IANA specification the first line is the header, naming each column, and a field value may not contain a tab or a line terminator, so there is no quoting mechanism at all — unlike CSV, which quotes fields to embed commas. The character encoding is not stored in the file; UTF-8 (optionally with a EF BB BF BOM) is the modern default. Because the delimiter is invisible, a TSV looks like ragged text in an editor that does not render tab stops.

What is a TSV file?

TSV stands for Tab-Separated Values. It is a plain-text format for tabular data: each line of the file is one row, and within a row the columns are separated by the horizontal TAB character, Unicode/ASCII code point 0x09. It is the same idea as a comma-separated CSV file, with the delimiter changed from a comma to a tab. Tab-delimited text has been in everyday use since the 1980s, and the format was given a media type when the University of Minnesota’s Internet Gopher team registered text/tab-separated-values with IANA in June 1993, in connection with the Gopher protocol. That registration is the nearest thing TSV has to a specification, and it is stricter, if far shorter, than CSV’s later and looser RFC 4180.

Because a TSV is just text, it crosses every operating system, language, database and spreadsheet without conversion. People most often meet a TSV as an export from a database or analytics tool, from scientific and bioinformatics pipelines (where tab-delimited tables are a de-facto standard), and as the “Save As tab-delimited text” option in a spreadsheet. The sections below go into how the delimiter actually works, the exact rules the IANA specification sets, and why those rules make TSV behave differently from CSV.

The tab delimiter and the byte layout

The whole format rests on one control character. A single horizontal tab, byte 0x09, marks the boundary between two fields; a newline ends the record. A tiny table of three rows looks like this at the byte level (tabs shown as \t, line ends as \n):

name\tage\tcity\n
Ada\t36\tLondon\n
Grace\t44\tNew York\n

In raw bytes the first line is:

6E 61 6D 65   09   61 67 65   09   63 69 74 79   0A
 n  a  m  e  TAB   a  g  e   TAB   c  i  t  y     LF

Nothing else is structural. There is no file header signature, no length prefix, no escape sequence. A parser splits each line on 0x09 to get the fields and splits the file on the newline to get the records. The record terminator is a newline, which in practice is LF on Unix and macOS and CR/LF on Windows; robust readers accept either. One consequence of the delimiter being an invisible control character is that a TSV looks like ragged, misaligned text in an editor that does not render tab stops, which is why the columns only “line up” in a spreadsheet or in an editor set to show whitespace.

The IANA rules: header row, no tabs or newlines in a field, no quoting

The IANA registration lays down a few firm rules that give TSV its character. The first line is special: it contains the name of each field, separated by tabs, so a conforming TSV always starts with a header row. Each field value is represented as text. And two things are explicitly forbidden inside a field: a field may not contain a tab, and a value may not contain a line terminator.

Those two prohibitions are the reason TSV has no quoting mechanism, and that is the single biggest difference from CSV. In a CSV, a value that itself contains the delimiter (a comma) is wrapped in double quotes, and a literal quote inside is doubled; the parser must understand that quoting to read the file correctly. TSV takes the opposite approach: rather than allowing the delimiter inside a field and escaping it, the specification simply bans the delimiter from appearing inside a field at all. Because a real tab or newline almost never occurs inside ordinary data, values are written bare, with no surrounding quotes and no escaping rules to get wrong. When a field genuinely needs to hold a tab or a line break, the strict answer is that TSV cannot carry it directly; tools that stretch the format usually substitute an escape such as \t or \n by convention, which is outside the registered specification.

Why TSV instead of CSV: two failure modes it avoids

TSV exists mainly to dodge two problems that plague CSV. The first is the comma collision. Real data is full of commas: addresses, product descriptions, prices written with thousands separators. A naive comma parser breaks on all of them, and correct CSV handling requires the quoting machinery above. Tabs, by contrast, hardly ever appear inside a value, so a TSV usually parses cleanly with no quoting needed at all.

The second is the European-locale problem. In many countries the comma is the decimal separator, so 3,14 is a number, not two fields. Spreadsheets in those locales switch the CSV delimiter to a semicolon, and files then get mangled when they move between regions that disagree about what the delimiter is. A tab delimiter sidesteps the whole argument, because the tab is never a decimal separator. The trade-off is small but real: since the delimiter is invisible, a stray literal tab accidentally sitting inside a value will silently shift every later column on that line, and the format offers no quoting to protect against it. That is why the specification bans tabs inside fields in the first place.

Opening a TSV and converting it correctly

Any spreadsheet opens a TSV and splits it into columns on the tabs: Microsoft Excel, Google Sheets, LibreOffice Calc and Apple Numbers all handle it, and any text editor shows the raw rows. The one thing to watch on import is encoding: because the character set is not recorded in the file, opening a UTF-8 TSV as legacy ANSI garbles non-Latin text. If characters look wrong, re-open through the import dialog (Excel’s Data › From Text/CSV, or LibreOffice’s text-import assistant), choose UTF-8 and tick Tab as the separator, or save the file with a UTF-8 BOM so the app auto-detects it.

Conversions are straightforward because the source is already text. Converting to CSV just swaps tabs for commas, though be aware that any value already containing a comma will then need CSV quoting, which is exactly the situation TSV was chosen to avoid. Converting to Excel’s .xlsx is the most-wanted step: open the TSV in a spreadsheet and Save As .xlsx to get a real workbook with formatting, formulas and multiple sheets. The same open-and-save route produces .ods, .xls or a PDF snapshot of the table, and for developers a script (Python’s pandas, or command-line csvkit) turns the rows into JSON objects keyed by the header line.

References