Ad Expiration
Ads expire after 60 minutes, ensuring fresh content and accurate metrics. This follows the same pattern used by Google AdMob.
How It Works
Every ad returned by the SDK includes an expiresAt timestamp:
const ad = await ads.getAd({ input: 'user query' });
console.log(ad.expiresAt); // 1704067200000 (Unix timestamp in ms)
console.log(new Date(ad.expiresAt)); // Date object 60 min from fetch timeThe 60-minute expiration window balances ad freshness with reasonable cache duration.
Checking Expiration
Use the isAdExpired helper to check if an ad should be refreshed:
import { isAdExpired } from 'notpixel';
const ad = await ads.getAd({ input: 'query' });
// Later...
if (isAdExpired(ad)) {
// Ad is stale, fetch a new one
const freshAd = await ads.getAd({ input: 'query' });
}Automatic Cache Handling
When caching is enabled, the SDK automatically:
- Checks if cached ads are expired before returning them
- Fetches fresh ads when cached ones have expired
- Removes expired entries from cache
const ads = new Ads({
publisherId: 'pub-xxx',
cache: true, // Expiration is respected automatically
});
// First call - fetches from API
const ad1 = await ads.getAd({ input: 'query' });
// 30 minutes later - returns cached ad
const ad2 = await ads.getAd({ input: 'query' });
// 61 minutes later - fetches fresh ad (cached one expired)
const ad3 = await ads.getAd({ input: 'query' });Browser Usage
The expiration utilities are also available in the browser tracking library:
import { isAdExpired, AD_EXPIRATION_MS } from 'notpixel/browser';
// Check expiration
if (isAdExpired(ad)) {
// Refresh via your backend
const freshAd = await fetchAdFromServer();
}
// Calculate remaining time
const remainingMs = ad.expiresAt - Date.now();
const remainingMinutes = Math.floor(remainingMs / 60000);
console.log(`Ad expires in ${remainingMinutes} minutes`);Constants
| Constant | Value | Description |
|---|---|---|
AD_EXPIRATION_MS | 3600000 | 60 minutes in milliseconds |
Why 60 Minutes?
- Fresh inventory: Advertisers update bids and budgets frequently
- Accurate metrics: Ensures impressions reflect current campaign status
- Budget control: Prevents serving ads from exhausted budgets
- A/B testing: Allows campaigns to rotate creatives
Best Practices
- Store
expiresAt: When caching ads client-side, always store theexpiresAtvalue - Check before display: Verify expiration before showing an ad to users
- Graceful refresh: Pre-fetch replacement ads before current ones expire
- Handle missing ads: Have fallback UI when no fresh ad is available
// Example: Pre-fetch before expiration
function scheduleRefresh(ad: Ad) {
const refreshBuffer = 5 * 60 * 1000; // 5 minutes before expiration
const refreshIn = ad.expiresAt - Date.now() - refreshBuffer;
if (refreshIn > 0) {
setTimeout(async () => {
const freshAd = await ads.getAd({ input: lastQuery });
updateAdDisplay(freshAd);
}, refreshIn);
}
}