The Trinity Beast — Translation Parameters

All 45 runtime parameters that govern the Translation Engine, and what each one actually decides — Bedrock token rates, token and duration estimation, spend controls, and customer pricing. Learn these and you can reprice or retune the whole service without touching a line of code.

Parameters: 45 Categories: 4 Storage: Aurora translation_parameters Cache: Valkey tx:params (27-hour TTL) Updated: October 10, 2026 Version: v22

Table of Contents

  1. Overview
  2. How Parameters Work
  3. The Cost Formula
  4. Parameter Categories
    1. Bedrock Pricing
    2. Token Estimation
    3. Cost Controls
    4. Customer Pricing
    5. Refund Rules
  5. Managing Parameters
  6. Nightly Sync Job
  7. Complete Parameter Reference

List of Diagrams

Overview

Translation parameters control every cost, pricing, and operational aspect of the Translation Engine (TBTS). They are stored in the translation_parameters Aurora table — the authoritative source — and cached in Valkey as the tx:params hash for fast reads by ECS containers and Lambda workers.

  • Separate from application parameters: Translation is a standalone service with its own cost model. These parameters live in translation_parameters, not application_parameters. This prevents a bad translation config change from affecting the LPO server, and vice versa.
  • Startup: ECS containers load tx:params from Valkey on startup. Lambda workers load it on cold start.
  • Polling: Containers read from Valkey on demand. The sync job refreshes the cache nightly with a 27-hour TTL — always available between sync runs.
  • Write-through: Any update via the admin API writes to Aurora and Valkey simultaneously. In-memory values on the responding container update immediately.
  • Nightly sync: The sync job re-syncs all parameters from Aurora to Valkey each night, ensuring consistency after any direct Aurora edits.
  • Rates that keep themselves current: before that copy, the same job reads every model's Bedrock token rates from the public AWS Price List and writes any change to Aurora, so nobody has to notice an AWS price change by hand (see Nightly Sync Job).
  • Force reload: POST /admin/translate/params/reload flushes Valkey and reloads from Aurora immediately. All containers pick up changes on their next read.

Important: The legacy Valkey keys translation:rate:{model}:input and translation:rate:{model}:output are superseded by tx:params. The app:config keys translation_markup_pct and translation_infra_per_pair are also superseded. All translation cost logic now reads exclusively from tx:params. The legacy keys are retained for backward compatibility only.

How Parameters Work

-- Aurora: authoritative source
SELECT key, value, description, category, updated_at, updated_by
FROM translation_parameters
ORDER BY category, key;

-- Valkey: fast cache (tx:params hash, 27-hour TTL)
HGETALL tx:params

-- Update a parameter (applies immediately to Aurora + Valkey + in-memory)
POST /admin/translate/params
{"key": "pricing.markup_pct", "value": "30", "updated_by": "cory"}

-- Force all containers to reload from Aurora
POST /admin/translate/params/reload

-- View parameters in the TBI Administration dashboard
Translation tab → Translation Parameters section

Fallback Chain

Every parameter accessor follows a three-level fallback to ensure the system never returns zero for a cost value:

  1. Valkey tx:params hash — fast path, ~0.1ms, refreshed nightly by sync job (27-hour TTL)
  2. Aurora translation_parameters table — authoritative source, ~5ms, used when Valkey is unavailable
  3. Hardcoded defaults — safe floor values matching the seed data, used only if both Aurora and Valkey are unreachable

The Cost Formula

The Translation Engine tracks every token at the most granular level Bedrock reports. The ground-truth cost calculation for any translation job is:

BedrockCostForTokens — the single source of truth for all cost calculations:

cost = (uncached_input_tokens  × input_rate_per_token)
     + (cached_tokens          × cache_read_rate_per_token)   ← 90% cheaper than input
     + (cache_write_tokens     × cache_write_rate_per_token)  ← one-time per cache population
     + (output_tokens          × output_rate_per_token)

Where uncached_input = total_input - cached_tokens. This formula is used everywhere actual cost is recorded — finalize Lambda, SQS cost messages, Aurora bedrock_cost_usd column, and the daily spend counter in Valkey.

Customer Price Formula

Here is the thing to understand before you read a single line of the formula below: customers pay a true flat 3.00 USD per document-language pair. For every model except Claude Opus 4.8, the cost-plus calculation below no longer runs at all — the flat 3.00 USD rate is applied directly, per pair. The formula survives for exactly one agent: Claude Opus 4.8, where cost-plus runs with 3.00 USD as a floor, so a large Opus document can price above it and is advertised as "From 3.00". So the formula is real, but only Opus ever exercises it; everything else is a flat rate.

That is a deliberate design choice worth appreciating rather than a rounding convenience. A cost-plus price on a small document produces a quote of a few cents, and a few cents cannot carry a Stripe fee, a confirmation email, and a support conversation. Pricing on the floor gives the customer something far more valuable than precision: a number they can predict before they ask. Nine documents into three languages is 27 pairs, so 81.00 USD, and they can work that out themselves without a quote call.

infra       = InfraCostForJob(translatable_bytes_per_doc, num_languages)
subtotal    = total_bedrock_cost + infra
service_fee = subtotal × (pricing.markup_pct / 100)
total       = subtotal + service_fee

total_pairs = doc_count × language_count
pair_floor  = pricing.minimum_per_pair_usd × total_pairs

final       = max(total, pair_floor, pricing.minimum_quote_usd)

That formula now executes on a single path — Claude Opus 4.8 — and its last line is where the money is decided there: three candidates compete and the largest wins, so the cost-based total takes the price only when it beats the 3.00 USD per-pair floor. Opus 4.8 bills 5.50 USD per million input tokens and 27.50 USD per million output tokens, the highest rates in the table and about 1.7 times Sonnet 4.6, so it is the one model whose token bill can climb past the floor, on documents above about 200 KB. For every other agent there is no competition to resolve: the price is 3.00 USD per pair, full stop.

What this looks like in the ledger. Measured across every recorded job, average Bedrock cost per pair by model: Sonnet 4.6 0.67 USD, Haiku 0.16 USD, DeepSeek V3 0.12 USD, Mistral Large 0.05 USD, Qwen3 235B 0.02 USD. Add infrastructure and a 30% markup and the highest of those is still comfortably under 1.00 USD, against a 3.00 USD floor. That gap is not a mistake to be tuned away — it is the margin that funds the mission, and it is why the price stays simple.

Two floors exist rather than one, and the distinction matters when you are reading a quote. pricing.minimum_per_pair_usd scales with the work — it is 3.00 USD multiplied by the pair count. pricing.minimum_quote_usd is an absolute backstop on the whole quote, also 3.00 USD, which catches the smallest possible job of one document into one language. On any job larger than a single pair, the per-pair floor is the one doing the work.

Savings Stack

Two optimization layers compound for internal document translation, and both act on the cost side rather than the price side — they widen the margin under the floor rather than changing what a customer pays:

OptimizationMechanismSavingsParameter
Delta processingSkip pairs where the translation is already newer than the source70–90% reduction in workControlled by options.delta at job submission
Prompt cachingSystem prompt and protected terms are cached across calls90% off cached tokensbedrock.*.cache_read_per_1m

Batch inference used to be the third layer here and it is gone. Bedrock batch mode was permanently removed on June 20, 2026, along with the Standard delivery tier that depended on it. Every job now runs real-time in Express mode, which is the only delivery value the quote endpoint accepts — a request naming any other mode is rejected rather than silently downgraded. The lesson worth keeping is the one the removal teaches: batch traded a 50% token discount for a 12 to 24 hour SLA, and once the per-pair floor set the price, that discount stopped reaching the customer while the wait still did. Paying in latency for a saving nobody receives is a bad trade, so we stopped making it.

Parameter Categories

Bedrock Pricing Live — refreshed nightly from the AWS Price List

The actual per-token rates Amazon Bedrock charges us. Keep the distinction clear as you read: these are our costs, not what we charge customers. Customer pricing is the flat per-pair floor covered further down, and the gap between the two is the margin. Keys are named bedrock.<model>.realtime.<direction>_per_1m, with separate cache-read and cache-write keys for the Claude models that support prompt caching. Since October 2026 you no longer maintain these by hand: the nightly sync job reads them from the AWS Price List (us-east-2, the geographic rate our us. inference profiles are billed at) and writes any change here, holding a model's old values if its new ones look wrong.

Two multipliers are worth memorising because they drive every cost decision here. Prompt cache reads are 90% off on-demand input, which is why the system prompt and the protected-terms list are cached rather than resent. Cache writes are 1.25× on-demand, paid once when the cache is populated — a small premium that pays for itself immediately across a multi-language job.

The engine prices every job at the realtime rates, because Bedrock batch mode was permanently removed on June 20, 2026 and the quote endpoint accepts no other delivery mode. The nightly refresh also stores batch.* rates where AWS publishes them, so the data is there if that ever changes; nothing reads them today.

KeyDefaultUnitDescription
bedrock.sonnet46.realtime.input_per_1m3.30USD / 1M tokensSonnet 4.6 input. The agent Auto uses for Amharic, Hausa, Mongolian, Pashto and Somali, and a customer's choice for nuance-heavy content. Before October 2026 this row held the global cross-Region rate (3.00 / 15.00); the refresh now stores the geographic rate we are actually billed, 10% higher.
bedrock.sonnet46.realtime.output_per_1m16.50USD / 1M tokensSonnet 4.6 output. Output is 5× input on every model here, which is why estimation.output_input_ratio matters so much to a quote.
bedrock.sonnet46.cache_read_per_1m0.33USD / 1M tokensSonnet 4.6 prompt cache read — 90% off input. Applied to the system prompt and protected-terms tokens on every cached request.
bedrock.sonnet46.cache_write_per_1m4.125USD / 1M tokensSonnet 4.6 prompt cache write — 1.25× input, paid once when the cache is populated.
bedrock.opus48.realtime.input_per_1m5.50USD / 1M tokensClaude Opus 4.8 input, the Opus agent since October 2026, at about a third of the retired Opus 4 rate. Opus is the one model whose bill can climb past the flat per-pair floor.
bedrock.opus48.realtime.output_per_1m27.50USD / 1M tokensClaude Opus 4.8 output — the highest rate in the table.
bedrock.opus48.cache_read_per_1m0.55USD / 1M tokensClaude Opus 4.8 prompt cache read.
bedrock.opus48.cache_write_per_1m6.875USD / 1M tokensClaude Opus 4.8 prompt cache write, paid once per cache population.
bedrock.opus5.*stored onlyUSD / 1M tokensA rate set the refresh fetches and stores so a later change of Opus model needs no new data. No agent is offered on it and nothing prices against it.
bedrock.haiku55.realtime.input_per_1m0.11USD / 1M tokensClaude Haiku 5.5 input, the fastest Claude agent and a customer's choice for high-volume work.
bedrock.haiku55.realtime.output_per_1m0.55USD / 1M tokensClaude Haiku 5.5 output.
bedrock.haiku55.cache_read_per_1m0.011USD / 1M tokensClaude Haiku 5.5 prompt cache read.
bedrock.haiku55.cache_write_per_1m0.1375USD / 1M tokensClaude Haiku 5.5 prompt cache write.
bedrock.qwen3235b.realtime.input_per_1m0.22USD / 1M tokensQwen3 235B input — our standard: it translates our own library, and Auto picks it for every language it supports. It is also the least expensive model in the roster by a long way.
bedrock.qwen3235b.realtime.output_per_1m0.88USD / 1M tokensQwen3 235B output. No prompt-caching keys exist for this model, so its cost is input plus output and nothing else.
bedrock.mistrallarge.realtime.input_per_1m0.50USD / 1M tokensMistral Large input.
bedrock.mistrallarge.realtime.output_per_1m1.50USD / 1M tokensMistral Large output. Note the unusually tight 3× input-to-output ratio, against 5× elsewhere.
bedrock.deepseekv3.realtime.input_per_1m0.58USD / 1M tokensDeepSeek V3 input.
bedrock.deepseekv3.realtime.output_per_1m1.68USD / 1M tokensDeepSeek V3 output.

Only the three Claude agents carry cache keys — Sonnet 4.6, Opus 4.8 and Haiku 5.5. Qwen3 235B, Mistral Large and DeepSeek V3 are priced on input and output alone. That is not an omission in this table, it is the shape of what Bedrock offers, and it means the caching saving you can count on varies by which model a job routes to.

Token Estimation Derived from job history — refresh as real jobs accumulate

These ratios let the engine estimate a job's cost and duration before it runs, which is what makes a quote possible and a pre-flight spend check meaningful. They are not guesses — every one is derived from real Aurora translation_job_events data, and they get better the more jobs the system completes.

KeyDefaultUnitDescription
estimation.tokens_per_byte0.64tokens / byteInput tokens per translatable byte, and one of the more satisfying numbers in this system: it holds at 0.63–0.66 across every document type we have measured. That stability is what lets a byte count become a reliable cost estimate. Refresh it from the translation:actuals:{model} Valkey keys the nightly sync job writes.
estimation.output_input_ratio0.76ratioOutput tokens divided by input tokens. Varies by document type: code-heavy docs ~0.46 (code passes through untranslated), prose-heavy docs ~1.01. The 0.76 average is a reasonable middle ground for mixed technical documentation.
estimation.quote_padding_pct6percentPadding applied to token estimates for customer quotes. A 6% buffer keeps quotes slightly conservative — actual cost is usually at or below the estimate. Absorbed by the markup buffer on prose-heavy documents.
estimation.cache_hit_rate0.30fraction (0–1)Expected fraction of input tokens served from the prompt cache. The system prompt plus the protected-terms list accounts for roughly 30% of total input tokens, and at 90% off that is a real saving on every single request. Refresh from the actual cache_hit_rate values in the translation:actuals:* Valkey keys.
estimation.cached_system_tokens1200tokensApproximate token count of the cacheable system prompt block (system instructions + protected terms list). This is the fixed overhead per request — identical for every doc/lang pair. Must be a multiple of 3 per Trinity Beast convention.

How to keep these honest. The nightly sync job writes observed token ratios to Valkey keys such as translation:actuals:claude-sonnet-4.6. Review them in the TBI Administration dashboard under Translation → Token Usage and update the estimation parameters when the actuals have drifted. Use 5% as normal noise and 15% as the point where an update is warranted. This is the loop that keeps quotes accurate as the corpus and the model roster change, and it takes a couple of minutes.

Cost Controls Safety guardrails — prevent runaway spend

Operational limits that prevent runaway Bedrock costs. The daily spend cap is a hard stop — no new jobs are accepted after it is reached. The token limit is a secondary guard that catches unusually large documents before they hit the dollar cap. For a customer, both caps (and the kill switch) are checked before the charge: accept answers 503 tbts_service_paused and nothing is charged or queued. The customer limits themselves (12 languages, 42 documents, 300 KB per document, 9 quotes per batch) are code constants in internal/txlimits, not parameters, so no row here can loosen them.

KeyDefaultUnitDescription
controls.daily_spend_limit_usd600USDDaily Bedrock spend cap. No new translation jobs are accepted after this limit is reached. Resets at midnight UTC. Must be a multiple of 3 (200×3). Tracked in Valkey key autoops:bedrock:spend:daily.
controls.daily_token_limit51,000,000tokensDaily combined token limit (input + output). Secondary guard — model-agnostic. Catches unusually large documents before they hit the dollar cap. 51M = 17M×3. Tracked in Valkey keys autoops:bedrock:tokens:input:daily and autoops:bedrock:tokens:output:daily.
controls.max_docs_per_request42documentsA mirror of txlimits.MaxDocsPerQuote, set to '42' by the October 2026 migration and not read for enforcement. The enforced limit is the code constant: 42 documents for a customer quote and for POST /admin/translate alike.
controls.max_active_jobs12jobsWarning threshold for concurrent active translation jobs. Multiple of 3. At 12 or more the LPO adds a tx:warnings entry and still queues the job: it is advisory, not a hard stop.
controls.max_queue_depth12jobsDeclared but not enforced: nothing reads this value, and accepted jobs queue without a cap. Kept for reference only.
controls.customer_cancel_enabledtrueswitchLaunch switch for POST /translate/cancel/{quote_id}. true lets customers cancel; anything else answers 404.
controls.cost_per_chunk_floor0.03USDMinimum cost-per-chunk floor used by the nightly sync job when calculating rolling averages. Prevents unrealistically low averages from skewing customer quotes during low-activity periods.
controls.cost_per_chunk_ceiling0.09USDMaximum cost-per-chunk ceiling used by the nightly sync job. Caps runaway averages caused by anomalous jobs (e.g., a single very large document).

Customer Pricing What we charge — separate from what Bedrock charges us

These parameters control what customers pay for TBTS translations. They are applied at quote time by CustomerPriceForPair() in the translation engine. Changing these takes effect immediately — no deploy needed.

KeyDefaultUnitDescription
pricing.infra_per_pair_usd0.003USD / pairInfrastructure cost per language pair. Covers ECS task time, S3 storage, CloudFront invalidation, Lambda invocations, and Step Function state transitions. Added to Bedrock cost before markup is applied.
pricing.markup_pct30percentService fee markup applied to (Bedrock cost + infra cost). Covers support, margin, and operational overhead. Applied at quote time and in all customer-facing emails. This is the primary lever for adjusting customer pricing — change it here and it takes effect everywhere immediately.
pricing.minimum_per_pair_usd3.00USD / pairThe number that actually sets the price. Multiplied by the total pair count to form a floor, and because the cost-based calculation lands under it for every model except Opus on large documents, this is what a customer pays. Change this one value and you have repriced the entire service.
pricing.minimum_quote_usd3.00USDAbsolute floor on the whole quote, applied last. Where the per-pair floor scales with the work, this one catches the smallest job there is — one document into one language. It exists so no quote is ever worth less than the Stripe fee, email, and support it costs to fulfil.
pricing.ecs_cost_per_minute0.00112USD / minuteFargate task cost per minute, used to price the real compute time a job occupies. This is what makes the estimate duration-aware rather than a flat per-pair guess.
pricing.infra_rate_per_second0.0003USD / secondPer-second infrastructure rate applied across job duration, alongside the ECS minute rate.
pricing.fixed_job_overhead0.012USD / jobOne-time overhead charged per job rather than per pair — queue handling, orchestration, and the finalize step, all of which happen once no matter how many pairs a job carries.

Three parameters that used to live in this table are gone, and it is worth knowing why rather than wondering where they went. pricing.standard_tier_discount_pct and pricing.express_tier_premium_pct priced the two delivery tiers, and pricing.infra_markup_pct marked up the batch pipeline's rolling cost averages. All three depended on Bedrock batch mode, which was permanently removed on June 20, 2026. One delivery mode means nothing left to discount or add a premium against, so keeping the levers would have meant three knobs that turn and change nothing — the most expensive kind of documentation, because a reader trusts it.

The Opus-only price formula — everything else is a flat 3.00 USD/pair: this cost-plus calculation runs for a single agent, Claude Opus 4.8. Every other model skips it entirely and is priced at the flat 3.00 USD per-pair rate directly. For Opus, the floor is still the price on small documents and the formula only wins on large ones.

infra       = InfraCostForJob(translatable_bytes_per_doc, num_languages)
subtotal    = total_bedrock_cost + infra
service_fee = subtotal × (pricing.markup_pct / 100)
total       = subtotal + service_fee

total_pairs = doc_count × language_count
pair_floor  = pricing.minimum_per_pair_usd × total_pairs

final       = max(total, pair_floor, pricing.minimum_quote_usd)   ← Opus path only

The canonical implementation is Params.CustomerPriceForJob, and its own comment states the outcome plainly: a 3.00 USD per-pair floor, which only Opus on large documents exceeds. There is one older function, CustomerPriceForPair, kept solely so previously stored quote records still resolve — it is deprecated and is not what prices a new job.

Refund Rules New in October 2026 — the failed-pair refund machine

These six rows decide how a pair that could not be delivered becomes money back in the customer's account. The design keeps the customer in charge: a failed pair first gets one free retry, and only what is still undelivered is refunded, either when the customer chooses "Refund instead" or automatically once the window closes. The whole machine shipped switched off and was turned on on 2026-10-11, in one statement that also set refund.failed_pair_since, so no quote accepted before that moment is ever refunded by surprise. The free retry and the refund for a paid job that never started work from deploy, whatever these rows say.

KeyDefaultUnitDescription
refund.failed_pair_enabledfalseswitchThe launch switch for the automatic failed-pair refund, the "Refund instead" button and its API. Off until the live test passes.
refund.failed_pair_window_hours72hoursHow long a failed pair waits for the customer's free retry before it is refunded automatically.
refund.failed_pair_max_attempts3attemptsStripe attempts per quote before the refund is marked error for an operator.
refund.sweep_interval_minutes15minutesHow often the refund sweeper ticks. A multiple of 3, clamped to 3–60, and re-read on every tick, so a change needs no restart.
refund.failed_pair_since(empty)RFC 3339 UTCOnly quotes accepted after this moment enter the machine. Empty means off. Set in the same statement that turns the flag on.
refund.start_failure_since(empty)RFC 3339 UTCThe start-failure catch-up covers quotes accepted after this moment. Stamped once by migration 03b at deploy, after every LPO task runs the new code.

Managing Parameters

Via the TBI Administration Dashboard

The easiest way to manage translation parameters is through the TBI Administration dashboard. Navigate to the Translation tab and scroll to the Translation Parameters section (admin only).

Via the Admin API

-- List all parameters
GET /admin/translate/params

-- Filter by category
GET /admin/translate/params?category=customer_pricing

-- Update a parameter (applies immediately to Aurora + Valkey + in-memory)
POST /admin/translate/params
{"key": "pricing.markup_pct", "value": "30", "updated_by": "cory"}

-- Force all containers to reload from Aurora
POST /admin/translate/params/reload

Via Aurora SQL (direct)

-- View all parameters
SELECT key, value, category, updated_at, updated_by
FROM translation_parameters
ORDER BY category, key;

-- Update a parameter
UPDATE translation_parameters
SET value = '35', updated_at = NOW(), updated_by = 'cory'
WHERE key = 'pricing.markup_pct';

-- After a direct SQL update, reload Valkey via the API:
POST /admin/translate/params/reload

Important: Direct SQL updates to Aurora do NOT automatically update Valkey or in-memory values on running containers. Always follow a direct SQL update with a POST /admin/translate/params/reload call to ensure all containers pick up the change within their next 5-minute poll cycle.

Nightly Sync Job

The nightly sync job (trinity-beast-sync-job, BeastReconciler, runs at 1 AM EDT) performs four translation-related tasks, and the first one is new in October 2026:

0. Refresh Bedrock rates from the AWS Price List

Before anything is copied, the job asks AWS what each model costs today. It calls the public Price List (pricing:GetProducts, served from us-east-1 and filtered to us-east-2, where our Bedrock traffic runs) for all seven rate keys, checks every value, and writes any change into the bedrock_pricing rows of Aurora. Step 1 then carries the fresh rates into tx:params in the same run, and a final check confirms Valkey holds exactly what Aurora holds.

It is careful in the way a price source has to be. Each model is all-or-nothing: a fetch error, a missing dimension, an unknown unit, a value outside 0.0001–500 USD per million tokens, or a change of more than 3× in one night keeps that model's stored rates and adds one line to a single ops alert. Nothing in it can stop the rest of the nightly job. For a deploy, SYNC_ONLY=bedrock-rates runs only the refresh, the copy and the check, so the day's spend and token guards are never reset mid-day.

Diagram 6.1: Nightly Bedrock Rate Refresh

flowchart LR
    subgraph AWS["AWS Price List (us-east-1 endpoint)"]
        PL["GetProducts
us-east-2 rates, 7 models"] end subgraph SYNC["Sync job (BeastReconciler, 1 AM nightly)"] CHK{"Every value plausible?
unit known, 0.0001-500,
no jump over 3x"} KEEP["Keep stored rates
for that model"] ALERT["One ops alert
for the whole run"] VER{"Aurora = tx:params?"} end subgraph DATA["Stores"] AUR[("Aurora
translation_parameters
bedrock_pricing rows")] VK[("Valkey
tx:params, 27 h TTL")] end LPO["LPO containers
quote and cost math"] PL --> CHK CHK -->|"yes: write changes"| AUR CHK -->|"no"| KEEP KEEP --> ALERT AUR -->|"Step 1 copies the table"| VK VK --> VER VER -->|"no"| ALERT VK -->|"read first"| LPO AUR -.->|"fallback"| LPO style AWS fill:#3b2a5c,stroke:#a78bfa,color:#ffffff style SYNC fill:#1e3a5f,stroke:#60a5fa,color:#ffffff style DATA fill:#14403a,stroke:#10b981,color:#ffffff style PL fill:#2e1065,stroke:#a78bfa,color:#e2e8f0 style CHK fill:#422006,stroke:#fbbf24,color:#e2e8f0 style KEEP fill:#422006,stroke:#fbbf24,color:#e2e8f0 style ALERT fill:#7f1d1d,stroke:#fca5a5,color:#e2e8f0 style VER fill:#422006,stroke:#fbbf24,color:#e2e8f0 style AUR fill:#064e3b,stroke:#10b981,color:#e2e8f0 style VK fill:#064e3b,stroke:#10b981,color:#e2e8f0 style LPO fill:#334155,stroke:#94a3b8,color:#e2e8f0 linkStyle 0,1,4 stroke:#10b981,stroke-width:2px linkStyle 2,3,6 stroke:#fbbf24,stroke-width:2px linkStyle 5 stroke:#60a5fa,stroke-width:2px linkStyle 7,8 stroke:#94a3b8,stroke-width:2px

1. Sync translation_parameters → tx:params

Reads all rows from the translation_parameters Aurora table and writes them to the tx:params Valkey hash with a 27-hour TTL, so the hash always outlives the next run. This ensures all containers have fresh parameter values, including the rates refreshed in step 0, even if the Valkey cache expired overnight.

2. Rolling 7-day cost averages

Queries translation_job_events for the last 7 days, grouped by model and execution mode. Calculates the average cost-per-chunk for each combination and writes to Valkey:

Valkey KeyDescription
translation:cost_per_chunk:{model}Real-time path (backward compatible)
translation:cost_per_chunk:{model}:batchBatch inference path
translation:cost_per_chunk:{model}:batch_cachedBatch + prompt caching path
translation:cost_per_chunkBlended average (all models, backward compat)

The floor and ceiling from controls.cost_per_chunk_floor and controls.cost_per_chunk_ceiling are applied to these averages before they are written to Valkey. Note that the batch and batch_cached variants above are historical: batch inference was removed on June 20, 2026, so those keys are retained for backward compatibility and are no longer written with fresh data. There is also no longer an infrastructure markup applied at this stage — pricing.infra_markup_pct existed to mark up the batch pipeline's averages and went away with it.

3. Actual token ratio data

Writes actual token ratios from real jobs to Valkey for operator review:

-- Key pattern: translation:actuals:{model}
-- Example: translation:actuals:claude-sonnet-4.6

Fields:
  avg_input_tokens   — average input tokens per pair
  avg_output_tokens  — average output tokens per pair
  avg_cached_tokens  — average cached tokens per pair
  output_input_ratio — derived: avg_output / avg_input
  cache_hit_rate     — derived: avg_cached / avg_input
  pair_count         — number of pairs in the 7-day window
  updated_at         — when this was last calculated

Review these periodically and update estimation.output_input_ratio and estimation.cache_hit_rate in translation_parameters when the actuals have drifted from the stored defaults. This is the feedback loop that keeps every future quote grounded in what the engine really did rather than in what it was once assumed to do.

Complete Parameter Reference

The 46 parameters read from the live translation_parameters table on 2026-10-10, plus the six refund rows and the controls.max_docs_per_request update of the October 2026 migration, and the rate rows the nightly refresh adds for the new Claude agents, sorted by category and key. Read the live table with GET /admin/translate/params for today's exact values and count.

KeyCategoryDefaultDescription
bedrock.deepseekv3.realtime.input_per_1mbedrock_pricing0.58DeepSeek V3 input (USD/1M tokens)
bedrock.deepseekv3.realtime.output_per_1mbedrock_pricing1.68DeepSeek V3 output (USD/1M tokens)
bedrock.mistrallarge.realtime.input_per_1mbedrock_pricing0.50Mistral Large input (USD/1M tokens)
bedrock.mistrallarge.realtime.output_per_1mbedrock_pricing1.50Mistral Large output (USD/1M tokens)
bedrock.qwen3235b.realtime.input_per_1mbedrock_pricing0.22Qwen3 235B input (USD/1M tokens)
bedrock.qwen3235b.realtime.output_per_1mbedrock_pricing0.88Qwen3 235B output (USD/1M tokens)
bedrock.sonnet46.cache_read_per_1mbedrock_pricing0.33Sonnet 4.6 prompt cache read (USD/1M tokens)
bedrock.sonnet46.cache_write_per_1mbedrock_pricing4.125Sonnet 4.6 prompt cache write (USD/1M tokens)
bedrock.sonnet46.realtime.input_per_1mbedrock_pricing3.30Sonnet 4.6 input (USD/1M tokens)
bedrock.sonnet46.realtime.output_per_1mbedrock_pricing16.50Sonnet 4.6 output (USD/1M tokens)
bedrock.haiku55.*bedrock_pricing0.11 / 0.55 / 0.011 / 0.1375Claude Haiku 5.5: realtime input and output, cache read and write (USD/1M tokens)
bedrock.opus48.*bedrock_pricing5.50 / 27.50 / 0.55 / 6.875Claude Opus 4.8, the live Opus agent: realtime input and output, cache read and write (USD/1M tokens)
bedrock.opus5.*bedrock_pricingstored onlyRate set kept for a later change of Opus model; no agent is offered on it (USD/1M tokens)
bedrock.{sonnet46,qwen3235b,deepseekv3,mistrallarge}.batch.*bedrock_pricingsonnet46 1.65 / 8.25 · qwen3235b 0.11 / 0.44 · deepseekv3 0.29 / 0.84 · mistrallarge 0.25 / 0.75Batch input and output rates, stored where AWS publishes them; nothing reads them while every job runs in real time (USD/1M tokens)
estimation.cache_hit_ratetoken_estimation0.30Expected fraction of input tokens served from cache
estimation.cached_system_tokenstoken_estimation1200Tokens in the cacheable system prompt block
estimation.output_input_ratiotoken_estimation0.76Output tokens divided by input tokens
estimation.quote_padding_pcttoken_estimation6Padding % applied to token estimates for quotes
estimation.seconds_per_bytetoken_estimation0.0014Seconds of processing per translatable byte
estimation.speed_factor.claude-sonnet-4.6token_estimation1.0Duration multiplier for claude-sonnet-4.6
estimation.speed_factor.deepseek-v3token_estimation0.7Duration multiplier for deepseek-v3
estimation.speed_factor.mistral-largetoken_estimation0.6Duration multiplier for mistral-large
estimation.speed_factor.qwen3-235btoken_estimation0.6Duration multiplier for qwen3-235b
estimation.startup_secondstoken_estimation10Fixed job startup time before the first pair moves
estimation.tokens_per_bytetoken_estimation0.64Input tokens per translatable byte
controls.cost_per_chunk_ceilingcost_controls0.09Upper bound applied to rolling cost-per-chunk averages
controls.cost_per_chunk_floorcost_controls0.03Lower bound applied to rolling cost-per-chunk averages
controls.daily_spend_limit_usdcost_controls600Hard daily Bedrock spend cap — no new jobs accepted past it
controls.daily_token_limitcost_controls51000000Secondary daily token guard, catches oversized documents early
controls.max_active_jobscost_controls12Warning threshold for jobs running concurrently (advisory; jobs still queue)
controls.max_docs_per_requestcost_controls42Mirror of txlimits.MaxDocsPerQuote; not read for enforcement
controls.max_queue_depthcost_controls12Declared, not enforced: accepted jobs queue without a cap
controls.customer_cancel_enabledcontrolstrueLaunch switch for customer cancel (POST /translate/cancel/{quote_id})
pricing.ecs_cost_per_minutecustomer_pricing0.00112Fargate task cost per minute (USD)
pricing.fixed_job_overheadcustomer_pricing0.012One-time per-job overhead (USD)
pricing.infra_per_pair_usdcustomer_pricing0.003Infrastructure cost per language pair (USD)
pricing.infra_rate_per_secondcustomer_pricing0.0003Per-second infrastructure rate across job duration (USD)
pricing.markup_pctcustomer_pricing30Service fee markup % applied to cost
pricing.minimum_per_pair_usdcustomer_pricing3.00The flat per-pair price customers actually pay (USD)
pricing.minimum_quote_usdcustomer_pricing3.00Absolute floor on the whole quote (USD)
refund.failed_pair_enabledrefundfalseLaunch switch for the automatic failed-pair refund
refund.failed_pair_max_attemptsrefund3Stripe attempts before the refund is marked error
refund.failed_pair_sincerefund(empty)Only quotes accepted after it enter the machine; empty = off
refund.failed_pair_window_hoursrefund72Hours a failed pair waits for the free retry
refund.start_failure_sincerefund(empty)Start-failure catch-up horizon; stamped by migration 03b
refund.sweep_interval_minutesrefund15Refund sweeper tick (multiple of 3, clamped 3–60)