Look-ahead cache
Proactively prefetches upcoming streamed tracks to disk so they start instantly and survive brief network drops. It applies to http(s):// sources only — file:// (local) tracks are already on disk and are skipped.
Methods live on the TrackPlayer singleton:
import { getTrackPlayer } from 'react-native-queue-player';
const player = getTrackPlayer();
// Disk budget + eviction policy are configure-time (fixed at cache
// construction), not runtime controls. Set them once at app init alongside your
// other config; changing either later means calling configure() again (a full
// player reinit) with your complete config.
await player.configure({
// ...your other PlayerConfig (httpHeaders, userAgent, ...)
lookaheadCacheMaxSizeMb: 200, // disk budget; default 100 MB
lookaheadCacheEvictionPolicy: 'lru', // 'lru' (default) or 'fifo'
});
// Runtime controls: enable/disable + how many tracks to prefetch. These apply
// live, no configure() cycle needed.
await player.setLookaheadCache({
enabled: true,
lookaheadCount: 3, // prefetch the next N tracks
allowsCellularAccess: true, // default; false backs a "Wi-Fi only" setting
});
:::note Protecting the playing track
Eviction runs on every download commit, so the entry backing the track being
played can otherwise be deleted mid-playback. iOS protects the playing track and
its neighbours under both eviction policies. Android protects them under
'fifo' only — Media3's LRU evictor has no protected-key concept, and its
recency bump is per byte-range span rather than per track.
Where the playing track is protected, lookaheadCacheMaxSizeMb behaves as a
budget rather than a hard cap: if the protected tracks alone exceed it, nothing
is evictable and currentSizeMb can read above maxSizeMb until the window
moves.
:::
Methods
setLookaheadCache(config: LookaheadCacheConfig): Promise<void>
getLookaheadCacheStatus(): Promise<CacheStatus>
clearLookaheadCache(): Promise<void> // wipes + stops; does not auto-restart prefetch
onCacheStatusChange(callback: (status: CacheStatus) => void): () => void // fires once on subscribe with current status
Types
type LookaheadCacheConfig = {
enabled: boolean; // disabled: every read goes to the origin, nothing is written
lookaheadCount: number; // prefetch the next N tracks
allowsCellularAccess?: boolean; // default true
};
// allowsCellularAccess — prefetch downloads whole upcoming tracks, so on a
// metered connection it can spend a lot of data on tracks the listener skips
// past. Set false to back a "download over Wi-Fi only" setting. It is a runtime
// control like the two above, so a settings toggle can flip it without a
// configure() cycle. It gates prefetch only — playback is never blocked by it.
// Disk budget + eviction policy live on PlayerConfig (configure-time only):
// configure({ lookaheadCacheMaxSizeMb?: number,
// lookaheadCacheEvictionPolicy?: 'lru' | 'fifo' })
// Both are fixed at cache construction (Android's SimpleCache can't resize or
// swap its evictor live); read the active ceiling back from CacheStatus.maxSizeMb.
//
// Eviction policy — default 'lru'. Changing it clears the cache and rebuilds:
// 'lru' evicts the least-recently-used track first (recently played tracks
// are kept).
// 'fifo' evicts the oldest-fetched track first, regardless of replays
// ("keep the newest-fetched"); suits a forward-only prefetch queue.
type CacheStatus = {
enabled: boolean;
currentSizeMb: number; // current disk usage
maxSizeMb: number; // the configured budget
tracksFullyCached: number; // total tracks fully downloaded on disk
currentlyCaching: string[]; // URLs downloading right now
};
:::note How allowsCellularAccess is enforced
The two platforms offer different primitives, so the enforcement point differs:
- iOS sets the flag on each prefetch request and the OS refuses to run that request over cellular. A download already on the wire keeps the value it started with and runs to completion.
- Android has no per-request equivalent, so prefetch stops being scheduled while the default network is cellular. That also cancels the download in flight; its partial data stays in the cache and resumes once prefetch is permitted again.
So a prefetch issued while it is false never crosses a cellular link on
either platform; a download that was already in flight when the value changed
finishes on iOS and is cancelled on Android. Playback is unaffected on both.
:::
In React, see useLookaheadCache.