> For the complete documentation index, see [llms.txt](https://docs.k9.io/key9-identity/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.k9.io/key9-identity/maxmind-api-proxy/caching/overview.md).

# How Caching Works

`maxmind-api-proxy` uses Redis as a look-aside cache to avoid querying MaxMind for IPs that have been seen recently. This is the primary mechanism for reducing API costs.

***

## Cache flow

```
Incoming request for IP X
         │
         ▼
  Redis GET geoip:X
         │
    ┌────┴────┐
   HIT       MISS
    │           │
    │      Query MaxMind for X
    │           │
    │      Redis SET geoip:X  (TTL = redis_cache_time hours)
    │           │
    └────┬──────┘
         │
    Return JSON to client
```

On a **cache hit** the response is returned immediately from Redis without any network call to MaxMind.

On a **cache miss** the proxy queries MaxMind, stores the response in Redis under the key `geoip:<ip_address>`, and returns the result.

***

## Cache keys

Each IP address is stored under the key `geoip:<ip_address>`:

```
geoip:8.8.8.8
geoip:2001:4860:4860::8888
```

IPv4 and IPv6 addresses are treated as distinct keys.

***

## Cache TTL

The `redis_cache_time` config value sets how long, **in hours**, a cached entry lives before Redis automatically expires it:

```json
{
  "redis_cache_time": 24
}
```

After the TTL expires, the next query for that IP becomes a cache miss and hits MaxMind again. There is no proactive cache invalidation — entries only expire via the Redis TTL mechanism.

Choose a TTL that balances cost savings against data freshness. MaxMind updates its databases periodically; a 24-hour TTL is a reasonable default for most use cases. For rapidly changing datasets (e.g. hosting/VPN detection) a shorter TTL may be appropriate.

***

## Caching error responses

The `cache_errors` config field controls whether MaxMind error responses are cached:

```json
{
  "cache_errors": false
}
```

| Value                 | Behaviour                                                                                                                                          |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `false` (recommended) | Error responses from MaxMind (those containing an `"error"` field) are **not** stored in Redis. The next query for that IP will hit MaxMind again. |
| `true`                | Error responses are cached like any other response. Subsequent queries for the same IP return the cached error until the TTL expires.              |

`cache_errors: false` is safer because it prevents a transient MaxMind error (e.g. a temporary outage or rate limit) from being replayed to clients for hours. Use `cache_errors: true` only if you explicitly want to suppress repeated calls for IPs that are legitimately not in MaxMind's database.

***

## Inspecting the cache

You can inspect cached entries directly with `redis-cli`:

```bash
# Connect to Redis
redis-cli -h 127.0.0.1 -p 6379 -a your_redis_password

# Check if an IP is cached
EXISTS geoip:8.8.8.8

# View the cached data
GET geoip:8.8.8.8

# Check the remaining TTL (in seconds)
TTL geoip:8.8.8.8

# Manually evict a specific IP
DEL geoip:8.8.8.8

# Count all cached entries
KEYS geoip:* | wc -l
```

***

## Cache statistics

When `http_mode` is not `production`, the proxy logs cache statistics after every request:

```
[ Total Queries: 42 | Cached: 35 [83.3%] | Not Cached: 7 [16.7%] - 8.8.8.8 pull from cache.
```

| Field         | Description                                                      |
| ------------- | ---------------------------------------------------------------- |
| Total Queries | Total number of lookup requests handled since the proxy started. |
| Cached        | Requests served from Redis.                                      |
| Not Cached    | Requests that required a MaxMind query.                          |
| Percentage    | Running hit/miss rate since startup.                             |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.k9.io/key9-identity/maxmind-api-proxy/caching/overview.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
