All projects
Haziq Nazeer
BackendSocial Platform Backend (Instagram for Dogs)2025 — Present

Frizbee

The NestJS backend for an Instagram-style social network for dogs — feed, Reels, 24h Stories, a full social graph and push — designed with keyset pagination and 37 database indexes to scale toward 1M+ users.

Backend Engineer
Frizbee preview

01 — Overview

The project

Frizbee is the backend for an Instagram-style social platform built for dogs: a photo / Reels feed, ephemeral 24-hour Stories, a full social graph (followers, mutual friends, blocks), “Wolf Pack” communities, reactions and threaded comments, and push notifications. It's a NestJS 11 + Prisma + PostgreSQL API with Redis, BullMQ, an S3 / CloudFront media layer and an FFmpeg HLS transcode pipeline.

Role

Backend Engineer

Timeline

2025 — Present

Stack

9 technologies

02 — Context

Problem & approach

The problem

A social feed has to stay fast as data grows into the millions of rows: offset pagination collapses, naïve queries trigger N+1 explosions, ephemeral content must expire reliably, media can't be pushed through the API, and blocks / privacy must be enforced on every read — all without slowing the hot path.

My approach

I designed the data model and queries for scale from day one. The feed uses keyset (cursor) pagination backed by composite (createdAt DESC, id DESC) indexes — 37 indexes and uniques across 24 models — so feed reads stay O(limit) regardless of table size. Viewer reactions and context are batch-loaded to kill N+1s; hot signals (Pick-of-the-Litter, viral cutoff) are precomputed off the request path and cached in Redis. Three independent BullMQ queues (media, notifications, push) isolate retry domains, an hourly cron expires Stories in bounded batches, and media uploads go direct to S3 via presigned URLs with a background FFmpeg worker that streams from S3 to stay memory-light. For Reels, that worker compresses every upload into a YouTube-style adaptive-bitrate HLS ladder with an auto-generated poster thumbnail, served from the CloudFront CDN — so instead of streaming a large raw MP4 on every view, players fetch small edge-cached segments at the right resolution and start instantly, cutting Reel load times by ~95%. Engineered to scale toward 1M+ users.

03 — Showcase

A closer look

Reels — delivered through the FFmpeg HLS video pipeline

Reels — delivered through the FFmpeg HLS video pipeline

Dog profiles and the social graph the API models

Dog profiles and the social graph the API models

Search and discovery across posts and Wolf Packs

Search and discovery across posts and Wolf Packs

04 — Capabilities

Key features

01

Dual feed

Photo / text Posts and video Reels, with FOR_YOU, followers and friends scopes.

02

Keyset pagination

Cursor pagination on every list, backed by composite indexes — O(limit) reads.

03

Ephemeral Stories

24-hour Stories with hourly, batched, memory-bounded TTL cleanup.

04

Social graph

Followers (“pawollers”), mutual friends and symmetric blocks.

05

“Wolf Pack” communities

Group spaces with bidirectional invite / request join negotiation.

06

HLS video pipeline

YouTube-style adaptive-bitrate HLS — a background FFmpeg worker compresses every Reel into multiple renditions with an auto-generated poster thumbnail.

07

Instant Reel loads

Adaptive HLS + CloudFront CDN + compression cut Reel start / load time by ~95%.

08

Aggregated push

“X and N others” deduped notifications delivered via Firebase FCM.

05 — Contribution

My role

As Backend Engineer, here is exactly what I owned and delivered on this project.

  • Built the entire NestJS backend — 16 modules, 24 Prisma models, 31 migrations.
  • Designed the indexed schema (37 indexes / uniques) and the keyset-paginated, privacy- and block-aware feed engine.
  • Eliminated N+1s by batch-loading viewer reactions and context per page.
  • Built the event-driven notification + FCM push pipeline across 3 BullMQ queues with independent retries.
  • Built the S3 + CloudFront media layer and the background FFmpeg pipeline that compresses each Reel into an adaptive-bitrate HLS ladder with poster thumbnails — cutting video load times by ~95%.
  • Built ephemeral Stories with cron-driven, batched TTL cleanup and Redis-cached feed signals.

06 — Engineering

Challenges I solved

Challenge

Feed pagination has to stay fast at millions of rows.

Solution

Keyset (cursor) pagination with take limit+1 over composite (createdAt DESC, id DESC) indexes — O(limit) reads instead of offset scans that degrade with depth.

Challenge

Rendering a feed page risked an N+1 storm of per-post reaction lookups.

Solution

Batch-loaded the viewer's reactions for the whole page in one query (postId IN …) and loaded block / friend context once via Promise.all.

Challenge

Ephemeral Stories must reliably disappear without exhausting memory.

Solution

An hourly cron deletes expired stories in bounded pages (100×100), removing S3 objects before DB rows, backed by an expiresAt index.

Challenge

A Firebase outage shouldn't corrupt notification state or double-send pushes.

Solution

Split push into its own BullMQ queue with per-device jobs, idempotency via a pushSentAt marker, and dead-token pruning.

Challenge

Reels loaded slowly — large raw MP4s were streamed straight from storage on every view, so playback stalled and buffered.

Solution

A background FFmpeg worker now compresses each upload into an adaptive-bitrate HLS ladder (multiple resolutions) with an auto-generated poster thumbnail, delivered over the CloudFront CDN — so players fetch small, edge-cached segments and start at the right quality instantly. Reel load / start time dropped by ~95%.

07 — Toolbox

Built with

NestJSPrismaPostgreSQLRedisBullMQAWS S3CloudFrontFFmpeg / HLSFirebase FCM

08 — Impact

Outcomes

~95%

Faster Reel load time

1M+

Designed to scale to users

37

Targeted DB indexes

O(limit)

Keyset-paginated feed

Next project

Vybstack

AI Social Platform Backend

Want something like this built?

I'm available for freelance work. Let's build yours.

Hire me