AI-Powered Personalization: Building Recommendation Systems for Web Apps | SoniNow Blog

Limited TimeLearn More

aipersonalizationrecommendation systemsmachine learningux

AI-Powered Personalization: Building Recommendation Systems for Web Apps

Published

2026-06-23

Read Time

4 mins

AI-Powered Personalization: Building Recommendation Systems for Web Apps

Personalization drives user engagement. Whether you're recommending products, content, or features, an AI-powered recommendation system can increase click-through rates by 40-60% compared to generic alternatives. Here's how to build one that delivers real business value.

The Recommendation Landscape

Three main approaches power modern recommendation systems:

Collaborative Filtering: "Users who liked X also liked Y." Based on user-item interaction patterns. Works well at scale but suffers from the cold-start problem.

Content-Based Filtering: "You liked X because it has properties A, B, C." Based on item features and user preferences. No cold-start for new items but limits serendipity.

Hybrid Approaches: Combine both methods to get the best of each—this is what production systems actually use.

Building a Hybrid Recommendation Engine

Start with a simple hybrid architecture using embeddings:

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

class HybridRecommender:
    def __init__(self, embedding_model):
        self.embedding_model = embedding_model  # e.g., text-embedding-3-small
        self.user_profiles = {}  # user_id → embedding
        self.item_embeddings = {}  # item_id → embedding
        self.interaction_matrix = {}  # user_id → {item_id: score}
    
    def recommend(self, user_id, top_k=10, alpha=0.7):
        """
        Hybrid recommendation: alpha * content + (1-alpha) * collaborative
        """
        # Content-based score
        user_embed = self.user_profiles.get(user_id, np.zeros(1536))
        content_scores = {
            item_id: cosine_similarity([user_embed], [item_embed])[0][0]
            for item_id, item_embed in self.item_embeddings.items()
        }
        
        # Collaborative score (if user has history)
        collab_scores = {}
        if user_id in self.interaction_matrix:
            user_history = self.interaction_matrix[user_id]
            similar_users = self._find_similar_users(user_id)
            collab_scores = self._aggregate_preferences(similar_users)
        
        # Hybrid combination
        combined = {}
        for item_id in self.item_embeddings:
            content_score = content_scores.get(item_id, 0)
            collab_score = collab_scores.get(item_id, 0)
            combined[item_id] = alpha * content_score + (1 - alpha) * collab_score
        
        return sorted(combined, key=combined.get, reverse=True)[:top_k]

User Profile Construction

A user profile is a learned representation of preferences. Build it from multiple signals:

// User profile aggregation (serverless function)
async function buildUserProfile(userId) {
  const [clicks, purchases, views, searchHistory] = await Promise.all([
    db.query('SELECT item_id FROM clicks WHERE user_id = $1', [userId]),
    db.query('SELECT item_id FROM purchases WHERE user_id = $1', [userId]),
    db.query('SELECT item_id, dwell_time FROM views WHERE user_id = $1', [userId]),
    db.query('SELECT query FROM searches WHERE user_id = $1', [userId])
  ]);

  const weightedItems = [
    ...purchases.rows.map(r => ({ id: r.item_id, weight: 3.0 })),
    ...clicks.rows.map(r => ({ id: r.item_id, weight: 1.5 })),
    ...views.rows.map(r => ({ id: r.item_id, weight: Math.min(r.dwell_time / 30, 1.0) }))
  ];

  return weightedItems;
}

Weights matter: Purchases should weight higher than clicks (3x). Dwell time contextualizes views (a 30-second view vs. a quick scroll-by). Searches reveal explicit intent.

Feature Engineering for Items

Every item needs a rich feature vector. For an e-commerce or content platform:

item_features = {
    "title_embedding": embedding_model.encode(item.title),
    "description_embedding": embedding_model.encode(item.description),
    "categorical_features": one_hot_encode([item.category, item.subcategory, item.brand]),
    "numeric_features": normalize([item.price, item.rating, item.popularity_score]),
    "recency_factor": days_since(item.published_date),
    "image_embedding": vision_model.encode(item.image_url)  # if available
}

Cold start for new items: Without interaction data, the content-based component handles recommendations entirely. As interactions accumulate, the collaborative signal strengthens.

Real-Time Personalization

Static recommendations are outdated as soon as the user clicks something. Implement real-time updates:

class RealTimeRecommender:
    def __init__(self, redis_client):
        self.cache = redis_client
        self.recommendation_ttl = 300  # 5 minutes
    
    async def get_recommendations(self, user_id, context):
        cache_key = f"recs:{user_id}:{context.get('page', 'home')}"
        
        cached = await self.cache.get(cache_key)
        if cached:
            return json.loads(cached)
        
        # Real-time computation
        recs = await self.compute(user_id, context)
        
        # Cache for 5 minutes
        await self.cache.setex(cache_key, self.recommendation_ttl, json.dumps(recs))
        return recs
    
    async def on_interaction(self, user_id, item_id, interaction_type):
        # Invalidate cache immediately on interaction
        await self.cache.delete(f"recs:{user_id}:*")
        # Update user profile asynchronously
        asyncio.create_task(self.update_profile(user_id, item_id, interaction_type))

Cache invalidation on interaction is the hidden key to real-time personalization. Stale recommendations for even 10 minutes hurt conversion rates measurably.

A/B Testing Personalization

Never deploy a recommendation change without an experiment:

// RecommendOS A/B test setup
const experiment = {
  id: "rec-algorithm-v2",
  variants: {
    control: { type: "popularity", name: "Most Popular" },
    treatment: { type: "hybrid", alpha: 0.7, name: "Hybrid V2" }
  },
  metrics: ["click_through_rate", "conversion", "avg_session_duration", "revenue_per_user"],
  sampleSize: 10000,
  minimumDuration: "7d"
};

Key metrics for recommendation systems:

  • Click-through rate (CTR): Are users clicking recommendations?
  • Conversion rate: Do recommendations lead to purchases/signups?
  • Diversity: Are recommendations too narrow? Track category entropy.
  • Freshness: Are new items being recommended? Track percentage of new items in top positions.
  • Revenue lift: The ultimate business metric: incremental revenue from recommendations vs. baseline.

Infrastructure Considerations

At SoniNow, we build recommendation systems that scale from thousands to millions of users. Our web development and AI automation services include:

  • Real-time user profile construction with event streaming (Kafka/Redpanda)
  • Vector similarity search with pgvector or Qdrant
  • Redis caching for sub-10ms recommendation delivery
  • A/B testing infrastructure for algorithm iteration
  • Dashboard for monitoring recommendation performance

A well-built recommendation system is your silent revenue engine. Talk to us about adding intelligent personalization to your web application.