Cache and polling strategy guide
Otimizar o uso de chamadas da API e fundamental para evitar rate limits e reduzir custos. Neste guia veremos os intervalos recomendados por tipo de dado.
Optimizing API call usage is essential to avoid rate limits and reduce costs. In this guide we'll cover the recommended polling intervals by data type.
A API usa Bunny CDN com TTLs diferentes por endpoint. O browser recebe no maximo 30s de cache para dados da API (imagens recebem 7 dias). A tabela abaixo mostra o cache no CDN (s-maxage):
The API uses Bunny CDN with different TTLs per endpoint. The browser gets at most 30s cache for API data (images get 7 days). The table below shows CDN cache (s-maxage):
| Endpoint | CDN Cache | Motivo / Reason |
|---|---|---|
/fixtures?live=all |
15 seconds | Placares mudam a qualquer momento / Scores change anytime |
/odds/live |
15 seconds | Odds ao vivo mudam constantemente / Live odds change constantly |
/fixtures?id=X |
30 seconds | Detalhe de jogo ao vivo / Live fixture detail |
/fixtures/events |
30 seconds | Gols, cartoes, substituicoes / Goals, cards, subs |
/fixtures/statistics |
30 seconds | Estatisticas do jogo ao vivo / Live match stats |
/fixtures/players |
30 seconds | Stats por jogador no jogo / Per-player match stats |
/fixtures?date=YYYY-MM-DD |
60 seconds | Horarios e status do dia / Daily schedule and status |
/odds?fixture=X |
60 seconds | Odds pre-jogo / Pre-match odds |
/fixtures?league=X |
5 minutes | Calendario da liga / League schedule |
/fixtures?team=X |
5 minutes | Calendario do time / Team schedule |
/fixtures/lineups |
5 minutes | Escalacoes confirmadas / Confirmed lineups |
/players/topscorers |
15 minutes | Rankings de artilheiros / Scorer rankings |
/players/topassists |
15 minutes | Rankings de assistencias / Assist rankings |
/standings |
1 hour | Classificacao atualiza apos jogos / Standings update after matches |
/teams/statistics |
1 hour | Agregacoes de temporada / Season aggregations |
/fixtures/headtohead |
1 hour | Historico de confrontos / Match history |
/players?id=X |
1 hour | Estatisticas individuais / Individual stats |
/injuries |
1 hour | Lesoes e suspensoes / Injuries and suspensions |
/players/squads |
6 hours | Elencos atuais / Current squads |
/coachs |
6 hours | Informacoes de treinadores / Coach info |
/transfers |
6 hours | Historico de transferencias / Transfer history |
/fixtures/rounds |
6 hours | Rodadas disponiveis / Available rounds |
/leagues, /teams, /countries |
1 day | Dados estruturais mudam raramente / Structural data rarely changes |
/seasons, /timezone, /venues |
1 day | Referencia estatica / Static reference |
Images (/football/*, /flags/*) |
7 days | Logos, fotos, bandeiras / Logos, photos, flags |
class Poller {
constructor(fetchFn, intervalMs) {
this.fetchFn = fetchFn;
this.intervalMs = intervalMs;
this.timer = null;
this.controller = null;
}
async tick() {
if (this.controller) this.controller.abort();
this.controller = new AbortController();
try {
await this.fetchFn(this.controller.signal);
} catch (err) {
if (err.name !== 'AbortError') console.error(err);
}
}
start() {
this.tick();
this.timer = setInterval(() => this.tick(), this.intervalMs);
}
stop() {
clearInterval(this.timer);
if (this.controller) this.controller.abort();
}
}
// Usage
const livePoller = new Poller(async (signal) => {
const res = await fetch(`${BASE}/fixtures?live=all&key=${API_KEY}`, { signal });
const data = await res.json();
updateUI(data.response);
}, 20000);
livePoller.start();
// When leaving the page
window.addEventListener('beforeunload', () => livePoller.stop());
Para dados que mudam raramente (times, ligas), um cache em memoria com TTL evita chamadas desnecessarias.
const cache = new Map();
async function cachedFetch(url, ttlMs) {
const cached = cache.get(url);
if (cached && Date.now() - cached.time < ttlMs) {
return cached.data;
}
const res = await fetch(url);
const data = await res.json();
cache.set(url, { data, time: Date.now() });
return data;
}
// Teams cached for 24h
const teams = await cachedFetch(
`${BASE}/teams?league=71&season=2025&key=${API_KEY}`,
86400000
);
/fixtures?date=today para saber se ha jogos no dia / Use to check if there are matches todayx-ratelimit-remaining para saber quantas chamadas restam / Monitor to know remaining callss-maxage (ate 7 dias para imagens), mas o browser sempre recebe max-age de no maximo 30 segundos para dados da API. Isso garante que o usuario veja dados frescos sem sobrecarregar a origem.
s-maxage (up to 7 days for images), but the browser always gets a max-age of at most 30 seconds for API data. This ensures users see fresh data without overloading the origin.