Tech Stack
Gumroad is built on a modern, scalable stack designed to handle high-traffic e-commerce operations:Backend
- Rails 7.1.6 - Main application framework
- Ruby 3.4.3 - Programming language
- MySQL 8.0.x - Primary relational database with Makara for read replicas
- MongoDB - Document store for specific use cases
- Redis - Caching and session management
- Sidekiq 7.2 - Background job processing with Sidekiq Pro features
- Elasticsearch 7.11.2 - Full-text search and analytics
Frontend
- React 18.1.0 - UI component library
- TypeScript 5.5.0 - Type-safe JavaScript
- Inertia.js 3.15 - Modern monolith SPA framework
- Tailwind CSS 4.1.14 - Utility-first CSS framework
- Shakapacker 8.0 - Webpack integration for Rails
Infrastructure
- Docker - Local development environment
- Puma 6.4.2 - Web server
- AnyCable 1.5 - WebSocket server for real-time features
- Nomad - Production deployment orchestration
Application Structure
Directory Layout
The
app/modules/ directory is legacy. Use concerns in the appropriate directory instead (e.g., app/models/concerns/).Key Architectural Patterns
Service Objects
Service Objects
Complex business logic is encapsulated in service objects located in
app/services/. These objects follow the single responsibility principle and make the codebase more maintainable.Example structure:Presenters
Presenters
Presenters in
app/presenters/ handle view-layer data preparation, keeping controllers thin and views clean.Policy-Based Authorization
Policy-Based Authorization
Database Architecture
MySQL with Makara
The application uses MySQL 8.0.x with the Makara gem for database connection management:Makara automatically routes read queries to replicas and write queries to the primary database, improving performance and scalability.
Connection Pooling
The database pool size is configurable viaDB_POOL_SIZE environment variable. Sidekiq workers use larger pool sizes to handle concurrent job processing.
Schema Management
Database migrations are managed through Rails migrations:Background Job Processing
Sidekiq Configuration
Gumroad uses Sidekiq with Pro features for reliable background job processing:Queue Priorities
Jobs are organized by priority:- critical - Receipt and purchase emails (time-sensitive)
- default - Standard background jobs
- low - Non-urgent batch operations
- mongo - Legacy queue for one-time scripts
Job Naming Convention
All new Sidekiq job classes must end with “Job”:Search with Elasticsearch
Elasticsearch 7.11.2 powers search functionality across products, users, and sales data.Reindexing
After initial setup or schema changes, reindex all data:Caching Strategy
Redis is used for:- Session storage
- Action caching
- Fragment caching
- Sidekiq job queues
- Rate limiting
Real-time Features
WebSocket functionality is powered by:- AnyCable - Scalable WebSocket server
- Action Cable - Rails WebSocket framework
config/anycable.yml defines connection settings.
Code Organization Principles
Use conventions
Follow Rails conventions and Gumroad-specific patterns documented in CONTRIBUTING.md.
Keep controllers thin
Controllers should primarily route requests and delegate to service objects or models.
Performance Considerations
Database Queries
- Use database indexes appropriately
- Avoid N+1 queries with eager loading
- Use
includesandjoinsstrategically - Monitor query performance with Active Record Query Trace (development)
Background Jobs
- Keep jobs idempotent when possible
- Use
lock: :until_executedfor deduplication - Avoid
on_conflict: :replacedue to performance impact - Monitor job queue latency
Caching
- Use action caching for expensive operations
- Implement fragment caching for partial views
- Set appropriate cache expiration times
Development Tools
- Pry - Enhanced IRB console with debugging
- Rubocop - Ruby code linter
- ESLint - JavaScript/TypeScript linter
- Bullet - N+1 query detection (development)
- Rack Mini Profiler - Performance profiling
Next Steps
Authentication
Learn about Devise and OAuth implementation
Testing
Understand the testing strategy with RSpec
Deployment
Deploy changes to staging and production
Contributing
Read the contribution guidelines