Skip to main content

Overview

Lichess’s backend is built with Scala 3 and the Play Framework 2.8, following a highly modular architecture that separates concerns into independent modules. The server is fully asynchronous, leveraging Scala Futures and Akka Streams for high-performance concurrent operations.

Technology Stack

Core Technologies

  • Scala 3: Primary backend language providing type safety and functional programming features
  • Play Framework 2.8: Web framework handling HTTP requests and routing
  • Akka: Actor system and streaming library for concurrency
  • Macwire: Compile-time dependency injection
  • Scalatags: Type-safe HTML templating
  • ReactiveMongo: Asynchronous MongoDB driver

Key Dependencies

Modular Architecture

Module System

Lichess is organized into 85+ independent modules, each responsible for a specific domain. The build.sbt defines module dependencies in a strict hierarchy:
This dependency hierarchy ensures clean separation and prevents circular dependencies.

Key Modules

core: Foundation types and interfaces used across all modulescommon: Shared utilities, caching, text processingdb: MongoDB connection management and database abstractionsmemo: Caching layer with Caffeine/Scaffeine integrationi18n: Internationalization supporting 140+ languages
game: Game data models, moves, PGN handling
  • Location: modules/game/src/main/
  • Dependencies: tree, rating, memo
  • Features: Game compression, move validation, game queries
round: Live game management and real-time play
  • Location: modules/round/src/main/
  • Dependencies: room, game, user, playban, pref, chat
  • Features: Move processing, game lifecycle, actor-based game instances
analyse: Computer analysis and engine evaluation
  • Dependencies: tree, memo, ui
  • Integrates with Fishnet for Stockfish analysis
user: User accounts, authentication, profilessecurity: Authentication, authorization, rate limitingchat: Real-time chat functionalitymsg: Direct messaging between usersrelation: User relationships (follow, block)team: Team management and membership
tournament: Arena and Swiss tournamentssimul: Simultaneous exhibitionspuzzle: Tactical puzzles and trainingstudy: Shared analysis boards and studiesrelay: Broadcasting live games

Application Initialization

The application bootstraps through a dependency injection hierarchy defined in app/Env.scala:
Macwire performs compile-time dependency injection, ensuring type safety and eliminating runtime reflection overhead.

Asynchronous Processing

Scala Futures

All I/O operations are non-blocking and return Future[T]:

Akka Streams

Lichess uses Akka Streams for processing continuous data flows:
  • Real-time game event broadcasting
  • Large dataset processing (exports, database migrations)
  • Backpressure handling for external API integrations

Actor System

Critical real-time features use Akka actors:
  • Game instances: Each active game runs in its own actor
  • Tournament management: Tournament lifecycle managed by actors
  • Message routing: Event bus for cross-module communication

Routing

Play Framework’s routing is defined in conf/routes and split across multiple files:
Routes are type-safe with custom parameter extractors for domain types like GameId, UserId, etc.

Controllers

Controllers follow Play Framework conventions:
Key controller patterns:
  • Action composition: Authentication, rate limiting via action builders
  • Async actions: All actions return Future[Result]
  • JSON responses: Game API endpoints return Play JSON

Performance Optimizations

Scaffeine (Scala wrapper for Caffeine) provides high-performance in-memory caching:
Cached data includes:
  • User profiles and preferences
  • Game metadata
  • Leaderboards and rankings
  • Feature flags and settings
  • Projection: Only fetch required fields from MongoDB
  • Indexing: Extensive indexes on frequently queried fields
  • Batching: Bulk operations for mass updates
  • Connection pooling: ReactiveMongo manages connection pool
Kamon integration provides:
  • Request tracing and latency metrics
  • JVM metrics (memory, GC, threads)
  • Custom business metrics
  • InfluxDB and Prometheus export

Chess Logic

Pure chess logic is isolated in the scalachess submodule:
  • Move generation and validation
  • Chess variants (Chess960, Crazyhouse, etc.)
  • PGN parsing and generation
  • Position evaluation basics
This separation keeps game rules independent of server infrastructure.

Configuration

Configuration uses HOCON format in conf/base.conf:

See Also