The Challenge
We wanted to create a Spotify Wrapped-style experience for League of Legends players - a beautiful, personalized summary of their gaming year. But there was a catch: we needed to process potentially hundreds of matches, analyze complex statistics, and deliver results in under 2 minutes.
The solution? A modern serverless architecture combining AWS services, AI-powered insights, and the Riot Games API.
System Architecture
Here's the complete infrastructure that powers LoL Wrapped:

The full serverless stack: Frontend, GraphQL API, Database, Compute, and AI
Key Components
🎨 AWS Amplify
Hosts our Astro-based frontend with global CDN distribution. Every code push triggers an automatic build and deployment - zero-downtime updates in minutes.
⚡ AWS AppSync
Our GraphQL API layer. Handles all client requests, manages real-time subscriptions for live updates, and orchestrates between DynamoDB and Lambda.
💾 Amazon DynamoDB
NoSQL database storing wrapped data with millisecond latency. On-demand scaling means we only pay for what we use - perfect for bursty workloads.
🔥 AWS Lambda
Serverless Python functions that fetch data from Riot API, process hundreds of matches, calculate statistics, and generate insights. Auto-scales from zero to thousands of concurrent executions.
🚀 AWS App Runner
Runs our MCP (Model Context Protocol) server - a persistent HTTP service that exposes Riot API tools to AI agents. Container-based deployment with automatic scaling and health checks.
🤖 Amazon Bedrock
Powers AI-generated insights using Claude 4.5 Sonnet. Analyzes your playstyle, generates personalized commentary, and creates natural language summaries of your gaming year.
The Data Flow
When you request your Wrapped, here's what happens behind the scenes:
- Request Initiation: Your browser sends a GraphQL mutation to AppSync with your summoner name and region.
- Status Tracking: AppSync creates a record in DynamoDB with status "PROCESSING" and returns immediately.
- Lambda Invocation: AppSync triggers a Lambda function asynchronously to start data collection.
- Riot API Calls: Lambda fetches your PUUID, summoner info, match history (up to 100 games), and champion masteries from Riot's API.
- Analytics Processing: Our analytics engine calculates 200+ statistics including KDA, winrates, temporal patterns, and achievement tracking.
- AI Enhancement: Bedrock's Claude analyzes the data to generate personalized insights and natural language summaries.
- Asset Enrichment: Champion splash arts and icons are fetched from Data Dragon CDN.
- Final Update: Lambda writes the complete wrapped data back to DynamoDB with status "COMPLETED".
- Client Display: Frontend polls AppSync every 3 seconds, detects completion, and renders your beautiful wrapped visualization.
MCP: The Secret Sauce
One of the most innovative parts of our architecture is the Model Context Protocol (MCP) server. This standardized interface lets AI models interact with external data sources in a structured way.
Our MCP server exposes Riot API functionality as "tools" that Claude can use. Instead of hardcoding API calls, we let the AI agent decide when and how to fetch data - making the system more flexible and intelligent.
# Example MCP tool
@mcp.tool()
async def get_player_wrapped(
game_name: str,
tag_line: str,
region: str,
max_matches: int = 100
) -> str:
"""
Generate a complete Wrapped for a player.
Returns JSON with stats, rankings, and insights.
"""
# Fetch and analyze data...
return wrapped_json
Performance & Scalability
- Sub-2-minute processing: From request to completed wrapped in ~90 seconds
- Rate limit handling: Smart throttling to respect Riot's 20 req/sec limit
- Cost-efficient: Serverless = $0 when idle, scales only when needed
- Global CDN: Frontend loads in <1s from anywhere in the world
- Automatic scaling: Handles 1 user or 10,000 users without code changes
Complete Tech Stack
Frontend
Astro, React, TypeScript, Tailwind CSS, AWS Amplify
Backend
AWS Lambda (Python), AppSync (GraphQL), DynamoDB, App Runner
AI & Analytics
Amazon Bedrock (Claude 4.5), Pydantic AI, FastMCP, NumPy
Infrastructure
Terraform, CloudFormation, Docker, GitHub Actions
External APIs
Riot Games API, Data Dragon CDN
Challenges We Solved
⚡ Rate Limiting
Riot's API has strict rate limits (20 req/s, 100 req/2min). We implemented intelligent request batching and exponential backoff to maximize throughput while staying compliant.
🔄 Real-time Updates
Users don't want to wait staring at a loading screen. We use polling with GraphQL subscriptions ready for upgrade, showing progress updates as matches are processed.
💰 Cost Optimization
By using serverless architecture and on-demand DynamoDB, we keep costs near zero during development and scale gracefully under load. Estimated cost: $0-10/month for moderate usage.
What's Next?
- WebSocket subscriptions for true real-time updates
- Social sharing with custom OG images
- Multi-year comparison (compare 2024 vs 2025)
- Team wrapped (aggregate stats for friend groups)
- More AI-powered insights and predictions
Try It Yourself
Ready to see your year in League of Legends? Get your personalized Wrapped now.