Reddit Clone Database Schema database schema
The Reddit Clone Database Schema database schema is a DB Planner template with 108 tables, 890 columns and 201 relationships, free to use. Core tables include ad_campaigns, ad_metrics_daily, ad_targeting_rules, admin_actions. It can be opened as an interactive diagram or exported as PostgreSQL, MySQL, or MSSQL DDL.
- Tables
- 108
- Columns
- 890
- Relationships
- 201
- Category
- Social
- Exports
- DBML, SQL, C#
- Price
- Free
What this schema models
A full Reddit clone database schema — not a core subset, the whole platform. 108 tables, 61 enums and 201 relationships covering accounts, sessions, MFA, OAuth apps, trophies and avatars; communities with rules, flair, emojis, widgets, wiki and traffic; posts, galleries, drafts, scheduling, collections and polls; nested comment trees; voting, karma and five separate ranking functions; coins, awards, premium and orders; AutoMod, mod notes, crowd control, appeals and admin actions; notifications, private messages, modmail and live chat; live threads, search, the complete advertising stack, experiments, feature flags, audit logs and rate limits. THE FOUR DECISIONS 1. The COMMUNITY is the unit, not a follow graph. There is no fan-out feed table anywhere in this schema on purpose. Home is a ranked union over the rows in subreddit_subscriptions, assembled at read time. That single absence is the biggest structural difference between Reddit and a Twitter-shaped model, and it is the reason multireddits are trivial here: a named bag of subreddits produces its own listing for free precisely because the feed is computed rather than materialised. user_follows exists, but it feeds the profile surface and never the home listing. Wiring the home feed to it is how a Reddit clone accidentally turns into Twitter. 2. RANK IS STORED, not computed at read time. posts carries hot_score, best_score, top_score, rising_score and controversial_score as five separate indexed columns, each written when a vote lands. Every Reddit sort is a DIFFERENT function of the same votes, so each one gets its own column and its own index. (subreddit_id, is_stickied, hot_score) IS the front page query — an index scan, never an ORDER BY over a time-decay formula. Only the genuinely expensive combinations, top of the year and all-time and r/all, fall back to the precomputed slices in post_rankings. 3. A COMMENT TREE IS A PATH, not a recursion. comments carries parent_id AND a materialised tree_path with depth, so a thread with ten thousand replies loads as one prefix range query on (post_id, tree_path) ordered by score — not a recursive CTE per expand. best_score is the Wilson lower bound, which is why a comment with 9 of 10 upvotes correctly outranks one with 1 of 1. 4. A VOTE IS A ROW; score is a cache. post_votes and comment_votes use composite primary keys with value constrained to +1 or -1, so a vote is idempotent, changing your mind is an UPDATE and un-voting is a DELETE. Every score, karma and coin figure in the model is a rebuildable cache over an append-only ledger: karma_events for karma, coin_transactions for coins, the vote tables for scores. DETAILS WORTH STEALING - removed_at is NOT deleted_at. A moderator removal and an author deletion are different columns with different visibility rules. That is literally the [removed] versus [deleted] distinction, and collapsing it is the single most common mistake in a Reddit clone. - A profile IS a subreddit. user_profiles.profile_subreddit_id points at a subreddits row with is_profile_subreddit set, so u/name reuses the entire posting, flair and moderation stack instead of needing a parallel one. - Displayed score is not stored score. posts keeps true upvotes and downvotes plus a display_seed, because vote fuzzing is an anti-spam feature and belongs in the model rather than being invented in the view layer. - A crosspost is a self-reference on posts, never a copy of the row. - AutoMod rules are DATA, not code. automod_rules holds the field, operator, pattern and action, so a community changes its own filtering without a deploy, and match_count tells moderators which rule is doing the work and which has never fired. - Two-tier moderation is one nullable column. reports.rule_id set means the report cites a subreddit rule and lands in that community queue; null with a site reason escalates to admins. - A ban is a row with an expiry, never a boolean, and subreddit_bans and site_suspensions are deliberately separate tables because they are issued by different people and appealed to different people. is_shadowban cannot be a status, because the user must not be told. - mod_notes is the institutional memory a mod team keeps on a user, with a label that renders as a badge. It stops a team re-litigating the same person every six months. - Crowd control collapses rather than removes, which is why comments.is_collapsed is stored state. - Money is integers in minor units beside an explicit currency. Coins are their own signed ledger with balance_after stored, so a statement renders without re-summing history and a mismatch is an alarm. - A promoted post is a real posts row with is_promoted set, so it is voted on, commented on and reported through exactly the same machinery as organic content. - Every counting table is pre-aggregated per day: post_views, post_insights_daily, subreddit_traffic_daily, ad_metrics_daily. Raw hit logs belong in an event pipeline, never in the database the site reads on every page load. - Multireddits, contest mode, comment_score_hide_minutes, approved users, per-page wiki editors, vote manipulation signals and experiment assignments are all modelled — the features most clones forget. WHAT YOU GET Clean DBML that imports straight into DB Planner, plus a laid-out board with cards colour-coded across eight zones — identity, communities, content, voting, economy, moderation, messaging and platform — sticky notes explaining every decision, and a Note on almost every table saying why it exists. It also ships six Mermaid FLOWCHARTS, cross-linked to the exact tables each step writes to: vote-to-rank, comment-tree, moderation-pipeline, feed-assembly, post-submission, and coins-and-awards. Those links and the labelled groups are things neither DBML nor Mermaid can express on their own, which is the point — you can see the write path, not just the shape. Postgres-flavoured types (uuid, timestamptz, smallint, integer minor units) that port cleanly to MySQL or SQL Server. Useful for developers actually building a Reddit clone or a community platform, students who need a realistic Reddit ER diagram for a DBMS project, and teams designing ranking, comment-tree or karma infrastructure for the first time who want to argue with a complete reference model before writing their first migration.
Tables (108)
| Table | Columns |
|---|---|
| ad_campaigns | 12 |
| ad_metrics_daily | 6 |
| ad_targeting_rules | 5 |
| admin_actions | 7 |
| ads | 9 |
| advertisers | 7 |
| api_rate_limits | 6 |
| audit_logs | 10 |
| automod_matches | 7 |
| automod_rules | 15 |
| avatar_assets | 8 |
| award_gifts | 10 |
| awards | 11 |
| ban_appeals | 10 |
| banned_domains | 6 |
| chat_channel_members | 6 |
| chat_channels | 10 |
| chat_messages | 9 |
| chat_reactions | 4 |
| coin_balances | 6 |
| coin_transactions | 8 |
| collection_posts | 3 |
| collections | 8 |
| comment_votes | 5 |
| comments | 24 |
| content_revisions | 8 |
| crowd_control_settings | 9 |
| drafts | 12 |
| email_change_requests | 6 |
| experiment_assignments | 4 |
| experiments | 7 |
| feature_flags | 7 |
| flairs | 11 |
| 3 | |
| karma_events | 8 |
| link_previews | 10 |
| live_thread_contributors | 5 |
| live_thread_updates | 6 |
| live_threads | 9 |
| media_assets | 14 |
| mentions | 6 |
| messages | 9 |
| mfa_devices | 8 |
| mod_actions | 12 |
| mod_notes | 9 |
| modmail_conversations | 10 |
| modmail_messages | 7 |
| multireddit_subreddits | 3 |
| multireddits | 8 |
| notification_settings | 5 |
| notifications | 10 |
| oauth_access_tokens | 9 |
| oauth_applications | 10 |
| order_items | 6 |
| orders | 11 |
| password_resets | 7 |
| payment_methods | 10 |
| poll_options | 5 |
| poll_votes | 3 |
| polls | 5 |
| post_insights_daily | 7 |
| post_media | 6 |
| post_rankings | 6 |
| post_views | 4 |
| post_votes | 5 |
| posts | 41 |
| premium_subscriptions | 10 |
| push_subscriptions | 4 |
| recovery_codes | 4 |
| related_subreddits | 5 |
| removal_reasons | 5 |
| report_reasons | 6 |
| reports | 14 |
| saved_items | 5 |
| saved_searches | 8 |
| scheduled_posts | 10 |
| search_queries | 8 |
| site_suspensions | 10 |
| subreddit_approved_users | 4 |
| subreddit_bans | 12 |
| subreddit_emojis | 7 |
| subreddit_karma | 5 |
| subreddit_moderators | 14 |
| subreddit_mutes | 7 |
| subreddit_rules | 8 |
| subreddit_styles | 7 |
| subreddit_subscriptions | 4 |
| subreddit_topics | 3 |
| subreddit_traffic_daily | 8 |
| subreddit_widgets | 7 |
| subreddits | 36 |
| topics | 5 |
| trending_subreddits | 5 |
| trophies | 6 |
| user_avatar_items | 4 |
| user_blocks | 3 |
| user_devices | 8 |
| user_flairs | 6 |
| user_follows | 3 |
| user_preferences | 13 |
| user_profiles | 12 |
| user_sessions | 9 |
| user_trophies | 5 |
| username_history | 6 |
| users | 20 |
| vote_anomalies | 8 |
| wiki_page_editors | 4 |
| wiki_pages | 9 |
Relationships (201)
ad_campaigns.advertiser_id references advertisers.idmany to onead_metrics_daily.ad_id references ads.idmany to onead_targeting_rules.campaign_id references ad_campaigns.idmany to oneadmin_actions.admin_id references users.idmany to oneads.campaign_id references ad_campaigns.idmany to oneads.creative_asset_id references media_assets.idmany to oneads.post_id references posts.idmany to oneautomod_matches.rule_id references automod_rules.idmany to oneautomod_rules.created_by references users.idmany to oneautomod_rules.subreddit_id references subreddits.idmany to oneaward_gifts.award_id references awards.idmany to oneaward_gifts.giver_id references users.idmany to oneaward_gifts.receiver_id references users.idmany to oneawards.subreddit_id references subreddits.idmany to oneban_appeals.reviewer_id references users.idmany to oneban_appeals.subreddit_ban_id references subreddit_bans.idmany to oneban_appeals.suspension_id references site_suspensions.idmany to oneban_appeals.user_id references users.idmany to onebanned_domains.added_by references users.idmany to onebanned_domains.subreddit_id references subreddits.idmany to onechat_channel_members.channel_id references chat_channels.idmany to onechat_channel_members.last_read_message_id references chat_messages.idmany to onechat_channel_members.user_id references users.idmany to onechat_channels.created_by references users.idmany to onechat_channels.subreddit_id references subreddits.idmany to onechat_messages.author_id references users.idmany to onechat_messages.channel_id references chat_channels.idmany to onechat_messages.media_asset_id references media_assets.idmany to onechat_messages.reply_to_id references chat_messages.idmany to onechat_reactions.message_id references chat_messages.idmany to onechat_reactions.user_id references users.idmany to onecoin_transactions.user_id references users.idmany to onecollection_posts.collection_id references collections.idmany to onecollection_posts.post_id references posts.idmany to onecollections.author_id references users.idmany to onecollections.subreddit_id references subreddits.idmany to onecomment_votes.comment_id references comments.idmany to onecomment_votes.user_id references users.idmany to onecomments.author_id references users.idmany to onecomments.parent_id references comments.idmany to onecomments.post_id references posts.idmany to onecomments.removal_reason_id references removal_reasons.idmany to onecomments.removed_by references users.idmany to onecontent_revisions.editor_id references users.idmany to onecrowd_control_settings.updated_by references users.idmany to onedrafts.author_id references users.idmany to onedrafts.flair_id references flairs.idmany to onedrafts.subreddit_id references subreddits.idmany to oneemail_change_requests.user_id references users.idmany to oneexperiment_assignments.experiment_id references experiments.idmany to oneexperiment_assignments.user_id references users.idmany to onefeature_flags.updated_by references users.idmany to oneflairs.subreddit_id references subreddits.idmany to onehidden_posts.post_id references posts.idmany to onehidden_posts.user_id references users.idmany to onekarma_events.subreddit_id references subreddits.idmany to onekarma_events.user_id references users.idmany to onelive_thread_contributors.live_thread_id references live_threads.idmany to onelive_thread_contributors.user_id references users.idmany to onelive_thread_updates.author_id references users.idmany to onelive_thread_updates.live_thread_id references live_threads.idmany to onelive_threads.created_by references users.idmany to onemedia_assets.uploader_id references users.idmany to onementions.mentioned_subreddit_id references subreddits.idmany to onementions.mentioned_user_id references users.idmany to onemessages.parent_id references messages.idmany to onemessages.recipient_id references users.idmany to onemessages.sender_id references users.idmany to onemfa_devices.user_id references users.idmany to onemod_actions.automod_rule_id references automod_rules.idmany to onemod_actions.moderator_id references users.idmany to onemod_actions.report_id references reports.idmany to onemod_actions.subreddit_id references subreddits.idmany to onemod_actions.target_user_id references users.idmany to onemod_notes.moderator_id references users.idmany to onemod_notes.subreddit_id references subreddits.idmany to onemod_notes.user_id references users.idmany to onemodmail_conversations.assigned_to references users.idmany to onemodmail_conversations.participant_id references users.idmany to onemodmail_conversations.subreddit_id references subreddits.idmany to onemodmail_messages.author_id references users.idmany to onemodmail_messages.conversation_id references modmail_conversations.idmany to onemultireddit_subreddits.multireddit_id references multireddits.idmany to onemultireddit_subreddits.subreddit_id references subreddits.idmany to onemultireddits.owner_id references users.idmany to onenotification_settings.user_id references users.idmany to onenotifications.actor_id references users.idmany to onenotifications.subreddit_id references subreddits.idmany to onenotifications.user_id references users.idmany to oneoauth_access_tokens.application_id references oauth_applications.idmany to oneoauth_access_tokens.user_id references users.idmany to oneoauth_applications.owner_id references users.idmany to oneorder_items.order_id references orders.idmany to oneorders.payment_method_id references payment_methods.idmany to oneorders.user_id references users.idmany to onepassword_resets.user_id references users.idmany to onepayment_methods.user_id references users.idmany to onepoll_options.post_id references polls.post_idmany to onepoll_votes.option_id references poll_options.idmany to onepoll_votes.user_id references users.idmany to onepost_insights_daily.post_id references posts.idmany to onepost_media.media_asset_id references media_assets.idmany to onepost_media.post_id references posts.idmany to onepost_rankings.post_id references posts.idmany to onepost_rankings.subreddit_id references subreddits.idmany to onepost_views.post_id references posts.idmany to onepost_votes.post_id references posts.idmany to onepost_votes.user_id references users.idmany to oneposts.author_id references users.idmany to oneposts.collection_id references collections.idmany to oneposts.crosspost_parent_id references posts.idmany to oneposts.flair_id references flairs.idmany to oneposts.id references polls.post_idone to oneposts.removal_reason_id references removal_reasons.idmany to oneposts.removed_by references users.idmany to oneposts.subreddit_id references subreddits.idmany to onepremium_subscriptions.gifted_by references users.idmany to onepremium_subscriptions.user_id references users.idmany to onepush_subscriptions.device_id references user_devices.idmany to onerecovery_codes.user_id references users.idmany to onerelated_subreddits.related_subreddit_id references subreddits.idmany to onerelated_subreddits.subreddit_id references subreddits.idmany to oneremoval_reasons.subreddit_id references subreddits.idmany to onereport_reasons.subreddit_id references subreddits.idmany to onereports.report_reason_id references report_reasons.idmany to onereports.reporter_id references users.idmany to onereports.resolved_by references users.idmany to onereports.rule_id references subreddit_rules.idmany to onereports.subreddit_id references subreddits.idmany to onesaved_items.user_id references users.idmany to onesaved_searches.subreddit_id references subreddits.idmany to onesaved_searches.user_id references users.idmany to onescheduled_posts.author_id references users.idmany to onescheduled_posts.draft_id references drafts.idmany to onescheduled_posts.published_post_id references posts.idmany to onescheduled_posts.subreddit_id references subreddits.idmany to onesearch_queries.subreddit_id references subreddits.idmany to onesearch_queries.user_id references users.idmany to onesite_suspensions.issued_by references users.idmany to onesite_suspensions.lifted_by references users.idmany to onesite_suspensions.user_id references users.idmany to onesubreddit_approved_users.added_by references users.idmany to onesubreddit_approved_users.subreddit_id references subreddits.idmany to onesubreddit_approved_users.user_id references users.idmany to onesubreddit_bans.banned_by references users.idmany to onesubreddit_bans.lifted_by references users.idmany to onesubreddit_bans.rule_id references subreddit_rules.idmany to onesubreddit_bans.subreddit_id references subreddits.idmany to onesubreddit_bans.user_id references users.idmany to onesubreddit_emojis.created_by references users.idmany to onesubreddit_emojis.subreddit_id references subreddits.idmany to onesubreddit_karma.subreddit_id references subreddits.idmany to onesubreddit_karma.user_id references users.idmany to onesubreddit_moderators.invited_by references users.idmany to onesubreddit_moderators.subreddit_id references subreddits.idmany to onesubreddit_moderators.user_id references users.idmany to onesubreddit_mutes.muted_by references users.idmany to onesubreddit_mutes.subreddit_id references subreddits.idmany to onesubreddit_mutes.user_id references users.idmany to onesubreddit_rules.subreddit_id references subreddits.idmany to onesubreddit_styles.updated_by references users.idmany to onesubreddit_subscriptions.subreddit_id references subreddits.idmany to onesubreddit_subscriptions.user_id references users.idmany to onesubreddit_topics.subreddit_id references subreddits.idmany to onesubreddit_topics.topic_id references topics.idmany to onesubreddit_traffic_daily.subreddit_id references subreddits.idmany to onesubreddit_widgets.subreddit_id references subreddits.idmany to onesubreddits.created_by references users.idmany to onesubreddits.id references subreddit_styles.subreddit_idone to onesubreddits.id references crowd_control_settings.subreddit_idone to onetopics.parent_id references topics.idmany to onetrending_subreddits.subreddit_id references subreddits.idmany to oneuser_avatar_items.asset_id references avatar_assets.idmany to oneuser_avatar_items.user_id references users.idmany to oneuser_blocks.blocked_id references users.idmany to oneuser_blocks.blocker_id references users.idmany to oneuser_devices.user_id references users.idmany to oneuser_flairs.assigned_by references users.idmany to oneuser_flairs.flair_id references flairs.idmany to oneuser_flairs.subreddit_id references subreddits.idmany to oneuser_flairs.user_id references users.idmany to oneuser_follows.followee_id references users.idmany to oneuser_follows.follower_id references users.idmany to oneuser_profiles.profile_subreddit_id references subreddits.idmany to oneuser_sessions.device_id references user_devices.idmany to oneuser_sessions.user_id references users.idmany to oneuser_trophies.granted_by references users.idmany to oneuser_trophies.subreddit_id references subreddits.idmany to oneuser_trophies.trophy_id references trophies.idmany to oneuser_trophies.user_id references users.idmany to oneusername_history.changed_by references users.idmany to oneusername_history.user_id references users.idmany to oneusers.id references user_profiles.user_idone to oneusers.id references user_preferences.user_idone to oneusers.id references coin_balances.user_idone to onevote_anomalies.user_id references users.idmany to onewiki_page_editors.added_by references users.idmany to onewiki_page_editors.user_id references users.idmany to onewiki_page_editors.wiki_page_id references wiki_pages.idmany to onewiki_pages.last_edited_by references users.idmany to onewiki_pages.subreddit_id references subreddits.idmany to one
How to use this template
- Open the diagram to see the tables and how they relate.
- Copy it into your workspace. You get your own editable copy.
- Export it as PostgreSQL, MySQL, or MSSQL DDL, or as C# models.
Frequently asked questions
- What is in the Reddit Clone Database Schema schema?
- 108 tables and 201 relationships, across 890 columns. The table names and the full relationship list are shown on this page.
- Can I export it to PostgreSQL or MySQL?
- Yes. Every DB Planner template exports as DBML, PostgreSQL, MySQL, or MSSQL DDL, and as C# models.
- Is this template free?
- Yes. You can open it in the browser without an account, and copy it into your own workspace with a free DB Planner account.
- Can I change it after copying it?
- Yes. A copy is yours: you can rename tables, add columns, and export it. Changes the author makes later do not affect your copy.