You have correctly identified the fundamental mismatch. Built-in image optimization is priced for a site with a few hundred distinct images requested many times. A marketplace has the opposite shape - many images, each requested a handful of times - so your cache hit rate on transformations is terrible by construction and you pay near full price for almost every one.
Three things, in order of effort:
Cut the variant count. Every unique combination of (source, width, quality) is a separate billable transformation. Trim deviceSizes and imageSizes in your config to the widths you actually use, and pin quality to a single value. Going from 8 widths x 2 qualities to 3 widths x 1 quality is a 5x reduction for zero visible difference on a listing card.
Raise the cache TTL. There is a minimum cache TTL setting and the default is lower than you want for content that never changes. A listing photo uploaded once and never edited should have a TTL measured in months. If the cached transform expires, the next request pays for it again.
Transform at upload, not at request. This is the real answer for UGC. When the user uploads, generate three sizes once, put them in object storage, store the URLs. Then serve them as plain images with unoptimized set. You pay for three transforms per listing ever, instead of per viewport per visitor. For 9,000 listings that is 27,000 operations total, once.