Production-Grade Video Recommendation Engine
A TikTok-style short video platform demonstrating advanced recommendation algorithms, real-time personalization, and scalable database design.
Features • Architecture • Algorithm • Quick Start • API Reference
StreamRank is a full-stack video recommendation platform that implements production-grade ranking algorithms inspired by systems at TikTok, Netflix, and Spotify. Unlike tutorial-level implementations, StreamRank features:
- Hybrid Recommendation Engine: Combines content-based filtering with collaborative filtering
- MMR Diversity Injection: Prevents filter bubbles using Maximal Marginal Relevance
- Temporal Preference Decay: Recent user actions matter more than old ones
- Real-time Evaluation Metrics: Precision@K, NDCG, CTR tracking
- Wilson Score Popularity: Fair ranking for new content with few interactions
- Infinite scroll video feed with TikTok-style navigation
- Real-time like, skip, share tracking with engagement scoring
- Personalized recommendations based on watch history
- User preference visualization in debug mode
- Cold-start handling for new users
| Feature | Description |
|---|---|
| Collaborative Filtering | "Users like you also watched..." using cosine similarity |
| Watch-Time Weighting | Engagement quality signals from actual watch duration |
| MMR Reranking | Diversity injection to avoid showing 10 similar videos |
| Temporal Decay | Exponential decay on preferences (λ=0.02, ~35 day half-life) |
| Wilson Score | Fair popularity ranking for new content |
- BCNF-normalized database schema (5 tables)
- JWT authentication with Supabase Auth
- Real-time video import from Pexels API
- Responsive design with TailwindCSS 4
┌─────────────────────────────────────────────────────────────────┐
│ Frontend (Next.js 16) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Video Feed │ │ Profile │ │ Debug Dashboard │ │
│ │ (TikTok UI) │ │ (Prefs) │ │ (Algorithm View) │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│ REST API (axios)
▼
┌─────────────────────────────────────────────────────────────────┐
│ Backend (Spring Boot 3.4) │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ RecommendationService │ │
│ │ ┌─────────────────┬─────────────────┬─────────────────┐ │ │
│ │ │ Content-Based │ Collaborative │ Diversity │ │ │
│ │ │ Filtering │ Filtering │ (MMR) │ │ │
│ │ └─────────────────┴─────────────────┴─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ InteractionSvc │ │ MetricsService │ │ PexelsService │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│ JPA/Hibernate
▼
┌─────────────────────────────────────────────────────────────────┐
│ PostgreSQL (Supabase) │
│ ┌─────────┐ ┌─────────┐ ┌────────────┐ ┌──────────────────┐ │
│ │ users │ │ videos │ │video_tags │ │ user_tag_prefs │ │
│ └─────────┘ └─────────┘ └────────────┘ └──────────────────┘ │
│ ┌──────────────┐ │
│ │ interactions │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
StreamRank uses a hybrid scoring formula that combines multiple signals:
final_score = 0.30 × content_affinity # Tag-based preferences (with temporal decay)
+ 0.25 × collaborative_score # User-user similarity
+ 0.20 × popularity # Wilson Score Interval
+ 0.15 × recency # Exponential decay on upload time
+ 0.05 × watch_time_signal # Engagement quality
+ 0.05 × exploration_bonus # Cold-start + ε-greedy exploration
After scoring, MMR reranking is applied to ensure diversity:
MMR(d) = λ × Relevance(d) − (1−λ) × max(Similarity(d, d_selected))
Where λ = 0.7 balances relevance and diversity.
| Algorithm | Purpose | Reference |
|---|---|---|
| Cosine Similarity | User-user collaborative filtering | Standard ML |
| Wilson Score | Fair popularity ranking | Evan Miller |
| Exponential Decay | Temporal preference weighting | Standard time series |
| MMR | Diversity injection | Carbonell & Goldstein 1998 |
| ε-Greedy | Exploration vs exploitation | Multi-armed bandit |
BCNF-normalized design with 5 core tables:
┌──────────────────┐ ┌──────────────────┐
│ users │ │ videos │
├──────────────────┤ ├──────────────────┤
│ id (PK) │ │ id (PK) │
│ username │ │ title │
│ email │ │ video_url │
│ created_at │ │ thumbnail_url │
│ last_active_at │ │ duration_sec │
└────────┬─────────┘ │ like_count │
│ │ view_count │
│ │ skip_count │
▼ │ upload_time │
┌──────────────────┐ │ creator_id (FK) │
│ interactions │ └────────┬─────────┘
├──────────────────┤ │
│ id (PK) │ │
│ user_id (FK) │◄───────────────┘
│ video_id (FK) │
│ event_type │ ┌──────────────────┐
│ watch_duration │ │ video_tags │
│ created_at │ ├──────────────────┤
└──────────────────┘ │ video_id (PK,FK) │
│ tag (PK) │
┌──────────────────────┐ └──────────────────┘
│ user_tag_preferences │
├──────────────────────┤
│ user_id (PK, FK) │
│ tag (PK) │
│ affinity_score │
│ interaction_count │
│ last_updated │
└──────────────────────┘
| Layer | Technology | Version |
|---|---|---|
| Frontend | Next.js + React | 16 / 19 |
| Styling | TailwindCSS | 4.0 |
| Backend | Spring Boot + Java | 3.4.0 / 21 |
| Database | PostgreSQL (Supabase) | 16 |
| Auth | Supabase Auth + JWT | - |
| Video Source | Pexels API | - |
- Java 21+
- Node.js 20+
- PostgreSQL (or Supabase account)
- Pexels API key (free at pexels.com)
git clone https://github.com/yourusername/streamrank.git
cd streamrankcp .env.example .env
# Edit .env with your credentials:
# - SUPABASE_URL, SUPABASE_KEY
# - PEXELS_API_KEY
# - DATABASE credentialscd backend
./gradlew bootRun
# Server starts at http://localhost:8080cd frontend
npm install
npm run dev
# App available at http://localhost:3000Visit the admin panel to import videos from Pexels:
curl -X POST http://localhost:8080/api/admin/seed?count=20| Method | Endpoint | Description |
|---|---|---|
GET |
/api/feed/{userId} |
Get personalized recommendations |
GET |
/api/feed/cold-start |
Get recommendations for new users |
GET |
/api/feed/{userId}/debug |
Get recommendations with score breakdown |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/interactions |
Log user interaction (like, skip, view, etc.) |
GET |
/api/interactions/user/{userId} |
Get user's interaction history |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/metrics/user/{userId} |
Get user-level metrics (Precision@K, NDCG) |
GET |
/api/metrics/system |
Get system-wide analytics |
GET |
/api/metrics/user/{userId}/diversity |
Get feed diversity analysis |
streamrank/
├── backend/
│ ├── src/main/java/com/streamrank/
│ │ ├── controller/ # REST endpoints
│ │ ├── service/ # Business logic
│ │ │ ├── RecommendationService.java
│ │ │ ├── CollaborativeFilteringService.java
│ │ │ ├── DiversityService.java
│ │ │ └── MetricsService.java
│ │ ├── repository/ # Data access
│ │ └── model/ # JPA entities
│ └── build.gradle.kts
├── frontend/
│ ├── src/
│ │ ├── app/ # Next.js pages
│ │ ├── components/ # React components
│ │ ├── hooks/ # Custom hooks
│ │ └── lib/ # API client, utilities
│ └── package.json
├── docs/
│ ├── ARCHITECTURE.md
│ └── images/
└── README.md
StreamRank tracks recommendation quality with industry-standard metrics:
| Metric | Description |
|---|---|
| Precision@K | Of K recommended videos, how many did user engage with? |
| Recall@K | Of all videos user would like, how many did we show? |
| NDCG@K | Did we rank the best videos highest? |
| CTR | Click-through rate across recommendations |
| Diversity Score | Average dissimilarity across recommended videos |
Access metrics via the /api/metrics endpoints or the Debug Dashboard.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.