Skip to Content

How to Run Your Own AI Models Efficiently Without Wasting Compute

Running an LLM through an API is relatively straightforward. You send a prompt, receive tokens, and pay for usage.

Running your own LLM infrastructure is different.

Once you deploy models such as Llama, Qwen, Mistral, DeepSeek, Gemma, or your own fine-tuned model, you become responsible for much more than the prompt:

  • model selection
  • inference parameters
  • context-window management
  • GPU memory
  • KV cache
  • batching
  • concurrency
  • quantisation
  • model loading
  • request scheduling
  • latency
  • throughput
  • observability
  • infrastructure utilisation
  • cloud cost

A model producing a good answer does not necessarily mean the system is efficient.

You could have an LLM server using an expensive GPU while processing only a fraction of its potential workload. You could send thousands of unnecessary tokens with every request. You could configure a 32K context window when most requests use fewer than 2K tokens.

Or you could simply be generating far more tokens than your application actually needs.

This article explains the major parameters involved in LLM inference, how they affect output and infrastructure, and how developers can design self-hosted AI systems that use compute more efficiently.

First, Understand What Happens During LLM Inference

Consider a simple request:

System:
You are a technical support assistant.

User:
Explain why my Nginx server returns HTTP 502.

Before the model generates anything, several things happen.

The text is converted into tokens.

The model processes those input tokens during a stage commonly called prefill.

It then begins generating output tokens during the decode stage.

Conceptually:

Prompt
   ↓
Tokenizer
   ↓
Input Tokens
   ↓
Prefill
   ↓
KV Cache
   ↓
Decode
   ↓
Output Tokens

These stages have different performance characteristics.

Prefill involves processing the input context and can make heavy use of GPU compute.

Decode generates tokens sequentially and is often constrained by memory bandwidth and the model's ability to repeatedly access its weights and cached attention state.

This distinction matters because:

2,000 input tokens + 100 output tokens

and

100 input tokens + 2,000 output tokens

are both 2,100-token requests, but they do not necessarily create the same workload.

Understanding this is the foundation of efficient LLM hosting.

Temperature

temperature controls how strongly the model favours high-probability tokens during sampling.

Example:

{
  "temperature": 0.2
}

Lower temperature generally produces more predictable output.

Higher temperature increases variation.

For example, consider:

Complete this sentence:

The database failed because...

At a low temperature, the model may consistently generate something like:

The database failed because the connection pool was exhausted.

At a higher temperature, responses may vary more:

The database failed because replication lag caused the failover process to time out.

or:

The database failed because an unexpected schema migration locked several tables.

Typical usage

For code generation, extraction, classification, technical support, and structured output, lower temperatures are usually appropriate.

For brainstorming and creative generation, higher temperatures can be useful.

Example starting points:

Code generation       → 0.0–0.3
Technical Q&A         → 0.1–0.4
General assistant     → 0.4–0.8
Brainstorming         → 0.7–1.0+

These are guidelines, not universal rules. Different models respond differently to sampling parameters.

Does temperature reduce GPU cost?

Not significantly by itself.

A lower temperature does not magically make the transformer cheaper to execute.

The larger cost reduction usually comes from generating fewer tokens, using a smaller model, improving batching, or reducing unnecessary context.

Top-P

top_p, also known as nucleus sampling, limits sampling to a set of tokens whose cumulative probability reaches a specified threshold.

Example:

{
  "top_p": 0.9
}

Imagine the next-token probabilities are:

server       35%
application  25%
database     15%
process      10%
container     5%
...

Instead of sampling across the entire vocabulary, top_p restricts sampling to the most probable candidates until their cumulative probability reaches the threshold.

A lower value makes the model more conservative.

A higher value gives the model access to more alternatives.

In production systems, avoid changing every sampling parameter simultaneously without evaluation.

A configuration such as:

{
  "temperature": 0.2,
  "top_p": 0.9
}

can work well for technical tasks, but benchmark against your model and workload.

Top-K

top_k limits the candidate set to the K most probable tokens before sampling.

Example:

{
  "top_k": 40
}

Only the 40 highest-probability candidate tokens are considered.

Compare:

top_k = 1

with:

top_k = 50

With top_k = 1, generation effectively selects the highest-probability candidate at each sampling step.

With top_k = 50, the model can sample from a larger candidate set.

Not every inference API exposes top_k, and implementations can differ, so verify how your serving engine handles it.

Maximum Output Tokens

This is one of the most important parameters for infrastructure efficiency.

Depending on the API, you may see:

{
  "max_tokens": 500
}

or:

{
  "max_completion_tokens": 500
}

or:

{
  "max_new_tokens": 500
}

The exact name depends on the inference engine.

The concept is the same: limit how many tokens the model may generate.

Suppose your application only needs:

{
  "status": "critical",
  "risk": 87,
  "reason": "SSH exposed publicly"
}

Giving the model a 4,000-token generation budget makes little sense.

If the task normally requires fewer than 200 tokens, start with something closer to:

{
  "max_tokens": 250
}

Why?

Because generation is expensive.

Each additional generated token requires another decode step.

If your application processes millions of requests, unnecessary generation becomes unnecessary infrastructure cost.

Stop Sequences

Stop sequences allow generation to terminate when the model reaches a known delimiter.

Example:

{
  "stop": ["</result>"]
}

Suppose your expected response is:

<result>
risk=high
score=92
</result>

Once the model generates:

</result>

the server can stop generation.

Without a stopping condition, the model may continue:

Additional explanation:

The reason this happened...

That additional text might be completely useless to your application.

Efficient inference is often less about making tokens cheaper and more about avoiding unnecessary tokens entirely.

Repetition and Frequency Controls

Models can occasionally enter repetitive patterns.

For example:

The service failed because the database connection failed.
The database connection failed because the connection failed.
The connection failed because...

Depending on the inference engine, controls may include:

frequency_penalty
presence_penalty
repetition_penalty

These parameters discourage repeated tokens, phrases, or previously used concepts.

They are useful when repetition is an observed failure mode, but aggressive penalties can reduce answer quality.

Do not add penalties simply because the API exposes them.

Evaluate them against your actual workload.

Seed and Determinism

Some inference engines expose a seed.

Example:

{
  "seed": 42
}

A fixed seed can improve reproducibility when debugging or evaluating model behaviour.

However, a seed does not necessarily guarantee identical output across:

  • different hardware
  • different model versions
  • different inference engines
  • different kernels
  • different quantisation methods
  • different batching conditions

Use it as an evaluation and debugging control rather than assuming complete determinism.

Context Window

This is where LLM efficiency becomes much more interesting.

Suppose a model supports:

128,000 tokens

That does not mean every request should use 128,000 tokens.

Consider an application that sends:

System prompt       1,500 tokens
Conversation        8,000 tokens
Retrieved docs      7,000 tokens
User query            200 tokens
--------------------------------
Total              16,700 tokens

Now imagine most of the relevant information was contained in only 3,000 tokens.

You are repeatedly asking the model to process thousands of unnecessary tokens.

A large context window is a capacity, not a target.

The Hidden Cost of Large System Prompts

Developers often focus on user prompts while ignoring the system prompt.

Suppose every request includes a system instruction containing:

4,000 tokens

And your application receives:

100,000 requests/day

That means:

4,000 × 100,000
= 400,000,000 system-prompt tokens/day

before considering user input, retrieved documents, tool definitions, conversation history, or generated output.

This is why prompt architecture is also infrastructure architecture.

Ask whether the model really needs:

4,000 tokens of instructions

or whether the same behaviour can be achieved with:

800 tokens

Well-designed prompts can improve both model reliability and infrastructure efficiency.

Conversation History Is Not Free Memory

Consider a support assistant with a long conversation.

Message 1
Message 2
Message 3
...
Message 50

A naïve implementation may send all 50 messages back to the model for every new turn.

By turn 50, the request could contain tens of thousands of tokens.

Instead, manage conversation state intentionally.

For example:

Recent conversation
        +
Conversation summary
        +
Relevant historical facts
        +
Current user request

Instead of:

Entire conversation since the beginning

A practical context pipeline might look like:

Incoming request
       ↓
Retrieve recent messages
       ↓
Retrieve relevant memories
       ↓
Retrieve relevant documents
       ↓
Apply token budget
       ↓
Construct prompt
       ↓
LLM

Context management should be treated as a system component, not just prompt concatenation.

RAG Should Retrieve Relevant Context, Not Maximum Context

Retrieval-Augmented Generation can reduce the need to send entire knowledge bases to the model.

But badly configured RAG can create another problem.

Suppose your vector database returns:

20 documents × 1,000 tokens

That adds approximately:

20,000 tokens

to the request.

If only three documents matter, most of that context is waste.

A better retrieval pipeline may use:

Query
  ↓
Vector Search
  ↓
Candidate Documents
  ↓
Metadata Filtering
  ↓
Reranking
  ↓
Top Relevant Chunks
  ↓
LLM

Retrieval quality often matters more than retrieval quantity.

Model Size Matters

Suppose you have access to:

7B model
14B model
32B model
70B model

A common mistake is:

The 70B model is better, so every request should use 70B.

That may be unnecessary.

Consider these tasks:

Extract IP address from log
Classify ticket category
Summarise 500-word incident
Generate Bash script
Analyse complex architecture problem

They do not necessarily require the same model.

A smaller model may handle:

classification
extraction
simple summarisation
format conversion
routing

while a larger model handles:

complex reasoning
architecture analysis
difficult debugging
long-form generation

This creates a model-routing architecture.

Incoming Request
        ↓
     Router
     ↙    ↓    ↘
 Small  Medium  Large
 Model  Model   Model

The objective is not:

Use the cheapest model.

It is:

Use the smallest model that reliably satisfies the task.

Quantisation

Model weights are commonly stored or served using formats such as:

FP32
FP16
BF16
FP8
INT8
INT4

Quantisation reduces numerical precision to reduce memory and potentially improve inference efficiency.

For illustration, a 70-billion-parameter model using FP16 weights requires roughly:

70B × 2 bytes
≈ 140 GB

for the raw model weights alone.

At 8-bit precision, conceptually:

70B × 1 byte
≈ 70 GB

At 4-bit precision:

70B × 0.5 byte
≈ 35 GB

Actual runtime memory requirements differ because inference also needs memory for:

  • KV cache
  • activations
  • runtime buffers
  • CUDA graphs
  • framework overhead
  • batching
  • temporary operations

Quantisation can dramatically change the hardware required to serve a model.

But benchmark quality and performance.

A smaller representation is not automatically faster in every hardware/software combination.

KV Cache: One of the Most Important Parts of LLM Serving

During autoregressive generation, the transformer repeatedly attends to previous tokens.

Recomputing everything from scratch for every generated token would be extremely inefficient.

Inference engines therefore maintain a Key-Value cache, commonly called the KV cache.

Conceptually:

Prompt tokens
     ↓
Transformer
     ↓
KV Cache
     ↓
Generate token 1
     ↓
Update cache
     ↓
Generate token 2
     ↓
Update cache

KV-cache consumption generally grows with factors such as:

number of concurrent sequences
×
sequence length
×
model architecture
×
cache precision

This creates an important trade-off.

Large context windows and high concurrency can consume substantial GPU memory even when the model weights fit comfortably.

That is why:

Model fits in GPU memory

does not necessarily mean:

Production workload fits in GPU memory

Batching

Imagine a GPU receives these requests independently:

Request A
Request B
Request C
Request D

If they are processed inefficiently, GPU capacity may remain underutilised.

Batching allows multiple requests to share GPU execution.

A ┐
B ├── Batch → GPU
C ┤
D ┘

Modern LLM servers often use techniques such as continuous batching, where requests can enter and leave the active batch dynamically.

This is important because LLM requests have different lengths.

One request may generate:

50 tokens

while another generates:

1,500 tokens

Static batching can waste capacity waiting for long-running sequences.

Continuous batching improves utilisation by scheduling active sequences more dynamically.

Throughput vs Latency

These two metrics should not be confused.

Latency measures how long an individual request takes.

Throughput measures how much work the system can process over time.

You may measure:

requests/second

or:

tokens/second

Important LLM metrics include:

TTFT = Time To First Token

TPOT = Time Per Output Token

ITL = Inter-Token Latency

An interactive chatbot may prioritise low TTFT.

A batch-processing system may care much more about aggregate throughput.

The optimal infrastructure configuration therefore depends on workload.

Streaming

For interactive applications, streaming can significantly improve perceived performance.

Instead of waiting for:

Complete 1,000-token response

the application starts displaying tokens as they are generated.

Model
 ↓
Token
 ↓
Token
 ↓
Token
 ↓
Client

Streaming does not necessarily reduce total computation.

But it can significantly improve user experience because users see output earlier.

Concurrency

Suppose your server handles:

1 request

very quickly.

That does not mean it can handle:

100 simultaneous requests

efficiently.

Concurrency affects:

  • GPU memory
  • KV cache
  • batching
  • queue depth
  • TTFT
  • throughput
  • tail latency

Benchmark production systems at multiple concurrency levels.

For example:

Concurrency 1
Concurrency 4
Concurrency 8
Concurrency 16
Concurrency 32
Concurrency 64

Then measure:

TTFT
tokens/sec
requests/sec
GPU utilisation
GPU memory
queue time
p95 latency
p99 latency

Optimising only single-request latency can lead to poor production economics.

GPU Utilisation

Imagine paying for a GPU instance while seeing:

GPU utilisation: 22%

for most of the day.

You may have an infrastructure utilisation problem.

Potential causes include:

  • insufficient batching
  • low traffic
  • CPU preprocessing bottlenecks
  • slow tokenisation
  • network latency
  • inefficient serving engine
  • excessive synchronisation
  • model too large for the workload
  • poor request scheduling
  • storage bottlenecks

The objective is not to force the GPU to 100% utilisation constantly.

Instead, determine whether the infrastructure is delivering acceptable latency and throughput for the cost of the hardware.

CPU and RAM Still Matter

LLM hosting discussions often focus exclusively on GPUs.

But the complete pipeline may include:

API Gateway
    ↓
Authentication
    ↓
Request validation
    ↓
Tokenizer
    ↓
Retrieval
    ↓
Reranking
    ↓
Prompt construction
    ↓
GPU inference
    ↓
Post-processing
    ↓
Response

The GPU is only one component.

A slow CPU, insufficient RAM, inefficient retrieval service, or overloaded vector database can leave expensive GPU hardware waiting.

Optimise the whole inference path.

Use an Efficient Serving Engine

Loading a model using a basic Python script is useful for experimentation.

Production serving is different.

Popular inference engines include:

  • vLLM
  • Hugging Face Text Generation Inference
  • TensorRT-LLM
  • SGLang
  • llama.cpp for suitable workloads

Production engines can provide capabilities such as:

continuous batching
KV-cache management
prefix caching
quantisation
tensor parallelism
streaming
request scheduling
OpenAI-compatible APIs
metrics

The serving engine can materially affect how much useful work you obtain from the same GPU.

Prefix Caching

Consider an application where every request starts with the same large system prompt:

System prompt: 3,000 tokens
User prompt: 200 tokens

If supported by the inference stack, prefix caching can allow repeated prompt prefixes to reuse previously computed state rather than repeatedly processing the same prefix.

This can be especially valuable for workloads with:

  • long shared system prompts
  • common instruction prefixes
  • repeated document prefixes
  • multi-turn conversations

Caching effectiveness depends heavily on prompt structure.

For example, keeping stable content first:

Stable system instructions
Stable tools
Variable user content

is generally more cache-friendly than introducing changing information near the beginning of the prompt.

Prompt Design Is Infrastructure Optimisation

Consider this instruction:

You are an AI assistant responsible for carefully analysing the
following log information. You should examine each log line in detail
and determine whether there are potential security issues...

versus:

Analyse the logs for security risks.
Return JSON: severity, finding, evidence.

If both produce equivalent quality for your model, the second version is cheaper to process and easier to maintain.

At large scale, reducing prompt size by even a few hundred tokens can matter.

Prompt engineering is therefore not just about answer quality.

It can affect:

latency
memory
throughput
GPU utilisation
cloud cost

Avoid Sending Images When You Do Not Need Them

Multimodal models introduce another source of compute usage.

Suppose an application sends:

7 images

with every request.

Ask:

Does the model actually need all seven?

A better architecture might first perform:

Image filtering
      ↓
Deduplication
      ↓
Resize/compression
      ↓
Select relevant images
      ↓
Vision model

If seven images contain nearly identical information, sending all seven wastes inference capacity.

For document-processing pipelines, consider whether OCR or a specialised vision model can extract relevant information before invoking the larger multimodal model.

Do Not Use an LLM for Everything

Suppose you need to detect whether a string is an IPv4 address.

You could ask a 14B model:

Is 192.168.1.25 an IP address?

But this may be solved with ordinary code.

import ipaddress

ipaddress.ip_address("192.168.1.25")

LLMs should be used where probabilistic language or reasoning provides value.

Use conventional software for:

validation
exact arithmetic
regex matching
database lookup
sorting
simple transformations
deterministic rules

One of the easiest ways to reduce LLM infrastructure cost is simply not invoking the model when software can solve the task more efficiently.

Cache Responses

Suppose users repeatedly ask:

How do I reset my password?

If the context and answer are effectively identical, repeatedly running GPU inference may be unnecessary.

A cache layer can look like:

Request
   ↓
Cache lookup
   ↓
HIT ─────→ Response

MISS
   ↓
LLM
   ↓
Cache
   ↓
Response

Caching strategies may include:

exact prompt caching
semantic caching
prefix caching
application-level caching
retrieval caching

Each solves a different problem.

Autoscaling: Avoid Paying for Idle GPUs

Suppose your traffic pattern looks like:

09:00   High
12:00   High
17:00   Medium
23:00   Low
03:00   Almost zero

Running the same GPU capacity 24/7 may be wasteful.

Depending on latency requirements, infrastructure can scale according to:

request queue
active sequences
token throughput
GPU utilisation
KV-cache pressure
request rate

But GPU autoscaling has complications.

Model loading may take significant time.

Cold starts can be expensive.

Therefore, a production architecture might maintain:

Minimum warm capacity
        +
Autoscaled workers

rather than scaling everything to zero.

Model Routing Can Reduce Cloud Cost Dramatically

Consider this architecture:

                 ┌→ Small Model
Request → Router ├→ Medium Model
                 └→ Large Model

Suppose 10,000 daily requests consist of:

6,000 simple
3,000 medium
1,000 complex

Sending all 10,000 requests to the largest model means paying large-model infrastructure costs for simple extraction and classification tasks.

Instead:

Simple  → 7B/8B model
Medium  → 14B/32B model
Complex → larger reasoning model

Routing can be based on:

  • request type
  • prompt length
  • confidence
  • user tier
  • latency requirements
  • task complexity
  • previous model failure
  • expected output length

The routing layer itself can use rules, classifiers, or a smaller model.

Design a Token Budget

Every application should have a token-budget strategy.

For example:

Maximum context:       16,000

System prompt:          1,000
Conversation:           3,000
Retrieved context:      6,000
User input:             1,000
Output reserve:         2,000
Safety buffer:          3,000

Before calling the model:

if estimated_tokens > context_budget:
    trim_or_summarise()

Do not wait for the inference server to reject requests because the context exceeded the model limit.

Context management belongs in the application layer.

Measure Cost Per Useful Output

GPU utilisation alone is not enough.

Imagine two configurations.

Configuration A

GPU utilisation: 90%
Throughput:       2,000 tokens/sec
Error rate:       8%

Configuration B

GPU utilisation: 75%
Throughput:       1,700 tokens/sec
Error rate:       0.5%

Configuration A appears more efficient until failed or low-quality outputs are considered.

Useful metrics may include:

cost/request
cost/1M tokens
cost/successful request
tokens/request
TTFT
tokens/sec
queue time
GPU memory utilisation
cache-hit ratio
model-routing distribution
quality score

The goal is not maximum hardware utilisation.

The goal is maximum useful output per unit of infrastructure cost while meeting quality and latency targets.

A More Efficient Production Architecture

Instead of:

Application
     ↓
70B Model
     ↓
GPU

consider:

                    ┌───────────────┐
                    │ API Gateway   │
                    └───────┬───────┘
                            ↓
                    ┌───────────────┐
                    │ Request       │
                    │ Classification│
                    └───────┬───────┘
                            ↓
                    ┌───────────────┐
                    │ Cache Check   │
                    └───────┬───────┘
                            ↓
                    ┌───────────────┐
                    │ Context       │
                    │ Builder       │
                    └───────┬───────┘
                            ↓
                    ┌───────────────┐
                    │ Model Router  │
                    └───┬────┬─────┘
                        │    │
                  ┌─────┘    └─────┐
                  ↓                ↓
             Small Model       Large Model
                  │                │
                  └───────┬────────┘
                          ↓
                  Inference Engine
                          ↓
                     GPU Pool
                          ↓
                    Observability

Now the platform can make decisions based on workload instead of blindly forwarding every request to one expensive model.

Example: Optimising an AI Log Analysis Platform

Imagine a cybersecurity application analysing server logs.

A naïve architecture sends every log line directly to a large LLM.

Nginx Logs
Apache Logs
SSH Logs
System Logs
      ↓
Large LLM

This is expensive and unnecessary.

A better pipeline could be:

Logs
 ↓
Parser
 ↓
Deduplication
 ↓
Rule Engine
 ↓
Anomaly Detection
 ↓
Relevant Events
 ↓
Small LLM
 ↓
Complex Cases
 ↓
Large LLM

Suppose a server produces:

1,000,000 log lines/day

but filtering identifies only:

8,000 relevant events

and grouping/deduplication reduces those to:

600 incidents

The LLM may only need to analyse those 600 incident groups.

That is a fundamentally different infrastructure requirement from sending one million log records into an LLM.

Benchmark Before Choosing Infrastructure

Do not select GPU infrastructure because:

This GPU has more VRAM.

Build a representative benchmark.

For example:

Model: 14B
Quantisation: FP8

Prompt lengths:
512
2K
8K
16K

Output lengths:
100
500
1K

Concurrency:
1
8
32
64

Measure:

TTFT
TPOT
tokens/sec
requests/sec
GPU memory
GPU utilisation
power consumption where relevant
error rate
quality

Then calculate infrastructure economics.

Cost per hour
÷
successful requests per hour
=
infrastructure cost per successful request

This gives you a meaningful comparison between hardware configurations.

Optimise the Model and Infrastructure Together

LLM efficiency has several layers.

Application
    ↓
Prompt
    ↓
Context
    ↓
Model
    ↓
Inference Engine
    ↓
GPU
    ↓
Cloud Infrastructure

Optimising only one layer is rarely enough.

A shorter prompt cannot fix an inference server with poor scheduling.

A faster GPU cannot fix an application sending 20,000 irrelevant tokens per request.

Quantisation cannot fix unnecessary model calls.

Autoscaling cannot fix a 70B model being used for simple classification.

Treat AI infrastructure as a complete system.

A Practical Optimisation Checklist

Before scaling your self-hosted LLM environment, examine the following.

Model

Is this model larger than necessary?
Can simpler requests use a smaller model?
Can the model be quantised safely?

Prompt

Is the system prompt unnecessarily large?
Are instructions repeated?
Can structured output reduce generation?

Context

Are old conversations always included?
Is RAG retrieving too many chunks?
Can irrelevant context be removed?

Generation

Is max_tokens too high?
Can stop sequences terminate generation earlier?
Are responses longer than the application needs?

Serving

Is continuous batching enabled?
Is KV-cache utilisation monitored?
Can prefix caching help?
Is concurrency tuned?

Infrastructure

Is the GPU appropriate for the model?
Is GPU memory being used effectively?
Are CPU or network bottlenecks starving the GPU?
Can workers autoscale?

Architecture

Can deterministic logic replace some LLM calls?
Can requests be cached?
Can different models handle different task classes?

Observability

Are input/output tokens measured?
Is TTFT tracked?
Is throughput tracked?
Is queue time tracked?
Is cost/request calculated?

If you cannot answer these questions from telemetry, infrastructure optimisation becomes guesswork.

Where BitHost Can Help

Deploying an LLM is relatively easy.

Running it efficiently in production is the harder problem.

A team can successfully deploy a model and still waste significant cloud resources because of:

oversized GPU instances
poor batching
unnecessary context
inefficient model selection
idle GPU capacity
lack of caching
bad concurrency settings
oversized output limits
weak autoscaling
missing observability

This is where BitHost can help organisations running private and self-hosted AI infrastructure.

The focus is not simply:

Put an LLM on a GPU.

The objective is to understand how the application, model, inference engine and cloud infrastructure interact, then optimise the complete inference path.

Cloud Cost Optimisation for AI Workloads

Traditional cloud optimisation often focuses on:

CPU
RAM
storage
bandwidth
instance uptime

AI infrastructure adds another layer.

You also need to understand:

GPU utilisation
GPU memory
model residency
KV-cache consumption
tokens/sec
tokens/request
batch efficiency
queue depth
model routing
context length
cache hit rate

A GPU showing 80% utilisation does not automatically mean the environment is cost-efficient.

The useful question is:

How much production value are we getting from each hour of GPU infrastructure?

BitHost can help evaluate this across the stack.

Right-Sizing AI Infrastructure

Instead of selecting infrastructure first and adapting the application around it, workload characteristics should drive infrastructure design.

For example:

Model size
Context requirements
Traffic
Concurrency
Latency SLA
Output length
Availability requirement

can be used to determine:

GPU class
GPU count
RAM
CPU
serving engine
quantisation
batch configuration
scaling strategy

A 7B classification workload and a 70B reasoning workload should not automatically inherit the same deployment architecture.

Reducing Idle GPU Cost

GPU infrastructure is expensive when idle.

BitHost can help design environments around:

traffic patterns
warm capacity
autoscaling
request queues
batch workers
scheduled workloads
model loading strategy

For asynchronous workloads, requests may be grouped and processed efficiently rather than requiring low-latency GPU capacity to remain online continuously.

For interactive applications, minimum warm capacity can preserve responsiveness while additional workers scale with demand.

Optimising the Inference Stack

Cloud cost optimisation should also examine the software layer.

A deployment can be evaluated across:

Model
 ↓
Quantisation
 ↓
Inference Engine
 ↓
Batching
 ↓
KV Cache
 ↓
Concurrency
 ↓
GPU

The goal is to identify the configuration that meets quality and latency requirements at the lowest practical infrastructure cost.

That may involve comparing:

different model sizes
different quantisation levels
different serving engines
different GPU types
different batching configurations
different context limits

The correct answer depends on the workload.

Benchmarking should decide it.

Building AI Infrastructure That Can Be Measured

Optimisation requires visibility.

A production AI environment should expose metrics such as:

Request volume
Input tokens
Output tokens
Context length
TTFT
Generation speed
Queue time
Active requests
GPU utilisation
GPU memory
KV-cache utilisation
Cache hit rate
Model selected
Error rate
Infrastructure cost

These metrics allow engineering teams to answer questions such as:

Why did AI infrastructure cost increase this week?

Instead of guessing, telemetry might show:

Average context:
4.2K → 9.8K tokens

Average output:
320 → 610 tokens

Cache hit rate:
41% → 19%

GPU utilisation:
72% → 48%

Now the cost increase has technical explanations that can be investigated.

From "The Model Works" to "The System Is Efficient"

The first milestone in an AI project is often:

The model works.

The production milestone should be:

The model works reliably,
at the required latency,
under expected concurrency,
with measurable infrastructure cost.

Those are very different standards.

Running your own model gives you control.

But control also means responsibility for:

model selection
token usage
context architecture
inference optimisation
GPU utilisation
scaling
monitoring
cost

The most efficient AI platforms will not necessarily be the ones using the largest models or the most powerful GPUs.

They will be the ones that understand which model should perform which task, how much context it actually needs, how requests should be scheduled, and how much useful work each unit of compute produces.

How to Run Your Own AI Models Efficiently Without Wasting Compute
Bithost July 26, 2026
Share this post
How to Use Celery in Odoo for Heavy Task Scheduling and Report Generation
Stop blocking your Odoo workers with long-running jobs. Offload them to Celery and keep your system fast for everyone.