Memory Cache

Memory Cache

RawCull uses a smart 3-step cache to keep browsing fast and reduce repeated work when viewing RAW files. In simple terms: RawCull tries the fastest location first (memory), then disk, and only decodes from the original RAW file when needed.

Why this matters

Decoding RAW files is expensive.
Caching helps RawCull:

  • show thumbnails faster
  • reduce stutter while browsing
  • avoid decoding the same file again and again
  • keep performance stable during large photo sessions

The 3 cache layers (fastest to slowest)

  1. Memory cache (RAM)
    Fastest. Recently used thumbnails are kept in memory for instant access.

  2. Disk cache
    If a thumbnail is no longer in RAM, RawCull checks its disk cache.

  3. Source decode (RAW file)
    If not found in RAM or disk, RawCull decodes from the original RAW file and then stores the result for next time.


What happens when a thumbnail is requested

RawCull follows this sequence:

  1. Check memory cache
  2. If not found, check disk cache
  3. If still not found, decode from RAW
  4. Save the result back into cache so the next request is faster

This same logic is used in both:

  • bulk thumbnail generation
  • on-demand thumbnail loading while you browse

Grid view is optimized separately

Grid view needs many small thumbnails quickly, so RawCull uses a dedicated in-memory grid cache for that case.

  • Grid thumbnails are kept at about 200 px
  • This grid cache is separate from the larger preview/zoom cache
  • This keeps browsing smooth without pushing out larger preview images too aggressively

Memory pressure behavior (automatic safety)

When macOS signals memory pressure, RawCull automatically reacts:

  • Normal: stays at configured limits
  • Warning: reduces cache limits
  • Critical: clears in-memory cache aggressively to protect system stability

This helps prevent system slowdowns or memory-related crashes when resources are tight.


Cache statistics and maintenance

RawCull tracks cache behavior internally (hits, misses, evictions) so performance can be monitored.

You can also clear caches when needed. Clearing will remove:

  • in-memory thumbnail cache
  • grid cache
  • disk thumbnail cache

Use this if you want a clean rebuild (for example after major setting changes or troubleshooting).


Settings reference

These settings influence cache behavior:

  • memoryCacheSizeMB (default: 10000)
    Max size for the main in-memory thumbnail cache

  • gridCacheSizeMB (default: 400)
    Max size for the grid thumbnail memory cache

  • thumbnailCostPerPixel (default: 6)
    Internal cost value used for cache budgeting

  • thumbnailSizePreview (default: 1616)
    Target size used for preview-oriented thumbnail generation

  • thumbnailSizeGrid (default: 200)
    Grid thumbnail size target

  • thumbnailSizeFullSize (default: 8700)
    Upper bound for full-size viewing path

Settings are stored in: ~/Library/Application Support/RawCull/settings.json


Visual flow: thumbnail loading

flowchart TD
    A[Thumbnail Requested] --> Z{targetSize ≤ 200?}
    Z -- Yes --> ZA{gridThumbnailCache Hit?}
    ZA -- Yes --> ZB[Return NSImage — fast path]
    ZA -- No --> B
    Z -- No --> B
    B{memoryCache Hit?}
    B -- Yes --> C[beginContentAccess]
    C --> D[Return NSImage]
    D --> E[endContentAccess]
    B -- No --> F{Disk Cache Hit?}
    F -- Yes --> G[Load JPEG from Disk]
    G --> H[Wrap as DiscardableThumbnail]
    H --> I[Store in memoryCache with cost]
    I --> I2[storeInGridCache — downscale to 200 px]
    I2 --> D
    F -- No --> J[SonyThumbnailExtractor]
    J --> K[Normalize NSImage]
    K --> L[storeInMemoryCache]
    L --> L2[storeInGridCache — downscale to 200 px]
    L2 --> D
    K --> M[Encode JPEG data]
    M --> N[DiskCacheManager.save — detached background]

Visual flow: memory pressure response

flowchart TD
    A[DispatchSourceMemoryPressure event] --> B{Pressure Level?}
    B -- normal --> C[Log + update currentPressureLevel]
    C --> CC[refreshConfig]
    CC --> D[Notify UI: no warning]
    B -- warning --> E[memoryCache limit → 60% of current]
    E --> E2[gridThumbnailCache limit → 60% of current]
    E2 --> F[Notify UI: warning]
    B -- critical --> G[memoryCache.removeAllObjects]
    G --> G2[gridThumbnailCache.removeAllObjects]
    G2 --> H[memoryCache limit → 50 MB]
    H --> I[Notify UI: warning]

Last modified April 25, 2026: Some updates (045d532)