Twitch DownloaderVODs · Clips · Live

Twitch Chat Log Analysis: What to Do With the File

Updated: 2026-07-29 · Written by the vodfetch founder

A Twitch chat log is a plain text file, one message per line, and ordinary shell tools turn it into real answers: how many messages, who spoke most, which minute chat exploded, and where a half-remembered moment happened. This guide covers the analysis rather than the download — the commands, how to read their output, and the limits that stop the numbers meaning more than they do.

Where the log comes from, and why it is analysable

Twitch does not hand you a chat log. Its public Helix API covers live chat — the chatter list, chat settings, sending messages and announcements, the pinned message, chat colours, emotes and badges — and its video endpoints return metadata only. Nothing in the public API returns the messages of a past broadcast. Every Twitch chat log in circulation is therefore produced by a third-party tool reading Twitch's video comments data, and this one is no exception.

Two properties of the export do all the work below. Every message occupies one line, and line order is broadcast order, because the export asks for comments from offset zero and pages strictly forward on Twitch's cursor. That means grep -n hands you a position in the stream for free, and a per-minute histogram needs no sorting step at all. The export procedure, the exact line format and the paging limits belong to /blog/download-twitch-vod-with-chat and /twitch-chat-log; this guide starts once the file is on disk.

One historical caveat matters if you are measuring reaction timing. Twitch ran a separate Chat on Videos feature that let viewers post new time-stamped comments onto a VOD after the broadcast had ended, expanded to all videos in September 2017 and discontinued on 12 November 2019, with the existing comments removed. Anything you export today is original live chat only, typed while the stream was running, so a message-rate curve cannot have been shifted by someone commenting a week later.

Counting the file correctly

Start with the total, and do not use wc -l. The export joins its lines with newline characters rather than terminating each one, so the file ends without a trailing newline and wc -l reports one message fewer than the file holds. On a two-hour file built to the export's exact line format and containing 7,980 messages, wc -l returned 7979 while grep -c "" returned 7980. Use grep -c "" 2371234567_chat.txt. The off-by-one produces no warning and follows every figure you derive from it.

For a per-chatter ranking, strip the timestamp first and then take the name: awk -F'] ' '{print $2}' 2371234567_chat.txt | cut -d: -f1 | sort | uniq -c | sort -rn | head. The two-stage split is what makes it robust. Message bodies routinely contain colons, so cutting on the colon alone would break, and the awk field separator removes the bracketed offset before that can matter. A message containing a bracket, such as array[0] is fine, does not break it either, because the name is read first. For unique chatters, replace the tail with sort -u | wc -l.

Exclude the question marks before you publish any of those numbers. Where Twitch returns no commenter for a message — typically a deleted or renamed account — the tool writes a literal ? in the name position. Those lines are not one person: they are every unresolvable account in the broadcast collapsed into a single bucket, and on a busy stream it is easily large enough to sit inside a top-ten table as though it were a real chatter. Filter it with grep -v '] ?: ' before ranking, and read the number of lines it removes as a rough floor on account churn rather than a measurement of it.

Reading the ranking: person, moderator or bot

A per-user table is only useful once you can tell what kind of account each row represents, and the file carries no badges to tell you. Twitch's chat documentation supplies a workable substitute in its published send-side rate limits. An account that is not the broadcaster, a moderator or a VIP may send 20 messages per 30 seconds, and no more than one message per second in a single channel. Broadcasters, moderators and VIPs are allowed 100 per 30 seconds. Verified bots are allowed 7,500 per 30 seconds.

The reading follows directly, and it is an inference rather than a lookup. An ordinary viewer account tops out around 40 messages a minute, so a row sitting far above that during a burst is a moderator, a VIP or a bot rather than an unusually fast typist. Sustained high totals spread evenly across the whole broadcast are the bot signature: a chat bot posting timers and command responses accumulates a large count without ever spiking, while a human's messages cluster tightly around the moments they were reacting to.

This matters most when the ranking itself is what you are quoting. The claim that a channel's top chatter sent 900 messages reads very differently once you notice the account is the channel's own moderation bot. Check the top rows against the channel before treating them as community members, and state in any write-up whether bots were excluded, because the resulting figure changes substantially depending on the answer.

Finding the loudest minute, and the command that gets it wrong

The timestamp has two shapes, and that breaks the obvious approach. The hour is omitted while the offset is still below one hour, so the first hour of a stream reads [53:12] and the second reads [1:00:30]. A histogram built with cut -d: -f1 therefore treats 53, meaning fifty-three minutes, and 1:00, meaning one hour, as unrelated strings. Run against the two-hour test file it collapsed every line from the second hour into a single bucket labelled [1 holding 4,380 messages, and ranked that fiction above every real minute in the file, with no error to warn you.

Normalise both shapes to seconds before bucketing. This produces a per-minute count ranked by volume: awk -F'[][]' '{n=split($2,a,":"); s=(n==3?a[1]*3600+a[2]*60+a[3]:a[1]*60+a[2]); c[int(s/60)]++} END{for(k in c) print k, c[k]}' 2371234567_chat.txt | sort -k2 -rn | head -5. The field separator splits on the brackets so the second field is the raw timestamp, split counts its parts, and the three-part case is read as hours, minutes and seconds. Each output row is a minute index and a count, so 60 840 means the minute beginning at 1:00:00 carried 840 messages.

On the test file that correctly surfaced minute 60 with 840 messages against a baseline near 60 per minute. Two notes on reading it. To see the curve in stream order rather than by volume, replace sort -k2 -rn with sort -n — awk emits its buckets in no defined order, so removing the sort altogether gives you neither ordering. And minute buckets are as fine as the data allows, because offsets are rounded to whole seconds before they are written.

Spotting a raid or an arriving crowd

The export carries no badges and no dependable record of system notices, so there is no field that says raid and nothing to look up. What the file supports is a behavioural inference, and it is worth being explicit that this is a heuristic rather than a detector. The signal is a rate spike that coincides with a spike in names appearing for the first time. A reaction to something on screen comes from people already in the room; an arrival brings unfamiliar names with it.

Build the per-minute histogram above, take the busiest minute, list the names speaking in it, and check how many of them appear anywhere earlier in the file. Because line order is time order, earlier simply means a lower line number, so grep -n -m1 on a name gives you its first appearance without any date parsing at all. If most of the speakers in a spike minute are new to the file, read it as an incoming crowd; if most were already talking, read it as a reaction to the stream itself.

Two caveats keep this honest. Raiders who arrive and lurk without typing are invisible to the file entirely, so the technique undercounts every raid by an unknown amount. And a large first-time-name spike can equally be the moment the stream got linked somewhere, or a wave of bot accounts. What the file establishes is that unfamiliar accounts began talking at a particular offset. That is a lead to check against the video, not a conclusion to publish.

Searching for a half-remembered moment

Locating a moment is the most common reason to keep a chat log, and Twitch's player offers scrubbing but no search over chat replay. With the file on disk it is one command: grep -n -m1 -i "no way" 2371234567_chat.txt returns the line number, the offset and the message in a single result. Drop -m1 to see every occurrence and aim for the densest cluster rather than the first hit, because the first mention of a phrase is rarely the moment itself.

Search for what viewers would have typed, not for what was said on stream. Chat paraphrases constantly: it names the game, the guest, the score and the joke, and it reacts within seconds. If you half-remember a boss fight, grep the boss's name; if you remember a reaction rather than an event, grep the emote code, since emotes are stored as the text that was typed. Then hand the offset back to the tool using the URL parameters documented in /blog/download-twitch-vod-with-chat rather than scrubbing the player, which also explains how the trim boundary relates to the offsets in this file.

What the file supports as a record

As a record the file is well defined: a timestamped, verbatim copy of what was said in public chat during one identified broadcast, named after the video ID so its provenance travels with the filename. To pull a single account's full contribution, run grep "] modbot99: " 2371234567_chat.txt, keeping the bracket, colon and trailing space so that a name which is a prefix of another name cannot match. That returns every line the account contributed, in order, each with its offset.

What it is not is a moderation record. It contains no bans, no timeouts, no mod actions and no mod comments, and Twitch's own moderation tools — the user card in Mod View, with its timeout history and mod comments — are where those live. Messages a moderator deleted during the broadcast do not appear in chat replay, so they are not in the export either and no tool can recover them. The practical consequence is that absence from the log is not proof a message was never sent, only that it is not being served now.

Timing is the part people get wrong. What makes the file checkable is the VOD still existing, because that is what lets someone else compare the log against the source. The VOD is on a clock. Export at the time of the incident rather than when it escalates weeks later: a log exported after the broadcast has expired is still readable, but by then there is nothing left to check it against.

Chat as a rough transcript, and where it stops

Because chat narrates the stream, the log doubles as a crude transcript for search purposes. If you need to know roughly when a topic came up, whether a particular game was played, or which guest appeared, chat will usually have said so within seconds. That makes a grep over the text file a zero-cost first pass before committing to run speech-to-text across hours of audio, which is far slower and considerably more annoying to get wrong on the first attempt.

The limits are obvious once stated. Chat records what viewers typed, not what was said, so nothing in the file is a quote and there is no attribution to the streamer at all. Quiet chat does not mean nothing happened; frequently it means the stream was holding attention. And anything the audience did not find remarkable leaves no trace, which is often exactly the material a real transcript would have preserved. For the spoken audio, /blog/how-to-get-twitch-transcript covers that route; the efficient combination is to use the chat log to locate the region of interest and transcribe only that.

The limits worth stating plainly

The file measures chat, not audience. There are no viewer numbers in it, no record of anyone who watched without typing, and no way to size the silent majority. A minute carrying 800 messages tells you that chat reacted, not that more people were watching than in the minute before. The two often move together, but the file contains no evidence of that and cannot be used to demonstrate it. Report message rate as chat intensity and say so, because dressing it up as an audience metric is the most common way this data gets misused.

The fields the export never requests rule out three whole classes of analysis: subscriber or moderator ratios, joining a chatter to their account across several broadcasts, and correlating chat against anything measured in real-world time, since offsets are relative to the start of the broadcast rather than absolute. /blog/download-twitch-vod-with-chat lists exactly what is and is not in a line.

Offsets are rounded to whole seconds. Two messages sent within the same second keep their true relative order in the file but carry an identical timestamp, so ordering finer than one second exists only as line order. If you re-sort the file by timestamp for any reason, use a stable sort or that sub-second ordering is destroyed silently.

The log's lifespan is the VOD's lifespan. The export is keyed on the video ID, so once Twitch deletes the past broadcast that ID stops resolving and the chat goes with it, and no public endpoint can recover the messages afterwards. Twitch stores past broadcasts for 60 days for Partners and for channels with Prime or Turbo, 14 days for Affiliates, and 7 days for everyone else — three separate tiers, which several pages ranking for these queries fuse or invert. /blog/download-twitch-vod-before-deleted covers the expiry mechanics; the consequence for analysis is that after the window your file is not a convenience copy, it is the only copy.

Converting a broadcast into a Highlight moves it off that 7, 14 or 60-day clock, but onto a bounded one: since 19 April 2025, announced on 19 February 2025, Highlights and Uploads share a single 100-hour storage budget per channel, published and unpublished counted together. Clips are the only user-created type with neither an expiry nor a cap, and clips carry no chat replay at all. The Chat (.txt) button is offered for any twitch.tv/videos link, and "No chat available for this VOD" is what you get when Twitch returns nothing for it.

How to download a Twitch video

  1. 1

    Get the true message count

    Run grep -c "" 2371234567_chat.txt rather than wc -l. The file has no trailing newline, so wc -l reports one message fewer than it actually holds, and that error propagates into every rate you calculate from it.

  2. 2

    Rank the chatters, minus the question marks

    Run grep -v '] ?: ' 2371234567_chat.txt | awk -F'] ' '{print $2}' | cut -d: -f1 | sort | uniq -c | sort -rn | head. The grep -v drops messages from unresolvable accounts, which all collapse to a literal ? and would otherwise rank as one fictional chatter.

  3. 3

    Identify bots and moderators in the top rows

    A non-privileged account may send 20 messages per 30 seconds under Twitch's documented limits, so roughly 40 a minute is its ceiling. Rows far above that, or with large totals spread evenly across the broadcast rather than clustered in bursts, are bots, moderators or VIPs. Decide whether to exclude them and say which you chose.

  4. 4

    Build the per-minute histogram

    Use the awk one-liner that normalises both timestamp shapes to seconds before bucketing, then sort -k2 -rn for the loudest minutes or sort -n for the curve in stream order. Do not use cut -d: -f1, which mixes minute values from the first hour with hour values from later ones and produces a nonsense ranking with no visible error.

  5. 5

    Test whether a spike is new people or the same people

    Take the busiest minute, list the names speaking in it, and grep -n -m1 each one to find its first line in the file. Line order is time order, so a low first-appearance line means the account was already present. Mostly new names points to an arriving crowd.

  6. 6

    Jump back to the moment in the video

    Run grep -n -m1 -i "<phrase>" 2371234567_chat.txt to get the offset, searching for what viewers would have typed rather than what was said, then hand that offset back to the tool with the URL parameters documented in /blog/download-twitch-vod-with-chat instead of scrubbing the player by hand.

Frequently asked questions

Can you download a Twitch chat replay as a file?

Yes, but not from Twitch. Twitch's public Helix API has no endpoint that returns a past broadcast's messages — its chat endpoints cover the chatter list, settings, sending, announcements, pinned messages, colours, emotes and badges, none of which is a log. Third-party tools read Twitch's video comments data instead. vodfetch saves it as a plain .txt file, one message per line with an offset. The export procedure is covered in /blog/download-twitch-vod-with-chat; this guide is about what to do with the file afterwards.

How do I count the messages in a Twitch chat log?

Use grep -c "" 2371234567_chat.txt rather than wc -l. The export joins lines with newline characters instead of terminating each one, so the file ends without a trailing newline and wc -l reports one fewer than the file contains. On a two-hour file built to the export's exact format and holding 7,980 messages, wc -l returned 7979 and grep -c "" returned 7980. The discrepancy is a single message, which sounds trivial until it becomes the denominator of a messages-per-minute figure.

How do I find the most active chatter in a VOD?

Run grep -v '] ?: ' file | awk -F'] ' '{print $2}' | cut -d: -f1 | sort | uniq -c | sort -rn | head. Splitting on '] ' first and then on the colon is what makes it survive messages that themselves contain colons or brackets. The grep -v matters: every account Twitch can no longer resolve is written as a literal question mark, and those aggregate into one bucket that can easily out-rank real people. Check the surviving top rows against the channel before calling them community members, because moderation bots usually sit near the top.

How do I find the busiest minute of a Twitch chat log?

Bucket by minute after normalising the timestamp, because it has two shapes: the hour is omitted below 1:00:00, so [53:12] and [1:00:30] are not comparable as strings. An awk one-liner that splits on the brackets, counts the parts and converts to seconds handles both. Do not use cut -d: -f1 — on a two-hour file it merged every second-hour line into one bucket of 4,380 and ranked that above every genuine minute, with no error message to warn you.

Can I tell how many people were watching from the chat log?

No. The file records what was typed, nothing else. It carries no viewer counts, no record of anyone who watched silently, and no sampling of lurkers, who are usually the large majority of an audience. A minute with 800 messages establishes that chat reacted, not that viewership rose. The two frequently move together, but the file offers no evidence of that and cannot be used to show it. Describe the metric as chat intensity and the analysis stays defensible.

Does the chat log show who was a subscriber, moderator or VIP?

No — badges, name colours and user IDs are not part of the export, as /blog/download-twitch-vod-with-chat sets out, so no amount of processing recovers them. The closest substitute is Twitch's documented send-side rate limits: an account that is not the broadcaster, a moderator or a VIP may send 20 messages per 30 seconds, so roughly 40 a minute is its ceiling, while broadcasters, moderators and VIPs get 100 per 30 seconds and verified bots 7,500. Anything well above 40 in a minute is privileged or automated. That is an inference, not a lookup.

Can I use a Twitch chat log as a record of what was said?

Within limits. It is a timestamped, verbatim copy of public chat during one identified broadcast, and grep "] name: " file returns one account's whole contribution in order. It is not a moderation record: it holds no bans, timeouts, mod actions or mod comments, and Twitch's Mod View user card is where those live. Messages a moderator deleted during the broadcast are not in it, so absence from the file is not proof a message was never sent. Export while the VOD still exists, because that is what lets anyone check the log against the source.

Can I detect a raid from the chat log?

Only as a heuristic. The file carries no badges and no dependable system-notice record, so there is nothing labelled raid. What it supports is an inference: a raid is a message-rate spike that coincides with a spike in names appearing for the first time. Because line order is time order, first appearance is just the lowest line number a name occurs on, so grep -n -m1 gives it directly. Raiders who arrive without typing are invisible, so the method undercounts, and a link posted elsewhere produces the same pattern.

Why is the chat exported as plain text instead of JSON or CSV?

Because every command worth running on this file works on plain text with nothing installed, while the JSON equivalent needs jq present plus a schema that differs between exporters. One message per line also means line order equals time order, so grep -n gives you a position for free and a histogram needs no sort. A truncated text file is still readable up to the last complete line; a truncated JSON array parses as nothing. JSON would win the moment you needed badges or user IDs, which this export does not carry in any format.

How long can I still export a VOD's chat log?

Until Twitch deletes the past broadcast. The export is keyed on the video ID, so when the VOD goes the chat goes with it, and no public endpoint can recover it. Twitch stores past broadcasts for 60 days for Partners and for channels with Prime or Turbo, 14 days for Affiliates, and 7 days for all other streamers — three separate tiers that competing pages routinely fuse or invert. /blog/download-twitch-vod-before-deleted covers the mechanics. Practically: export while the broadcast is recent, because afterwards your file is the only copy in existence.

Download your Twitch video now

Paste a Twitch link and save it as MP4 in seconds — free, no account.

Open the Twitch Downloader

Related guides

← Back to the Twitch Downloader