355. Design Twitter
mediumAsked at PinterestDesign Twitter is Pinterest's favorite social-graph design problem: build a feed where users follow others, post tweets, and read a merged most-recent-10 feed. The interviewer is checking whether you reach for the k-way-merge / min-heap pattern that production feed-serving uses.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Pinterest loops.
- Glassdoor (2026-Q1)— Pinterest backend / feed-infra onsite reports cite Design Twitter as the data-structure design round for feed-team SWEs.
- LeetCode Pinterest tag (2026-Q1)— High-frequency Pinterest-tagged problem; obvious analog to Pinterest's home-feed problem.
- Reddit r/cscareerquestions (2025-11)— Pinterest L4 candidate reports walking through this as a feed-design proxy.
Problem
Design a simplified social-graph service supporting four operations: postTweet(userId, tweetId), getNewsFeed(userId) (return the 10 most-recent tweet IDs from the user and anyone they follow, newest first), follow(followerId, followeeId), unfollow(followerId, followeeId).
Constraints
1 <= userId, followerId, followeeId <= 5000 <= tweetId <= 10^4All tweet IDs in a single test are unique.At most 3 * 10^4 calls in total to postTweet, getNewsFeed, follow, and unfollow.
Examples
Example 1
Twitter twitter; twitter.postTweet(1, 5); twitter.getNewsFeed(1); twitter.follow(1, 2); twitter.postTweet(2, 6); twitter.getNewsFeed(1); twitter.unfollow(1, 2); twitter.getNewsFeed(1);[null,[5],null,null,[6,5],null,[5]]Explanation: After following user 2 and user 2 posting 6, user 1's feed shows 6 then 5. After unfollowing, only user 1's own tweets remain.
Approaches
1. Concatenate-and-sort (brute force)
On getNewsFeed, walk every followee plus self, collect every tweet, sort by timestamp descending, slice the first 10.
- Time
- O(T log T) per feed where T = total tweets across followees
- Space
- O(T)
class TwitterBrute {
constructor() {
this.tweets = new Map();
this.follows = new Map();
this.time = 0;
}
postTweet(userId, tweetId) {
if (!this.tweets.has(userId)) this.tweets.set(userId, []);
this.tweets.get(userId).push({ id: tweetId, time: this.time++ });
}
getNewsFeed(userId) {
const followees = this.follows.get(userId) || new Set();
const all = [];
const include = new Set([userId, ...followees]);
for (const u of include) {
for (const t of this.tweets.get(u) || []) all.push(t);
}
all.sort((a, b) => b.time - a.time);
return all.slice(0, 10).map((t) => t.id);
}
follow(followerId, followeeId) {
if (!this.follows.has(followerId)) this.follows.set(followerId, new Set());
this.follows.get(followerId).add(followeeId);
}
unfollow(followerId, followeeId) {
this.follows.get(followerId) && this.follows.get(followerId).delete(followeeId);
}
}Tradeoff: Correct and simple. Falls over on real Pinterest scale (a user might follow thousands of boards) because we sort everything when we only need top-10.
2. Per-user tweet list + k-way merge with max-heap (optimal)
Keep each user's tweets in chronological order. For getNewsFeed, k-way merge across all followees using a max-heap by timestamp; pop 10.
- Time
- O(K log K + 10 log K) per feed where K = number of followees
- Space
- O(K) for the heap
class MaxHeap {
constructor() { this.a = []; }
push(item) { this.a.push(item); this._up(this.a.length - 1); }
pop() {
if (this.a.length === 0) return null;
const top = this.a[0];
const last = this.a.pop();
if (this.a.length > 0) { this.a[0] = last; this._down(0); }
return top;
}
size() { return this.a.length; }
_up(i) {
while (i > 0) {
const p = (i - 1) >> 1;
if (this.a[p].time < this.a[i].time) {
[this.a[p], this.a[i]] = [this.a[i], this.a[p]];
i = p;
} else break;
}
}
_down(i) {
const n = this.a.length;
while (true) {
const l = 2 * i + 1, r = 2 * i + 2;
let best = i;
if (l < n && this.a[l].time > this.a[best].time) best = l;
if (r < n && this.a[r].time > this.a[best].time) best = r;
if (best === i) break;
[this.a[best], this.a[i]] = [this.a[i], this.a[best]];
i = best;
}
}
}
class Twitter {
constructor() {
this.tweets = new Map();
this.follows = new Map();
this.time = 0;
}
postTweet(userId, tweetId) {
if (!this.tweets.has(userId)) this.tweets.set(userId, []);
this.tweets.get(userId).push({ id: tweetId, time: this.time++ });
}
getNewsFeed(userId) {
const include = new Set([userId, ...(this.follows.get(userId) || [])]);
const heap = new MaxHeap();
for (const u of include) {
const list = this.tweets.get(u);
if (!list || list.length === 0) continue;
const idx = list.length - 1;
heap.push({ ...list[idx], user: u, idx });
}
const out = [];
while (heap.size() && out.length < 10) {
const top = heap.pop();
out.push(top.id);
if (top.idx > 0) {
const next = this.tweets.get(top.user)[top.idx - 1];
heap.push({ ...next, user: top.user, idx: top.idx - 1 });
}
}
return out;
}
follow(followerId, followeeId) {
if (!this.follows.has(followerId)) this.follows.set(followerId, new Set());
this.follows.get(followerId).add(followeeId);
}
unfollow(followerId, followeeId) {
this.follows.get(followerId) && this.follows.get(followerId).delete(followeeId);
}
}Tradeoff: Production-shaped: each followee contributes only one pointer at a time, and we pop exactly 10. This mirrors the fan-out-on-read pattern Pinterest's home-feed service uses for users with bounded followee counts.
Pinterest-specific tips
Pinterest interviewers want you to volunteer the production analog: 'this is fan-out-on-read for a home-feed; for celebrities with 10M followers you'd switch to fan-out-on-write.' Don't go deep on that distinction unprompted, but signal that you know it exists. Use a single monotonically-increasing timestamp counter — wall-clock time creates ties.
Common mistakes
- Walking every tweet across every followee instead of using the heap — fails at scale.
- Using wall-clock Date.now() — two posts in the same millisecond collide.
- Forgetting to include the user's OWN tweets in their feed.
- Pushing all tweets into the heap up front instead of streaming pointers — defeats the whole optimization.
Follow-up questions
An interviewer at Pinterest may pivot to one of these next:
- Now handle 10M followers per celebrity: switch to fan-out-on-write for hot users.
- Add 'mute' (block specific users from showing up in feed).
- Persist tweets to a database — what does the schema look like?
- Support 'retweets' — does that change your data model?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why does Pinterest care about Design Twitter specifically?
Pinterest's home-feed is structurally identical: users follow boards / topics / other users; the home feed merges the most-recent pins across all sources. The k-way-merge pattern is the same primitive.
Is the heap version really better than sort-everything for n = 500?
Asymptotically yes; at the LeetCode constraint sizes the difference is negligible. The interview signal is whether you reach for the right pattern — not raw runtime.
Free learning resources
Curated free links for this problem.
Practice these live with InterviewChamp.AI
Drill Design Twitter and other Pinterest interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →