A Spring Boot–backed Lavalink plugin that adds a local-first disk cache in front of Lavaplayer's YouTube and Src source managers. When a track is requested, the plugin serves audio straight from disk whenever possible and, on misses, streams from the upstream source while persisting an encoded copy for future playback.
- Local-first playback – cached tracks are read from disk through
CachedAudioTrack, reducing network usage and startup latency. - As-you-play caching –
TeeAudioTrackstreams to the client and asynchronously downloads the original media to a.audiofile. - SQLite-backed index –
SqliteCacheIndextracks metadata, lock state, and LFU metrics for eviction decisions. - Adaptive eviction –
EvictionServiceenforces disk quotas through a least-frequently-used strategy with aging to avoid stale content. - Pluggable configuration – Spring Boot auto-configuration wires everything through the
plugins.cachenamespace.
.
├── build.gradle.kts # Kotlin + dependency management
├── settings.gradle.kts
└── src/main/kotlin/
└── com/lavalink/cache/
├── config/ # CacheConfig + Spring properties binding
├── eviction/ # EvictionService and policies
├── index/ # CacheIndex interface + SQLite implementation
├── key/ # Cache key normalization utilities
├── spring/ # Auto-configuration entry point
└── track/ # Cached/Tee tracks and source manager
- JDK 17+
- Gradle 8+ (install locally or generate a wrapper via
gradle wrapperonce) - A Lavalink server that supports plugins (plugin API 4.x)
Run the test suite and assemble the plugin JAR:
# from the repository root
gradle clean buildIf you prefer to ship a wrapper into the repo:
gradle wrapper --gradle-version 8.10
./gradlew.bat clean buildThe compiled artifact will appear under build/libs/.
- Copy the built JAR into Lavalink's
plugins/directory. - Add configuration to
application.yml(see below). - Restart Lavalink.
Configure the plugin with the plugins.cache namespace. Default values live in CacheProperties.
plugins:
cache:
enabled: true # Toggle the cache source manager
directory: data/cache # Where cached audio files are stored
db-file: data/cache/cache.db
max-bytes: 50_000_000 # Disk quota before eviction kicks in
min-keep-bytes: 524288 # Discard partial downloads below this size
lock-timeout: 600s # How long to wait before forcing unlock
eviction-interval: 60s # Background eviction cadenceRestart Lavalink after adjusting configuration.
- Lookup –
CachedSourceManagernormalizes the identifier into aCacheKeyand triesSqliteCacheIndexfor a ready entry. - Hit –
CachedAudioTrackstreams directly from the cached.audiofile. - Miss –
TeeAudioTrackdelegates playback to the original source whileBackgroundDownloaderpersists the upstream bytes. When the download completes, the index marks the entry as ready for reuse. - Eviction –
EvictionServicewatches size/age metrics and prunes least-used items while respecting active locks.
- The plugin relies on Spring auto-configuration (
CacheAutoConfiguration) registered viaMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. - Cache metadata lives in SQLite; inspect it with any standard SQLite client when debugging.
- Logging is provided by Logback; adjust levels via Lavalink's logging configuration if you need more insight.
- REST endpoints for cache introspection and manual invalidation.
- Smarter header propagation to support authenticated sources.
- Metrics export (Micrometer/Prometheus) for cache hit ratios.
Contributions and issue reports are very welcome—feel free to open a ticket or submit a PR with enhancements!