A PNPM monorepo demonstrating performance optimization opportunities in a three-tier architecture. This project is designed for educational purposes to teach students how to identify and optimize performance bottlenecks.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │ │ API │ │ Database │
│ (Next.js) │◄──►│ (Express) │◄──►│ (JSON Files) │
│ Port: 3000 │ │ Port: 3001 │ │ Configurable │
│ │ │ │ │ Delays │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- JSON-based database client with configurable delays
- CRUD operations for student data
- Simulates real database latency (1-3 seconds per operation)
- Configurable timing per operation type
- Express.js REST API
- Business logic layer
- CORS enabled for frontend communication
- Health check endpoint
- Next.js 14 application
- Tailwind CSS for styling
- Student directory interface
- Performance bottleneck demonstrations
- Node.js 18+
- PNPM 8+
-
Clone the repository
-
Install dependencies:
pnpm install
-
Start all services in development mode:
Option 1: Local development
pnpm dev # or ./scripts/dev.sh
Option 2: Network access (same WiFi/network)
pnpm dev:network # or ./scripts/dev-network.sh
Option 3: ngrok tunnels (universal remote access)
pnpm dev:ngrok # or ./scripts/dev-ngrok.sh
Option 4: Cloud deployment (persistent access)
pnpm deploy # or ./scripts/deploy.sh
Or start services individually:
# Database (builds TypeScript) pnpm db:dev # API server pnpm api:dev # Frontend pnpm web:dev
-
Open your browser to:
- Frontend: http://localhost:3000
- API Health Check: http://localhost:3001/health
- API Documentation: http://localhost:3001/api/students
- View all students with detailed information
- Filter students by major, year, and GPA range
- Persistent filter state - filters are saved in URL and survive page refreshes
- Real-time performance monitoring
- Sticky header and performance stats footer
This application intentionally includes several performance issues for educational purposes:
- ❌ Slow operations: Each CRUD operation takes 1-3 seconds
- ❌ No connection pooling: Each request creates new file operations
- ❌ No indexing: Linear search through JSON arrays
- ❌ No query optimization: Always loads full dataset
- ❌ No caching: Every request hits the database
- ❌ No pagination: Returns all records at once
- ❌ Sequential operations: No parallel processing
- ❌ No rate limiting: Unlimited concurrent requests
- ❌ No client-side caching: Each navigation refetches data
- ❌ No loading states optimization: Poor UX during delays
- ❌ No virtual scrolling: Renders all items at once
- ❌ No request deduplication: Multiple simultaneous requests possible
- ❌ Server-side filtering: Each filter change makes a new API call (intentionally inefficient)
You can configure database operation delays via environment variables:
# API package .env
DB_CREATE_DELAY=2000 # 2 seconds
DB_READ_DELAY=1000 # 1 second
DB_UPDATE_DELAY=2500 # 2.5 seconds
DB_DELETE_DELAY=1500 # 1.5 seconds
Or via the API endpoint:
curl -X POST http://localhost:3001/api/config/delays \
-H "Content-Type: application/json" \
-d '{"delays": {"read": 500, "create": 1000}}'
The database is pre-populated with 6 computer science students including:
- Names, emails, majors
- Academic year and GPA
- Contact information
- Generated avatars
Students will learn to:
- Identify bottlenecks using browser dev tools
- Implement caching at multiple layers
- Optimize database queries and operations
- Add pagination and virtual scrolling
- Implement parallel processing
- Add loading states and optimistic updates
- Monitor performance with metrics
-
Database Layer
- Add in-memory caching
- Implement query optimization
- Add database indexing simulation
- Connection pooling
-
API Layer
- Redis caching
- Response compression
- Pagination
- Parallel query execution
- GraphQL for efficient data fetching
-
Frontend Layer
- React Query/SWR for caching
- Virtual scrolling
- Code splitting
- Image optimization
- Service workers
GET /health - Health check
GET /api/students - Get all students (with optional filters)
GET /api/students/:id - Get student by ID
POST /api/students - Create new student
PUT /api/students/:id - Update student
DELETE /api/students/:id - Delete student
POST /api/config/delays - Update database delays
The /api/students
endpoint supports filtering via query parameters:
# Filter by major
GET /api/students?major=Computer%20Science
# Filter by year
GET /api/students?year=3
# Filter by GPA range
GET /api/students?gpaMin=3.0&gpaMax=4.0
# Combine multiple filters
GET /api/students?major=Data%20Science&year=4&gpaMin=3.5
Available filter parameters:
major
- Filter by exact major (case-insensitive)year
- Filter by year in school (1-5)gpaMin
- Minimum GPA (0.0-4.0)gpaMax
- Maximum GPA (0.0-4.0)
Filters are automatically saved in the URL, allowing users to:
- Bookmark filtered results for quick access
- Share filtered views with others via URL
- Maintain filter state across page refreshes and navigation
Example URLs:
# Computer Science students only
http://localhost:3000/?major=Computer%20Science
# 4th year students with GPA above 3.5
http://localhost:3000/?year=4&gpaMin=3.5
# Data Science students in years 3-4 with GPA 3.0-3.8
http://localhost:3000/?major=Data%20Science&year=3&gpaMin=3.0&gpaMax=3.8
# Install dependencies
pnpm install
# Development mode (local only)
pnpm dev
# Development mode (accessible on network)
pnpm dev:network
# Development mode (ngrok tunnels for remote access)
pnpm dev:ngrok
# Deploy to cloud (Vercel)
pnpm deploy
# Legacy: Development mode (all packages)
pnpm dev:all
# Build all packages
pnpm build
# Clean all build artifacts
pnpm clean
# Individual package commands
pnpm --filter db run build
pnpm --filter api run dev
pnpm --filter web-fe run build
All development and deployment scripts are located in scripts/
:
scripts/dev.sh
- Standard local developmentscripts/dev-network.sh
- Network-accessible development (for classrooms)scripts/dev-ngrok.sh
- ngrok tunnels for universal remote accessscripts/deploy.sh
- Quick cloud deployment to Vercel
- ngrok (Recommended): Run
pnpm dev:ngrok
- creates tunnels for both API and frontend - Network Mode: Run
pnpm dev:network
and share the local IP URL (same network only) - Cloud Deploy: Run
pnpm deploy
for persistent access
Use pnpm deploy
to create a permanent URL students can access anytime.
- Sign up at https://ngrok.com/ (free)
- Install:
brew install ngrok
(macOS) or download from website - Get your auth token from the ngrok dashboard
- Run:
ngrok config add-authtoken YOUR_TOKEN
- Then use:
pnpm dev:ngrok
- Package Manager: PNPM
- Database: JSON files with fs-extra
- API: Express.js + TypeScript
- Frontend: Next.js 14 + TypeScript + Tailwind CSS
- Icons: Lucide React
- Build: TypeScript compiler
MIT - Educational use encouraged!