agentsclimarketplace

Firefly cost optimization

Skill Focus-GTS/firefly-services-skills/plugins/firefly-services/skills/firefly-cost-optimization

Production-grade Claude Code skills for Adobe Firefly Services — credentials, generation (V3 async), custom models, expand/fill, video, Photoshop API, Lightroom API. Built by FocusGTS from real enterprise FDE work.

Install
npx -y skills add Focus-GTS/firefly-services-skills --skill firefly-cost-optimization

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

The production playbook for understanding and controlling Adobe Firefly Services consumption — where API spend actually goes, what to cache, what to batch, seed reuse for deterministic regenerations, prompt deduplication, response caching, custom-model-vs-style-reference cost tradeoff, and the "why is consumption 3× higher than expected" debugging sequence. Use whenever the user mentions "cost", "consumption", "API spend", "budget", "billing surprise", "consumption is high", "credits burning fast", "FinOps", "cost overrun", or wants to understand the cost shape of a generative pipeline before deploying it. Encodes the FinOps pattern that keeps generative pipelines on budget at scale.

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

16.3 KB, as published. Nobody here has run it

Firefly Cost Optimization

The FinOps playbook for Firefly Services. Every FDE engagement eventually gets the question: "why is consumption 3× what we forecast?" The answer is almost always one of six causes, all of which are preventable with the patterns below.

This skill encodes how to think about Firefly cost: where it actually goes, what knobs reduce it, what the cost shape of each endpoint looks like, and the debugging sequence that resolves a consumption surprise in hours instead of weeks.

When to Use This Skill

Use this skill when:

  • The user mentions "cost", "consumption", "credits", "API spend", "billing", "budget"
  • Consumption is running ahead of forecast and you need to debug why
  • A new pipeline is about to ship and the customer wants a cost forecast
  • The architect is choosing between two patterns and cost is the tiebreaker (custom model vs style reference, generate vs cache, base vs custom model)
  • The customer is renewing their Firefly enterprise contract and needs consumption justification

Do NOT use this skill when:

  • The workload is low-volume interactive (a designer using the app) — cost optimization is premature
  • The customer's spend is on Firefly-the-app (creative cloud subscription), not Firefly Services API — different cost model

Where Cost Actually Goes — The Five Buckets

API consumption breaks down into five buckets. Memorize the order — it tells you where to look first when consumption is high.

BucketTypical share of spendWhat drives it
1. Base generation calls50-70%One credit per output image; volume × variants
2. Retry storms5-25% (variable)Retries that should have been client-side fixes; the #1 surprise
3. Custom model training5-15%One-time per model; amortized across the model's lifetime
4. Photoshop / Lightroom operations5-15%Usually metered differently; check the enterprise agreement
5. Storage and bandwidth1-5%S3 / equivalent; usually a rounding error compared to generation

Bucket 2 is the variable. A healthy pipeline runs at 5%. A pipeline with bad retry logic and duplicate-generation bugs runs at 25%. The gap is the gap between forecast and reality.

Step 1 — Forecast Before You Build

Before any pipeline ships, forecast consumption. The formula:

monthly_credits = (
  active_campaigns_per_month *
  jobs_per_campaign *
  variants_per_job *
  aspects_per_variant
) * (1 + retry_overhead_pct) * (1 + rejection_overhead_pct)
VariableHealthy valueSurprise value
variants_per_job2-410+ (designers exploring without batching)
aspects_per_variant3-6 (per platform)12+ (rendering for every conceivable surface)
retry_overhead_pct5%30% (bad retry logic; see §3)
rejection_overhead_pct10%30% (low custom-model quality; see firefly-brand-guardrails)

Multiply the surprise values across the formula and you arrive at the 3-5× overrun that real pipelines hit. The forecast is a contract: the build team signs up for it, the FinOps team alarms when actual exceeds it.

Step 2 — Caching: The Highest-Leverage Lever

Three caches matter, in order of impact:

Cache 1: Prompt deduplication (per-campaign)

In a single campaign run, the same prompt is often submitted multiple times — by different upstream systems, retry logic, or accidental duplicates. A prompt-deduplication cache keyed on (promptHash, modelId, seed, parameters) returns the prior output without calling Firefly.

const cacheKey = sha256(JSON.stringify({
  prompt: req.prompt,
  customModelId: req.customModelId,
  seed: req.seed,
  size: req.size,
  contentClass: req.contentClass,
  styleReference: req.style?.imageReference?.source?.uploadId,
  structureReference: req.structure?.imageReference?.source?.uploadId,
}));

const cached = await ddb.get({ TableName: 'firefly-prompt-cache', Key: { cacheKey } });
if (cached.Item) return cached.Item.outputUrls;

const result = await firefly.generate(req);
await ddb.put({ TableName: 'firefly-prompt-cache', Item: {
  cacheKey, outputUrls: result.outputs.map(o => o.image.url), ttl: ...
}});
return result.outputs.map(o => o.image.url);

Cache TTL: align with the validity of the Firefly output URLs. Typically 24 hours, though re-hosting outputs in your own bucket lets you cache indefinitely.

Typical hit rate: 5-15% on a campaign run, climbing to 25%+ in batch-driven workflows where duplicate prompts are common.

Cache 2: Token cache (per-credential)

The IMS token cache is covered in firefly-services-auth. It is not a cost lever directly, but a broken token cache means re-auth on every call, which can hammer rate limits and cause retry storms (which are a cost lever).

Token cache hit ratio < 99% means refresh logic is broken — fix before optimizing anything else.

Cache 3: Asset cache (post-generation)

Outputs cached in your own S3 (instead of re-fetching from Adobe's temporary URLs) saves bandwidth and avoids URL-expiry retries. Always re-host generated assets immediately.

Step 3 — Retry Storms: The #1 Cost Surprise

A retry storm happens when the pipeline retries calls that should not be retried. Patterns:

Anti-patternCost impact
Retry on 422 (content rejection)Burns credits on guaranteed failures
Retry on 403 (entitlement)Burns credits + alerts noise
Retry on 400312 (expired storage ref) without regenerating the refSame call fails again; infinite loop until DLQ
Unbounded retry attemptsOne bad input runs forever
Missing idempotency keyUpstream retries cause duplicate generations
Step Functions retry + Lambda retry + SQS retry3 layers of retry = 27× the original calls

The retry classification table from firefly-services-rate-limits §5 is the canonical reference. The cost-specific extension:

FailureCost-optimal action
429Retry with Retry-After honoring — these will succeed
500-504Retry up to 3 times — typically succeed
422 (content)Never retry — surface to user; let them fix the prompt
403 (entitlement)Never retry — alert ops
400312 (storage expired)Regenerate ref then retry once
404 (custom model retired)Never retry — surface to user
Network timeoutRetry once with longer timeout

Audit one week of DLQ contents. Any class that should not have been retried but was, multiplied by the average retry count, equals your retry-storm overhead.

Step 4 — Seed Reuse for Deterministic Regeneration

The seed parameter on Generate Image lets you reproduce an exact output. For cost control, this matters in two scenarios:

ScenarioPattern
Design iteration ("almost right — generate again with this small tweak")Pass the original seed; tweak only the prompt fragment that changed. Result is much closer to the original.
Reproducibility for legal/auditStore the seed with every generated asset; can regenerate the exact same pixels months later if challenged

Without seed reuse, "make it slightly different" requires generating multiple new variants and picking. With seed reuse, one targeted generation often suffices.

{
  "prompt": "an icon of a key, brand-light style",
  "customModelId": "...",
  "seed": [42],
  "size": {"width": 1024, "height": 1024}
}

Store the seed alongside every output asset in DynamoDB. When designers want a variation, the UI surfaces "regenerate with tweak" using the original seed.

Step 5 — Custom Model vs Style Reference: The Cost Tradeoff

Both produce on-brand output. The cost shapes are different.

LeverUp-front costPer-generation costBest for
Custom model1 model training (hours, low credits)1 credit per generation (same as base)High-volume brand-consistent output; iconography; product subject
Style reference$01 credit + bandwidth/storage for the referenceLow-volume / one-off brand-styled output; rapid prototyping
Structure reference$01 credit + bandwidth/storage for the referenceComposition control independent of style

Break-even math: a custom model amortizes once you exceed ~hundreds of generations against the same style. Below that, style references are cheaper. Above that, the model wins — and as a bonus, the model is faster (no reference upload per call) and more consistent than reference-only.

Workflow shapeRecommendation
Designer exploring a new brand styleStyle reference; don't train a model yet
Brand has landed; campaigns runningTrain custom model; deprecate references
One-off creative testStyle reference; never train
Multi-customer SaaS with shared styleCustom model per customer (do not share)

See firefly-custom-models for the full lifecycle.

Step 6 — Right-Sizing Variants and Aspects

The variants and aspects multiply through every campaign. Be deliberate:

KnobCost-optimal defaultSurprise default
numVariations per generate call1 (also the API default), regenerate if not satisfiedExplicitly raising to 4+ burns 4× the credits per request
Aspect ratios per asset3 (one per major platform)8+ (every conceivable cut)
Resolution1024×1024 standard; upscale on demandAlways max resolution
Style + structure refsUse when neededAlways set, even when not needed (slows generation but not cost)

The single highest-impact change: keep numVariations at 1 (the API default). A request generates 1 image unless numVariations is explicitly raised. Designers can request more if they need them — but watch for code or UI that quietly sets it to 4, which burns 4× the credits before anyone notices.

Step 7 — The "Consumption is 3× Forecast" Debugging Sequence

When a customer reports overrun, work this sequence in order. Stop when you find the cause — usually one of the first three.

1. Check the retry rate

Query metrics for the past week:

MetricHealthyConcerning
429 rate< 1%> 5%
5xx retry rate< 2%> 10%
DLQ depth (current)0> 0 sustained
Average retries per success1.05> 1.3

Above the "concerning" thresholds, retry storm is the answer. Audit DLQ classification (§3).

2. Check for duplicate generations

In the job ledger, GROUP BY promptHash + customModelId + seed. If the same key has multiple succeeded jobs, idempotency is broken upstream.

-- Athena over the job ledger
SELECT promptHash, customModelId, seed, COUNT(*) as duplicate_count
FROM firefly_job_ledger
WHERE status = 'succeeded' AND createdAt > now() - INTERVAL '7' DAY
GROUP BY promptHash, customModelId, seed
HAVING COUNT(*) > 1
ORDER BY duplicate_count DESC LIMIT 100;

Duplicates × credits-per-duplicate = duplicate-generation overhead. Fix by enforcing idempotency keys at intake (see firefly-batch-pipeline §1).

3. Check variant and aspect counts

Audit the actual numVariations and aspect-count distributions across recent jobs. If numVariations >= 4 is the modal value, switch to default 1 and watch consumption drop.

4. Check rejection rate

If the human review queue (see firefly-brand-guardrails) is rejecting > 20% of output, the model or prompts are off-brand and the pipeline is regenerating to compensate. Retrain or tighten deny-lists.

5. Check for cache miss rate

Prompt deduplication cache hit rate should be in the 5-15% range. Below 5% means either the cache is broken (check TTLs and key construction), or the workload genuinely has no duplicates (which is fine).

6. Check for unused custom models

Models that were trained for an exploration and never retired still incur training charges. Audit the model registry quarterly; delete models that have not been called in 60 days.

Step 8 — Cost Observability — Dashboards to Build

DashboardMetricAlert when
Per-campaign burnCredits/hour, plotted against forecastActual > 150% of forecast for 1 hour
Per-credential burnCredits/day per client_idTop credential > 2× the next
Retry overhead(Total calls − unique jobs × 1) / unique jobs> 10%
Duplicate rateJobs / unique (promptHash, modelId, seed)> 1.05
Cache hit rateCache hits / total prompts< 5% for 7 days (cache may be broken)
Rejection rateRejected reviews / total reviews> 20%
Unused model countModels with 0 calls in 60 days> 5

Per-customer cost allocation uses S3 object tags (see firefly-batch-pipeline §6). Roll up to a daily / weekly / monthly customer invoice.

Validate

The cost layer is production-ready when:

  1. Every campaign has a documented monthly forecast and an alarm at 150% of forecast
  2. The retry-rate and duplicate-rate metrics are dashboarded with alarms
  3. Idempotency keys are enforced at intake (no duplicate generations from upstream retries)
  4. Prompt-dedup cache exists with measured hit rate
  5. The DLQ classification rules in §3 are wired (no retry on 422 / 403 / 404)
  6. numVariations defaults to 1; designers opt in to more
  7. Custom-model registry is audited quarterly; unused models are deleted
  8. The 7 dashboards above exist

Troubleshooting & Edge Cases

  • Forecast looks healthy but invoices are 2× expected: The forecast omitted a category. Check Photoshop / Lightroom / Custom Model training charges — they bill separately and are often missed.
  • One credential burning 5× the others: Either one customer is doing legitimate high-volume work, or one credential leaked and is being abused. Rotate and audit.
  • Cache hit rate dropped after a deploy: Cache key construction broke — a new parameter changes the hash. Audit cache key vs request shape.
  • Retry overhead climbed without a code change: Firefly-side incident is in progress. Check the Adobe status page; throttle the pipeline until it clears.
  • Custom-model generation is consistently slow + expensive: The model is poorly trained; high seed-to-seed variance forces designers to regenerate. Retrain with better data.
  • Reviewers reject everything from a new template: Template is off-brand. Pull from production; iterate; do not just "regenerate until it lands" — every regeneration burns credits.
  • Bandwidth charges from re-fetching Firefly outputs: Outputs are at temporary URLs that expire. Re-host in your bucket immediately after generation success.

Chaining with Other Skills

  • firefly-services-rate-limits — Retry classification is the cost-burn cornerstone
  • firefly-batch-pipeline — Idempotency, job ledger, and observability live there
  • firefly-brand-guardrails — Rejection rate is a direct cost driver
  • firefly-custom-models — Cost vs style-reference tradeoff
  • firefly-services-auth — Token cache health affects retry rate
  • firefly-services-troubleshoot — When a single failure mode dominates burn

References

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.