kuben-developer/tiktok-videos-4b

Dataset

314

stars

29

commits

Sep 8, 2026

updated

recommender-systems
short-video
social-media
social-network-analysis
tiktok

README

TikTok Videos: 4.5 billion posts with engagement metrics

4.5 billion TikTok video records with captions, engagement counts, sound identifiers and timing. Collected from TikTok's mobile API over roughly three weeks. Every content_id appears exactly once.

This is the largest public TikTok dataset I am aware of. It is released as-is, for research.

What is in it

27 Parquet files, zstd compressed, about 289 GB in total. One row per video.

ColumnTypeDescription
content_iduint64TikTok's video ID. Unique across the dataset
create_timedatetimeWhen the video was posted
descstringThe caption, as written by the creator
mentionslist[uint64]Account IDs tagged in the video
durationuint16Length in seconds
is_videouint81 for video, 0 for a photo post
music_iduint64The sound used. Join key across videos
music_titlestringName of the sound
viewsuint64Play count at collection time
likesuint64
commentsuint64Comment count
sharesuint64
savesuint64Bookmarks. Often the earliest signal that something is moving
countrystringTwo-letter country code
languagestringLanguage code
is_aduint8Marked as sponsored

Getting started

import duckdb

# Query it without loading it. No unpacking, no full download needed.
duckdb.sql("""
  SELECT music_id, music_title, count(*) AS videos, sum(views) AS plays
  FROM 'videos-*.parquet'
  WHERE create_time >= '2025-01-01'
  GROUP BY 1, 2 ORDER BY plays DESC LIMIT 20
""").show()
import pandas as pd
df = pd.read_parquet("videos-00.parquet", columns=["content_id", "views", "desc"])
from datasets import load_dataset
ds = load_dataset("kuben-developer/tiktok-videos-4b", streaming=True)

One file is about 10 GB and holds roughly 167 million videos, so start with a single file before pulling all 27.

How it was collected

Through the private HTTP API that TikTok's Android app uses, rather than the web endpoints or a headless browser. Requests are signed the way the app signs them, from anonymous device registrations. There is no login anywhere in the pipeline, no account, and no session cookie, so nothing here is account-gated content.

The method is written up in full at https://tiktok-api.seeksocial.io.

Things to know before you use it

The counts are a snapshot, not a time series. Every engagement number is whatever it was at the moment that row was collected, somewhere in a three week window. A video collected on day one and a video collected on day twenty have had different amounts of time to accumulate views. Do not compare raw counts across distant create_time values without normalising for age.

Rows are grouped by creator, not shuffled. The export preserves the storage order, which clusters each creator's videos together. If you are training on this, shuffle. Reading it sequentially gives you highly correlated batches.

Creator identity is not included. There is no author ID, username or profile data. You can group videos by sound, hashtag mention or caption, but not by who posted them. This is deliberate.

Media URLs are not included. TikTok's CDN links carry signed expiry parameters and stop working within days, so shipping 539 GB of them would have been 539 GB of dead links.

Coverage is a sample, not a census. This is 27 of 32 storage partitions, split on a hash of the creator ID, so it is an unbiased random subset of what was collected rather than a filtered one. What was collected is itself not all of TikTok.

Deduplicated on content_id. The source table had about 10% repeat rows from overlapping collection passes. Those are collapsed, keeping the most recently seen version of each video.

country and language are TikTok's labels, inferred by them, not verified. They are wrong often enough that you should not treat them as ground truth.

Licence and responsible use

Released for research and educational use.

Captions are written by real people and this dataset is personal data under GDPR, the UK GDPR and CCPA regardless of the fact that it was publicly posted. If you are in a jurisdiction those apply to, that obligation is yours the moment you download it. Do not use this to identify, profile, target or contact individuals.

Collection was contrary to TikTok's terms of service. This dataset is not affiliated with, endorsed by, or connected to TikTok or ByteDance.

If you are named in this data and want your rows removed, open a discussion on this repository.

Contributors

kuben-developer

29 commits

kuben-developer/tiktok-videos-4b

Dataset

314

stars

29

commits

Sep 8, 2026

updated

recommender-systems
short-video
social-media
social-network-analysis
tiktok

README

TikTok Videos: 4.5 billion posts with engagement metrics

4.5 billion TikTok video records with captions, engagement counts, sound identifiers and timing. Collected from TikTok's mobile API over roughly three weeks. Every content_id appears exactly once.

This is the largest public TikTok dataset I am aware of. It is released as-is, for research.

What is in it

27 Parquet files, zstd compressed, about 289 GB in total. One row per video.

ColumnTypeDescription
content_iduint64TikTok's video ID. Unique across the dataset
create_timedatetimeWhen the video was posted
descstringThe caption, as written by the creator
mentionslist[uint64]Account IDs tagged in the video
durationuint16Length in seconds
is_videouint81 for video, 0 for a photo post
music_iduint64The sound used. Join key across videos
music_titlestringName of the sound
viewsuint64Play count at collection time
likesuint64
commentsuint64Comment count
sharesuint64
savesuint64Bookmarks. Often the earliest signal that something is moving
countrystringTwo-letter country code
languagestringLanguage code
is_aduint8Marked as sponsored

Getting started

import duckdb

# Query it without loading it. No unpacking, no full download needed.
duckdb.sql("""
  SELECT music_id, music_title, count(*) AS videos, sum(views) AS plays
  FROM 'videos-*.parquet'
  WHERE create_time >= '2025-01-01'
  GROUP BY 1, 2 ORDER BY plays DESC LIMIT 20
""").show()
import pandas as pd
df = pd.read_parquet("videos-00.parquet", columns=["content_id", "views", "desc"])
from datasets import load_dataset
ds = load_dataset("kuben-developer/tiktok-videos-4b", streaming=True)

One file is about 10 GB and holds roughly 167 million videos, so start with a single file before pulling all 27.

How it was collected

Through the private HTTP API that TikTok's Android app uses, rather than the web endpoints or a headless browser. Requests are signed the way the app signs them, from anonymous device registrations. There is no login anywhere in the pipeline, no account, and no session cookie, so nothing here is account-gated content.

The method is written up in full at https://tiktok-api.seeksocial.io.

Things to know before you use it

The counts are a snapshot, not a time series. Every engagement number is whatever it was at the moment that row was collected, somewhere in a three week window. A video collected on day one and a video collected on day twenty have had different amounts of time to accumulate views. Do not compare raw counts across distant create_time values without normalising for age.

Rows are grouped by creator, not shuffled. The export preserves the storage order, which clusters each creator's videos together. If you are training on this, shuffle. Reading it sequentially gives you highly correlated batches.

Creator identity is not included. There is no author ID, username or profile data. You can group videos by sound, hashtag mention or caption, but not by who posted them. This is deliberate.

Media URLs are not included. TikTok's CDN links carry signed expiry parameters and stop working within days, so shipping 539 GB of them would have been 539 GB of dead links.

Coverage is a sample, not a census. This is 27 of 32 storage partitions, split on a hash of the creator ID, so it is an unbiased random subset of what was collected rather than a filtered one. What was collected is itself not all of TikTok.

Deduplicated on content_id. The source table had about 10% repeat rows from overlapping collection passes. Those are collapsed, keeping the most recently seen version of each video.

country and language are TikTok's labels, inferred by them, not verified. They are wrong often enough that you should not treat them as ground truth.

Licence and responsible use

Released for research and educational use.

Captions are written by real people and this dataset is personal data under GDPR, the UK GDPR and CCPA regardless of the fact that it was publicly posted. If you are in a jurisdiction those apply to, that obligation is yours the moment you download it. Do not use this to identify, profile, target or contact individuals.

Collection was contrary to TikTok's terms of service. This dataset is not affiliated with, endorsed by, or connected to TikTok or ByteDance.

If you are named in this data and want your rows removed, open a discussion on this repository.

Contributors

kuben-developer

29 commits