Common patterns: Caching patterns
How caching works
- Unified cache — the first request creates a shared copy (
x-cache-status: MISS). Subsequent requests serve that copy (HIT). - Edge node cache — after the unified cache is warm, responses are also served from the nearest CloudFlare edge node.
Cache TTL PRO
ttl to control how long a response stays valid before expiring:The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://microlink.io' URL with 'ttl' & 'apiKey' API parameters:
CLI Microlink API example
microlink https://microlink.io&ttl=1d --api-key YOUR_API_TOKENcURL Microlink API example
curl -G "https://pro.microlink.io" \
-H "x-api-key: YOUR_API_TOKEN" \
-d "url=https://microlink.io" \
-d "ttl=1d"JavaScript Microlink API example
import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
ttl: "1d",
apiKey: "YOUR_API_TOKEN"
})Python Microlink API example
import requests
url = "https://pro.microlink.io/"
querystring = {
"url": "https://microlink.io",
"ttl": "1d"
}
headers = {
"x-api-key": "YOUR_API_TOKEN"
}
response = requests.get(url, params=querystring, headers=headers)
print(response.json())Ruby Microlink API example
require 'uri'
require 'net/http'
base_url = "https://pro.microlink.io/"
params = {
url: "https://microlink.io",
ttl: "1d"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['x-api-key'] = "YOUR_API_TOKEN"
response = http.request(request)
puts response.bodyPHP Microlink API example
<?php
$baseUrl = "https://pro.microlink.io/";
$params = [
"url" => "https://microlink.io",
"ttl" => "1d"
];
$query = http_build_query($params);
$url = $baseUrl . '?' . $query;
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_TOKEN"
]
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #: " . $err;
} else {
echo $response;
}Golang Microlink API example
package main
import (
"fmt"
"net/http"
"net/url"
"io"
)
func main() {
baseURL := "https://pro.microlink.io"
u, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
q := u.Query()
q.Set("url", "https://microlink.io")
q.Set("ttl", "1d")
u.RawQuery = q.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
panic(err)
}
req.Header.Set("x-api-key", "YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
ttl: "1d",
apiKey: "YOUR_API_TOKEN"
})ttl=90s # 90 seconds
ttl=1h # 1 hour
ttl=1d # 1 day (24 hours)
ttl=7d # 7 days
ttl=min # alias for 1 minute
ttl=max # alias for 31 days| Content type | Recommended TTL |
|---|---|
| Rapidly changing (dashboards, feeds) | '1h' or less |
| Moderate changes (blogs, docs, marketing pages) | '1d' to '7d' |
| Rarely changing (static docs, stable references) | 'max' (31 days) |
x-cache-ttl response header. See the ttl reference for all supported formats.Stale-while-revalidate PRO
staleTtl parameter serves the cached response immediately while refreshing it in the background:The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://microlink.io' URL with 'ttl', 'staleTtl' & 'apiKey' API parameters:
CLI Microlink API example
microlink https://microlink.io&ttl=1d&staleTtl=0 --api-key YOUR_API_TOKENcURL Microlink API example
curl -G "https://pro.microlink.io" \
-H "x-api-key: YOUR_API_TOKEN" \
-d "url=https://microlink.io" \
-d "ttl=1d" \
-d "staleTtl=0"JavaScript Microlink API example
import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
ttl: "1d",
staleTtl: 0,
apiKey: "YOUR_API_TOKEN"
})Python Microlink API example
import requests
url = "https://pro.microlink.io/"
querystring = {
"url": "https://microlink.io",
"ttl": "1d",
"staleTtl": "0"
}
headers = {
"x-api-key": "YOUR_API_TOKEN"
}
response = requests.get(url, params=querystring, headers=headers)
print(response.json())Ruby Microlink API example
require 'uri'
require 'net/http'
base_url = "https://pro.microlink.io/"
params = {
url: "https://microlink.io",
ttl: "1d",
staleTtl: "0"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['x-api-key'] = "YOUR_API_TOKEN"
response = http.request(request)
puts response.bodyPHP Microlink API example
<?php
$baseUrl = "https://pro.microlink.io/";
$params = [
"url" => "https://microlink.io",
"ttl" => "1d",
"staleTtl" => "0"
];
$query = http_build_query($params);
$url = $baseUrl . '?' . $query;
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_TOKEN"
]
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #: " . $err;
} else {
echo $response;
}Golang Microlink API example
package main
import (
"fmt"
"net/http"
"net/url"
"io"
)
func main() {
baseURL := "https://pro.microlink.io"
u, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
q := u.Query()
q.Set("url", "https://microlink.io")
q.Set("ttl", "1d")
q.Set("staleTtl", "0")
u.RawQuery = q.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
panic(err)
}
req.Header.Set("x-api-key", "YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
ttl: "1d",
staleTtl: 0,
apiKey: "YOUR_API_TOKEN"
})staleTtl: 0, every request serves the cached copy instantly and triggers a background refresh.staleTtl value cannot exceed the ttl value.| Pattern | Behavior |
|---|---|
staleTtl: 0 | Always serve cache, always revalidate in background |
staleTtl: '12h' | Serve cache for 12 hours, then revalidate |
staleTtl: false | Disabled (default) — no stale serving |
Separate cache entries PRO
cacheKey to append a custom identifier and split that copy into independent entries:The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://microlink.io' URL with 'screenshot' & 'cacheKey' API parameters:
CLI Microlink API example
microlink https://microlink.io&screenshot&cacheKey=variant-acURL Microlink API example
curl -G "https://api.microlink.io" \
-d "url=https://microlink.io" \
-d "screenshot=true" \
-d "cacheKey=variant-a"JavaScript Microlink API example
import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
screenshot: true,
cacheKey: "variant-a"
})Python Microlink API example
import requests
url = "https://api.microlink.io/"
querystring = {
"url": "https://microlink.io",
"screenshot": "true",
"cacheKey": "variant-a"
}
response = requests.get(url, params=querystring)
print(response.json())Ruby Microlink API example
require 'uri'
require 'net/http'
base_url = "https://api.microlink.io/"
params = {
url: "https://microlink.io",
screenshot: "true",
cacheKey: "variant-a"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
response = http.request(request)
puts response.bodyPHP Microlink API example
<?php
$baseUrl = "https://api.microlink.io/";
$params = [
"url" => "https://microlink.io",
"screenshot" => "true",
"cacheKey" => "variant-a"
];
$query = http_build_query($params);
$url = $baseUrl . '?' . $query;
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET"
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #: " . $err;
} else {
echo $response;
}Golang Microlink API example
package main
import (
"fmt"
"net/http"
"net/url"
"io"
)
func main() {
baseURL := "https://api.microlink.io"
u, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
q := u.Query()
q.Set("url", "https://microlink.io")
q.Set("screenshot", "true")
q.Set("cacheKey", "variant-a")
u.RawQuery = q.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
panic(err)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
screenshot: true,
cacheKey: "variant-a"
})cacheKey values produce separate cache entries.# Two separate cache entries despite identical parameters
https://pro.microlink.io?url=https://example.com&screenshot=true&cacheKey=variant-a
https://pro.microlink.io?url=https://example.com&screenshot=true&cacheKey=variant-bBypassing the cache
force: true to skip the cache entirely and get a fresh response:The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://microlink.io' URL with 'force' API parameter:
CLI Microlink API example
microlink https://microlink.io&forcecURL Microlink API example
curl -G "https://api.microlink.io" \
-d "url=https://microlink.io" \
-d "force=true"JavaScript Microlink API example
import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
force: true
})Python Microlink API example
import requests
url = "https://api.microlink.io/"
querystring = {
"url": "https://microlink.io",
"force": "true"
}
response = requests.get(url, params=querystring)
print(response.json())Ruby Microlink API example
require 'uri'
require 'net/http'
base_url = "https://api.microlink.io/"
params = {
url: "https://microlink.io",
force: "true"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
response = http.request(request)
puts response.bodyPHP Microlink API example
<?php
$baseUrl = "https://api.microlink.io/";
$params = [
"url" => "https://microlink.io",
"force" => "true"
];
$query = http_build_query($params);
$url = $baseUrl . '?' . $query;
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET"
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #: " . $err;
} else {
echo $response;
}Golang Microlink API example
package main
import (
"fmt"
"net/http"
"net/url"
"io"
)
func main() {
baseURL := "https://api.microlink.io"
u, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
q := u.Query()
q.Set("url", "https://microlink.io")
q.Set("force", "true")
u.RawQuery = q.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
panic(err)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}import mql from '@microlink/mql'
const { data } = await mql('https://microlink.io', {
force: true
})x-cache-status will be BYPASS. Use sparingly — this always triggers a fresh request.Verify caching behavior
| Header | What it tells you |
|---|---|
x-cache-status | HIT (served from cache), MISS (fresh), or BYPASS (forced) |
x-cache-ttl | The effective cache lifetime in milliseconds |
cf-cache-status | CloudFlare edge cache status |
x-response-time | Total request duration — fast times usually indicate a cache hit |