Skip to content

The file index#

What is indexed#

One row per file under uploads:

Column
path Relative to the uploads folder
attachment_id The attachment the file belongs to, 0 for files no attachment owns
size full, original (the unscaled upload behind a -scaled file), a registered size name, backup-<size> (image-editor backups) or unattached
present The file exists on disk
width, height From the file itself, or from the attachment metadata
bytes, mtime From the file
hash SHA-1 of the content (new uploads, wp bb-media hash)
variants WebP/AVIF copies found next to the file

An attachment's files come from WordPress's own data: _wp_attached_file, the sizes and original_image in _wp_attachment_metadata, and _wp_attachment_backup_sizes. Files no attachment owns are found by scanning uploads; plugin working folders are skipped (custom-css-js, bb-migrate, wp-migrate-db, smush, woocommerce_uploads and others; filter bb_media_skip_dirs).

When two attachments name the same file, the lower ID owns it, as WordPress's own lookups return. When that attachment is deleted, the other one takes the file over.

Keeping it current#

Changes are applied at the end of the request that made them, once per attachment:

Event
Upload, regenerated sizes wp_generate_attachment_metadata
Edited image, metadata saved wp_update_attachment_metadata
File or backups changed, Smush compressed a file the _wp_attached_file, _wp_attachment_backup_sizes and wp-smpro-smush-data meta
Attachment deleted delete_attachment (its rows go at once)
BB Migrate pushed a file bb_migrate_file_changed, when BB Media is loaded in that request

Changes made outside WordPress (SFTP, a database import) are found by wp bb-media verify --fix.

Lookups#

$r = bb_media_lookup( $url_or_path );
// [ 'attachment_id' => 15540, 'size' => 'full', 'path' => '2026/06/cost-value-preview.png', 'url' => '…',
//   'present' => true, 'width' => 1080, 'height' => 1080, 'bytes' => 412377, 'hash' => '…', 'mime' => 'image/png',
//   'variants' => [ 'webp' => [ 'path' => '….png.webp', 'bytes' => 61234 ] ] ]

Any form of an uploads URL works: absolute (http or https), scheme-less, root-relative (/wp-content/uploads/…), with a query string or %-escapes, as well as absolute paths and paths relative to uploads. Theme files, other hosts and paths with .. return null. Each lookup is one indexed query, remembered for the request.

BB Cache#

With BB Media active, BB Cache asks it first and keeps its own method as the fallback:

  • srcset: the attachment of an image without a srcset. Root-relative image URLs, which BB Cache's own lookup never matched, now get one too.
  • width and height for images without them, from the index instead of reading the file.
  • WebP: which copy exists, without disk checks or BB Cache's day-long memory.