Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ ENV DOMAIN=localhost \
SIDECAR_CACHE_ENABLED="true" \
SIDECAR_CACHE_DIR="/data/ipfs/sidecar-cache" \
SIDECAR_CACHE_MAX_BYTES="1073741824" \
SIDECAR_CACHE_MAX_ENTRIES="10000" \
SIDECAR_CACHE_MAX_ENTRIES="100000" \
SIDECAR_CACHE_MAX_BLOB_BYTES="33554432" \
SIDECAR_CACHE_RECONCILE_INTERVAL="5" \
SIDECAR_CACHE_PROMOTION_TIMEOUT="86400" \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ sphere-sdk integration tests (see issue
| `SIDECAR_CACHE_ENABLED` | `true` | Kill switch — set to `false` to skip schema migration and disable all `/sidecar/*` endpoints |
| `SIDECAR_CACHE_DIR` | `/data/ipfs/sidecar-cache` | Directory for blob bytes (auto-created) |
| `SIDECAR_CACHE_MAX_BYTES` | `1073741824` (1 GiB) | Total cache budget across pending + in-kubo rows |
| `SIDECAR_CACHE_MAX_ENTRIES` | `10000` | Entry cap (whichever cap hits first) |
| `SIDECAR_CACHE_MAX_ENTRIES` | `100000` | Entry cap (whichever cap hits first) |
| `SIDECAR_CACHE_MAX_BLOB_BYTES` | `33554432` (32 MiB) | Per-submission size limit; oversize returns HTTP 413 |
| `SIDECAR_CACHE_RECONCILE_INTERVAL` | `5` | Seconds between reconciler iterations |
| `SIDECAR_CACHE_PROMOTION_TIMEOUT` | `86400` (24 h) | Pending rows older than this trigger operator WARN logs (never silently aged out) |
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ services:
- SIDECAR_CACHE_ENABLED=${SIDECAR_CACHE_ENABLED:-true}
- SIDECAR_CACHE_DIR=${SIDECAR_CACHE_DIR:-/data/ipfs/sidecar-cache}
- SIDECAR_CACHE_MAX_BYTES=${SIDECAR_CACHE_MAX_BYTES:-1073741824}
- SIDECAR_CACHE_MAX_ENTRIES=${SIDECAR_CACHE_MAX_ENTRIES:-10000}
- SIDECAR_CACHE_MAX_ENTRIES=${SIDECAR_CACHE_MAX_ENTRIES:-100000}
- SIDECAR_CACHE_MAX_BLOB_BYTES=${SIDECAR_CACHE_MAX_BLOB_BYTES:-33554432}
- SIDECAR_CACHE_RECONCILE_INTERVAL=${SIDECAR_CACHE_RECONCILE_INTERVAL:-5}
- SIDECAR_CACHE_PROMOTION_TIMEOUT=${SIDECAR_CACHE_PROMOTION_TIMEOUT:-86400}
Expand Down
4 changes: 2 additions & 2 deletions nostr-pinner/instant_pin_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
Capacity / back-pressure
------------------------
The cache is bounded by total bytes (SIDECAR_CACHE_MAX_BYTES, default 1 GiB)
AND entry count (SIDECAR_CACHE_MAX_ENTRIES, default 10_000). When full:
AND entry count (SIDECAR_CACHE_MAX_ENTRIES, default 100_000). When full:

* If there is room to evict already-confirmed (`in-kubo`) entries, evict LRU.
* If only `pending` entries remain, refuse the new submit with HTTP 503 so
Expand Down Expand Up @@ -58,7 +58,7 @@

DEFAULT_CACHE_DIR = "/data/ipfs/sidecar-cache"
DEFAULT_MAX_BYTES = 1 * 1024 * 1024 * 1024 # 1 GiB
DEFAULT_MAX_ENTRIES = 10_000
DEFAULT_MAX_ENTRIES = 100_000
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Bumping DEFAULT_MAX_ENTRIES to 100_000 introduces potential performance and memory bottlenecks in the cache eviction logic under load:

  1. Memory Footprint in Eviction: In _make_room_for (lines 371-376), the query SELECT cid, byte_size FROM instant_pin_cache WHERE state = 'in-kubo' ORDER BY last_accessed_at ASC is executed, and cursor.fetchall() is used to load all candidates into memory. With up to 100,000 entries, this can fetch tens of thousands of rows into memory on the write path, causing latency spikes and high memory usage.
  2. Database Query Performance: The query filters by state and orders by last_accessed_at. Without a composite index on (state, last_accessed_at), SQLite may perform a full table scan or filesort, which becomes significantly slower as the table grows to 100,000 rows.

Recommendations for future improvements:

  • Batch Eviction / Limit Query: Limit the SELECT query in _make_room_for using a LIMIT clause (e.g., only fetch the oldest N entries to evict, or evict in batches).
  • Composite Index: Add a composite index on (state, last_accessed_at) in init_instant_pin_cache_schema to optimize the eviction query.

DEFAULT_RECONCILE_INTERVAL = 5 # seconds
DEFAULT_PROMOTION_TIMEOUT = 24 * 60 * 60 # 24h alert threshold
DEFAULT_KUBO_PIN_TIMEOUT = 30 # seconds; per-promotion call cap
Expand Down