System Design: Cloudflare Serverless Social Network
Architecting a scalable serverless social network using Cloudflare Workers, R2, D1, KV, and Durable Objects.
Architecting a social network platform like Twitter/X or Threads demands high write throughput, real-time newsfeed generation, and low-latency media distribution worldwide.
Using the Cloudflare Edge Ecosystem, we can design a completely Serverless Social Network backed by Cloudflare Workers, R2 Object Storage, D1 Database, KV, and Durable Objects.
1. Core Design Challenges#
Key system design requirements for a social network include:
- Newsfeed Generation (Fanout Service): Delivering posts efficiently to thousands or millions of followers.
- Media Storage & Delivery: Storing images/videos with zero egress fees and fast CDN caching.
- Low-Latency Edge Caching: Reading timelines and user profiles near the user.
2. System Architecture#
The overall architecture leverages five Cloudflare primitives:
- Cloudflare Workers: Edge API Gateway handling authentication, post creation, and feed queries.
- Cloudflare R2: Object storage for media assets with zero egress cost.
- Cloudflare D1: Serverless SQLite database managing relational data (Users, Posts, Follows).
- Cloudflare KV: Edge key-value cache storing user timeline feeds.
- Durable Objects (DO): Stateful background engine for feed fanout processing and like/comment aggregations.
+--------------+ HTTP / Upload +---------------------+
| User Client | <----------------------> | Cloudflare Workers |
+--------------+ +---------------------+
/ | \
Presigned URL | \ Cache Feed
v v v
+-------+ +-------+ +-------+
| R2 | | D1 | | KV |
+-------+ +-------+ +-------+
|
Async Event
v
+--------------------------+
| Durable Object (Fanout) |
+--------------------------+text3. Implementation Details#
3.1. Feed Fanout with Durable Objects & KV#
When a user publishes a new post, a Durable Object worker asynchronously pushes the post ID to the followers’ KV timeline feed.
export class FeedFanoutDO implements DurableObject {
private state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const { authorId, postId, followers } = await request.json();
// Push Post ID into KV timeline feed of each follower // [!code focus]
const updates = followers.map(async (followerId: string) => {
const feedKey = `user:feed:${followerId}`;
const currentFeed: string[] = (await ENV_KV.get(feedKey, 'json')) || [];
const updatedFeed = [postId, ...currentFeed.slice(0, 99)];
await ENV_KV.put(feedKey, JSON.stringify(updatedFeed), { ttl: 86400 * 7 });
});
await Promise.all(updates);
return new Response('Feed Fanout Completed', { status: 200 });
}
}typescript3.2. Direct Media Upload to Cloudflare R2#
Clients fetch presigned URLs from Workers to upload images and videos directly to R2 without passing heavy binary payloads through Worker memory.
export async function generateUploadUrl(env: Env, filename: string): Promise<string> {
// Generate R2 Presigned Upload URL
const objectKey = `posts/${Date.now()}-${filename}`;
const signedUrl = await env.MY_R2_BUCKET.createSignedUrl(objectKey, {
expiresIn: 3600,
method: 'PUT'
});
return signedUrl;
}typescript[!NOTE] Cloudflare R2 provides zero egress fee storage, saving massive bandwidth costs for high-resolution image and video distribution.
4. Trade-offs & Limitations#
[!TIP] Advantages:
- Zero Infrastructure Management: No Kubernetes clusters or Redis instances to maintain.
- Global Edge Performance: Timelines are cached and served directly at edge locations close to users.
[!WARNING] Limitations:
- High-Follower Fanout: For accounts with millions of followers, a hybrid approach (Fanout-on-Write for active users + Fanout-on-Read from D1 for inactive users) is required.