← Back to list

How to Build LLM Systems on AWS Without Burning $20,000 a Month

A technical guide for architects who want control, not billing surprises.

caldeguer · 2026-04-21 04:55 · 5 claps · 6.4 min read
#artificial-intelligence #machine-learning #aws #software-architecture #llm
Open on Medium ↗
Wiki topics: LLM · Large Language Models ML · Machine Learning AI · AI · General EDU · Education & Learning ☁️ · DevOps & Cloud 🏛️ · Architecture

How to Build LLM Systems on AWS Without Burning $20,000 a Month

Your architecture defines your invoice.

Your architecture defines your invoice.

A technical guide for architects who want control, not billing surprises.

Integrating a language model today is ridiculously easy. With AWS Bedrock, you can go from zero to “we have AI” in under 10 minutes.

And that is exactly where the problem begins.

What starts as an experimental feature ends up, weeks later, as a $20,000/month invoice. Not because you have millions of users, but because your architecture was never designed to scale with cost control.

Most teams don’t fail at integrating AI. They fail at designing the system that decides when to use it.

🔥 The Real Problem: Implicit Decisions

When you make a direct call to an LLM, you are making several decisions without realizing it:

  • Which model to use
  • When to use it
  • How much context to send
  • How much output to allow
  • What to do if it fails

If you don’t explicitly control these decisions, the system scales… and so does the cost.

Key Insight: > An LLM is not just a component. It is a costly resource that must be orchestrated.

🧠 Principle #1: Not Every Problem Needs an LLM

Before talking about models, embeddings, or RAG, there is a more important question: Does this actually need Generative AI?

AWS already has optimized services for specific tasks:

  • Translation → Amazon Translate
  • OCR & Documents → Amazon Textract
  • Traditional NLP → Amazon Comprehend

These services are cheaper, faster, and more predictable.

Rule of Thumb: > If you can solve it with a deterministic service, using an LLM is a poor economic decision.

🏗️ Reference Architecture (Overview)

An LLM system in production should not look like this:

Client → LLM

That’s a demo. Not a real system.

A production-ready architecture should look like this:

Client → API → Orchestrator
                  ↓
              AI Filter
                  ↓
           Semantic Cache
                  ↓
              ML Router
        ↙        ↓        ↘
     Local    Economy    Premium

💡 Why this matters

This shift is the difference between:

  • a feature that works
  • and a system that scales sustainably

In real-world architectures, the goal is not just to generate responses…

It’s to decide when NOT to call the LLM.

⚙️ Step 1: Optimization Before Infrastructure

Before deploying anything, shrink the problem.

🧩 1.1 Model Selection (Bigger isn’t always better)

  • Classification → Small model (e.g., Llama 3 8B)
  • Simple Summary → Economy model
  • Complex Reasoning → Advanced model

Rule: The right model is the cheapest one that meets the requirement.

⚡ 1.2 Quantization

Reducing precision (FP32 → INT8/INT4) allows for lower memory usage, lower inference costs, and higher speed.

  • Note: It can degrade quality and requires case-by-case testing.
  • On AWS: This works best on EC2 (Graviton or light GPU) or ECS/EKS.

🧪 1.3 Distillation

Creating smaller versions of large models dramatically reduces costs while maintaining acceptable performance for specific tasks such as classification or structured extraction.

🔁 Step 2: Semantic Cache (The Biggest Savings Lever)

Most systems receive repeated or very similar prompts. An LLM treats “What are the hours?” and “What time do you open?” as different inputs. Your system shouldn’t.

  • How it works: Generate a prompt embedding → Search for similarity in a vector database → If it clears a threshold, reuse the cached response.
  • AWS Infra: Amazon OpenSearch or vector engines in DynamoDB.

Real Impact: 30% to 70% of requests can avoid inference entirely.

🧩 Step 3: RAG (Retrieval-Augmented Generation)

When you need dynamic context (documents, knowledge bases), RAG is the way to go. It reduces the need for fine-tuning, improves accuracy, and controls context.

Warning: RAG done well reduces tokens. RAG done poorly multiplies them.

🔀 Step 4: ML Router (Model Arbitrage)

Not all prompts have the same value. An efficient system classifies before executing:

  1. Trivial input → Local model
  2. Standard input → Economy model
  3. Complex input → Premium model

💰 Token Economics (The Budget Breaker)

Costs don’t depend on requests; they depend on processed tokens.

  • Limit output (max_tokens)
  • Trim unnecessary context
  • Optimize system prompts
  • Avoid excessive history

🛡️ Step 5: Observability and Cost Control

A system without monitoring is a time bomb.

  • Metrics: Amazon CloudWatch
  • Alerts: AWS Budgets
  • Traceability: AWS X-Ray
  • Security: WAF + Rate Limiting

💻 Simplified Orchestrator Example (Python)

Python

def lambda_handler(event, context):
    prompt = event.get("prompt")

    # 1. Unnecessary AI Filter
    if is_deterministic_task(prompt):
        return solve_without_llm(prompt)

    # 2. Semantic Cache
    cached = get_semantic_cache(prompt)
    if cached:
        return cached

    # 3. Routing
    model = route_with_ml(prompt)

    # 4. Execution
    response = call_model(prompt, model)

    # 5. Save to Cache
    save_to_cache(prompt, response)

    return response

💰Realistic Cost Model (1M Requests)

Assumptions

  • Avg input: 500 tokens
  • Avg output: 300 tokens
  • Total: 800 tokens/request

Scenario 1 — No Architecture (Naive LLM Usage)

  • Model: premium via Amazon Bedrock
  • Cost: ~$0.015 / 1K tokens

👉 Cost per request:

800 tokens ≈ $0.012

👉 1M requests:

≈ $12,000

👉 With inefficiencies (over-context, retries, no limits):

$15,000 – $20,000

Scenario 2 — Cheap Model Only

  • Model: small / economy
  • Cost: ~$0.002 / 1K tokens

👉 Cost per request:

≈ $0.0016

👉 1M requests:

≈ $1,600

⚠️ Trade-off:

  • lower quality
  • not suitable for complex reasoning

Scenario 3 — Optimized System

With:

  • 50% semantic cache hit rate
  • model routing (70% cheap, 30% premium)
  • reduced context (↓30% tokens)

👉 Effective tokens:

~400 tokens/request (after optimization)

👉 Blended cost:

≈ $0.0005 – $0.001 per request

👉 1M requests:

≈ $500 – $1,000

💡 Insight

The biggest cost reduction does not come from cheaper models. It comes from avoiding unnecessary inference entirely.

🧠 Conclusion

Building systems with LLMs isn’t an integration problem; it’s an architecture problem under uncertainty, cost, and latency constraints.

An LLM call is not just another API request. It is a probabilistic, high-variance, and cost-sensitive operation whose impact compounds with scale. Systems that treat it like a simple function call inevitably lose control — of quality, of latency, and especially of cost.

A production-grade design must therefore optimize for three things simultaneously:

  • When to execute → eliminate unnecessary inference
  • How to execute → choose the right model, context, and limits
  • When to avoid execution altogether → reuse, cache, or fallback to deterministic paths

This is why the most effective systems:

  • Decide before executing (filters, routing, policies)
  • Reuse before calculating (semantic caching, deduplication)
  • Constrain before scaling (token limits, context control, quotas)

In practice, the biggest savings don’t come from switching to cheaper models. They come from not calling the model at all.

Cost, then, becomes an architectural outcome — not a billing surprise.

Using managed services like Amazon Bedrock accelerates adoption, but it does not solve design. Without orchestration, even the best platform will scale inefficiently. Conversely, with the right architecture, teams can combine managed services with self-hosted workloads on Amazon EC2 to optimize both cost and control over time.

At scale, additional forces appear:

  • Multi-tenancy pressure → a single client can dominate usage if left unchecked
  • Token inflation → poorly bounded context silently multiplies cost
  • Quality vs. cost trade-offs → every optimization has an accuracy impact
  • Security risks (e.g., prompt injection in RAG) → architecture must include trust boundaries, not just data pipelines

These are not edge cases — they are inevitable in real systems.

The teams that succeed are not the ones with the best models. They are the ones with the best decision systems around those models.

Your architecture defines your invoice — but more importantly, it defines whether your system is sustainable, predictable, and scalable.

In the end, building with LLMs is an exercise in controlled intelligence: not maximizing what the model can do, but controlling when, how, and why it does it.

Your architecture defines your invoice.

I am currently working to address the following key questions:

🤔 1. To what extent does semantic caching impact response quality?

If we reuse responses based on vector similarity (e.g., a 0.92 threshold), how do we prevent:

  • Outdated answers: Stale data being served before the cache expires.
  • Loss of user-specific context: Accidentally serving User A’s personalized response to User B.
  • Similarity “False Positives”: Errors where the math says it’s a match, but the logic says it isn’t.

🤔 2. When does an ML Router stop being cost-effective?

Routing adds layers of complexity (model management, maintenance, and feature engineering).

  • The Break-even Point: At what stage does the router’s operational cost vs. the inference savings (e.g., using a small model vs. a large one) no longer justify its implementation?

🤔 3. Balancing RAG vs. Token Inflation

RAG improves precision, but it also increases prompt size and token costs.

  • The Optimization Strategy: What is the “sweet spot” for chunking, ranking, and context limits that ensures accuracy without causing costs to skyrocket?

🤔 4. The viability of replacing AWS Bedrock with self-hosted models

Considering:

  • Infrastructure Costs: Amazon EC2 (GPU/CPU) expenses.
  • Operational Overhead: Maintenance, scalability, and latency management.
  • The Reality Check: In which real-world scenarios does a self-hosted approach actually outperform a managed service?

🤔 5. Preventing Prompt Injection and Leaks in RAG Architectures

By using RAG, you are dynamically injecting external content into your prompt.

  • The Threat: What happens if retrieved documents contain malicious instructions, sensitive data, or untrustworthy content?
  • Mitigation Strategies: How do we implement effective context sanitization, source validation, and system instruction isolation?

🤔 6. Designing True Multi-tenancy without Cost Spikes

In LLM-based SaaS systems, a single client can generate thousands of requests or use extremely long prompts.

  • Governance: How do we control this without degrading the UX?
  • Solutions: Implementing dynamic per-tenant quotas, intelligent rate limiting, and token-based pricing.

메타데이터
post_id
b58d0e4d5619
slug
how-to-build-llm-systems-on-aws-without-burning-20-000-a-month-b58d0e4d5619
url
https://medium.com/@roybincg/how-to-build-llm-systems-on-aws-without-burning-20-000-a-month-b58d0e4d5619
canonical_url
https://medium.com/@roybincg/how-to-build-llm-systems-on-aws-without-burning-20-000-a-month-b58d0e4d5619
author_url
https://medium.com/@roybincg
status
ok
fetched_at
2026-06-27 07:40:21