Jakarta GPU Capacity: VRAM Sizing for Indonesian AI Teams

Photo by Timothy Borkowski via Wikimedia Commons (CC BY-SA 3.0)
Weights alone are parameters times bytes per parameter, so a 70 billion parameter model is about 140 GB at BF16. The Sahabat AI 70B model card states approximately 140 GB and recommends two NVIDIA H100s or four L40s. You then need extra memory on top for the KV cache, activations and runtime overhead, which is why the recommended setup leaves less headroom than it appears to.
Because the weights are only the first of three terms. The KV cache grows with context length multiplied by the number of concurrent sequences, and activations plus framework overhead take another slice. A configuration that loads cleanly with one test user can fail at peak simply because more sequences are alive at once.
No. CoreWeave announced 360 megawatts of contracted IT power in Greater Jakarta in August 2026, expected online in 2028, and contracted power is not a card you can rent this quarter. Design for the hardware you can get today, keep the model behind your own interface, and treat it as something you will swap more than once before that capacity opens.
Quantised models take less memory at the cost of lower precision, and how much quality you lose depends on the model, the language and the task. The only trustworthy answer comes from running your own eval at each format rather than from a leaderboard. Note also that quantising weights does not shrink the KV cache, which has its own dtype setting.
No, and assuming they do is why teams over-buy. Serving holds weights plus KV cache, while a full fine-tune also holds gradients, optimiser state and activations, so its footprint is a multiple of the serving footprint. Fine-tuning is bursty and can be rented by the hour, whereas serving is continuous and wants to sit near your users.

Photo by Timothy Borkowski via Wikimedia Commons (CC BY-SA 3.0)
Key Takeaway
VRAM decides which GPU an Indonesian AI team can actually use, and it is parameters times bytes per parameter plus a KV cache that grows with context length and batch size. The Sahabat AI 70B model card asks for roughly 140 GB, so two H100 cards hold the weights and little else. Quantise, or rent by the hour.
The question is small and the answer is not: which GPU do I rent to serve an Indonesian-language model from Jakarta? I opened the Sahabat AI 70B model card expecting a shopping list, and found one sentence that closes most of the options before the shopping starts. To load the model in FP16 or BF16 you need approximately 140 GB of VRAM, with two NVIDIA H100s or four L40s given as the recommended setups.
This post is the arithmetic behind that sentence, and what to do about it in a quarter when the large Jakarta AI capacity everyone is waiting for is contracted rather than rentable. It covers the four ways an Indonesian team can get a GPU today, how to size VRAM before renting anything, why fine-tuning and serving are different machines, and what quantisation genuinely buys and costs.
Start with the finding: for inference you are not shopping for FLOPS, you are shopping for memory. A model that does not fit in GPU memory does not run slowly, it does not run at all. The first term is the easy one — parameters times bytes per parameter. At BF16 that is two bytes each, so a 70 billion parameter model is about 140 GB of weights before anything else is loaded, which is exactly the figure the Sahabat AI 70B card publishes.
// The easy term: parameters x bytes per parameter.
const BYTES_PER_PARAM = { bf16: 2, int8: 1, int4: 0.5 };
function weightsGB(paramsBillion, format) {
return (paramsBillion * 1e9 * BYTES_PER_PARAM[format]) / 1e9;
}
weightsGB(70, "bf16"); // 140 — the figure the Sahabat AI 70B card publishes
weightsGB(70, "int8"); // 70 — one 80 GB card becomes conceivable
weightsGB(70, "int4"); // 35 — before format and scale overhead
// A model card gives you this line and stops. It is never the whole budget.This is worth doing by hand because it is the only part of the decision you can settle before spending anything. Throughput, latency and cost per token all depend on traffic you may not have yet. Whether the weights fit on the card you are about to rent is a fact you can establish in ten seconds with a calculator, and it disqualifies most of the menu on its own.
The second term grows with your traffic rather than with your model. Every token already processed keeps a key and a value vector in memory for every layer, so the cache is two, times layers, times key-value heads, times head dimension, times bytes per element — per token, per sequence. The published config for the Sahabat AI 70B lists 80 layers, 8 key-value heads and a head dimension of 128, which at two bytes an element comes to 320 KiB of cache for a single token.
// Straight out of the model's published config.json:
const LAYERS = 80; // num_hidden_layers
const KV_HEADS = 8; // num_key_value_heads — GQA, not the 64 attention heads
const HEAD_DIM = 128; // head_dim
const BYTES = 2; // bf16
// Key AND value, every layer, every token, every concurrent sequence.
const perToken = 2 * LAYERS * KV_HEADS * HEAD_DIM * BYTES;
// 327,680 bytes = 320 KiB per token
perToken * 8192; // 2.7 GB — a modest 8k conversation
perToken * 131072; // 42.9 GB — ONE session using the advertised 128k window
// Concurrency multiplies this. Parameter count does not.That number looks small and is not. The model advertises a 128k context window, and at 320 KiB per token one conversation that actually uses it needs about 43 GB of KV cache for one user — more than half of an 80 GB card. Grouped-query attention is already saving you here: if the cache were sized by the 64 attention heads rather than the 8 key-value heads, the same arithmetic would be eight times worse.
Set the context length from the p95 prompt length in your own logs, not from what the model supports. The cache budget follows the number you configure, so an unexamined default is the difference between a card with headroom and a card that preempts requests under load.
Put the two terms together against the recommended hardware and the shape of the problem appears. NVIDIA lists GPU memory of 80 GB for the H100 SXM and 48 GB for the L40S, so the model card's two recommendations come to 160 GB and 192 GB of total memory for a model whose weights alone are about 140 GB. The final column below is what is actually left to serve users with.
| Setup | Total VRAM | Weights | Left for cache | Tokens of cache |
|---|---|---|---|---|
| 2 x H100 80GB, BF16 | 160 GB | about 140 GB | about 20 GB | roughly 61,000 |
| 4 x L40S 48GB, BF16 | 192 GB | about 140 GB | about 52 GB | roughly 159,000 |
| 1 x H100 80GB, 4-bit | 80 GB | about 35 GB | about 45 GB | roughly 137,000 |
Read the last column, not the first. The two-H100 setup that satisfies the model card leaves room for roughly sixty thousand tokens of cache across every concurrent request, which is not even one full-length conversation. The four-L40S setup, which reads like the budget option, is the one with headroom. And both rows are still optimistic, because they count only weights and cache and nothing the runtime needs.
The expensive version of this mistake is sizing from the parameter count alone, committing to a rental, then meeting the KV cache under real concurrency. Weights are a fixed cost paid once at load time; the cache is a variable cost that arrives with your users, and it is what turns a configuration that worked in testing into an out-of-memory error at peak.
There are four real options and they differ less in price than in what they take away from you. A managed inference API removes the arithmetic above entirely and costs nothing while idle, at the price of serving whatever models the vendor lists and sending your prompts to their region. Renting GPU hours from an overseas neocloud gives you the widest menu of card types and hourly granularity, at the price of egress, a round trip out of Indonesia, and operating the server yourself.
Renting in-country is the option teams assume is a straight substitute and it is not: where it exists the menu of card types is narrower, so availability tends to decide your model rather than the other way round. Buying or colocating hardware is the only option that makes idle time free and every other cost yours — import, power, cooling, spares, and a card that depreciates whether or not anyone is chatting. I would not buy anything before I had a month of measured, saturated utilisation to point at.

Conflating these is the most expensive mistake in this area, because a fine-tuning footprint is a multiple of a serving footprint rather than the same number. Serving holds weights plus KV cache. A full fine-tune holds weights, gradients the size of the trainable weights, optimiser state for every trainable parameter, and activations that scale with batch size and sequence length — all before a single user has been served.
The practical consequence is that the two jobs should be bought differently. Fine-tuning is bursty, finite and tolerant of a queue, which makes it the ideal thing to rent by the hour on whichever card is available this week, including outside Indonesia when the training data allows it. Serving is continuous, latency-sensitive and wants to sit near your users. Teams that size one cluster for both end up paying for training-shaped hardware twenty-four hours a day. Adapter methods such as LoRA change the fine-tuning term dramatically by training a small fraction of the parameters, and change the serving term not at all — you still load the full base model.
Bytes per parameter is the only term in the weights arithmetic you control, which is why quantisation moves the answer further than anything else here. Two bytes per parameter puts a 70B model at 140 GB; one byte puts it at 70 GB; four bits puts it near 35 GB before format and scale overhead. That is not a saving, it is a change of category — the difference between a two-card rental you have to reserve and a single 80 GB card you can take by the hour.
The honest cost is that quantised models take less memory at the cost of lower precision, as vLLM's documentation puts it, and how much quality you actually lose is specific to your model, your language and your task. There is a second trap worth knowing: quantising the weights does nothing to the KV cache, which is a separate allocation with its own dtype. If long contexts are what fills your card, the cache dtype is the switch you want, and vLLM exposes it as kv-cache-dtype independently of the weight format.
The cheapest experiment in this whole post is running your own eval against a smaller model before renting anything larger. A 9 billion parameter model at BF16 is about 18 GB of weights and leaves most of a single 48 GB L40S free for cache. If it passes, none of the two-card arithmetic applies to you at all.
The last thing to get right is time. In August 2026 CoreWeave announced three Indonesian data centres carrying 360 megawatts of contracted IT power in Greater Jakarta, expected online in 2028. That is a real commitment and a genuine change to what Indonesian teams will be able to buy — in 2028. Contracted power is not a card in a slot, and a startup planning this quarter around it is planning around hardware that does not exist yet.
So design for the hardware you can get today and make the model a configuration value rather than an architectural assumption. Put the model behind your own interface, keep the prompt and the eval portable, and treat the card underneath as something you will change twice before that capacity opens. The teams best placed in 2028 are the ones already serving real traffic on rented hours in 2026, because they will know exactly what to ask for.

All three bands have to be budgeted before you can name a card, so the order of work is arithmetic first, hardware last. This is the sequence I would follow for an Indonesian product shipping now.
# Bound every term explicitly. The defaults suit a benchmark, not your traffic.
vllm serve GoToCompany/Llama-Sahabat-AI-v2-70B-IT \
--tensor-parallel-size 2 \
--max-model-len 8192 \
--max-num-seqs 4 \
--gpu-memory-utilization 0.92 \
--kv-cache-dtype fp8
# --tensor-parallel-size 2 splits the 140 GB of weights across both H100s
# --max-model-len 8192 where the KV cache term is really bounded — not by the card
# --max-num-seqs 4 4 x 8192 x 320 KiB = about 10 GB, inside the 20 GB left over
# --gpu-memory-utilization the remainder covers activations, CUDA graphs, fragmentation
# --kv-cache-dtype fp8 halves the cache; a separate decision from the weight format
# Wrong: leave max-model-len at the model default and meet 128k under load.
# Right: set it from the p95 prompt length in your own logs, then raise it deliberately.That last step is one command, and it is the one most teams leave at defaults. Every flag below maps to a term in the arithmetic above, which is the point: the server should be configured from your own numbers, not from the model card's.
The rule worth carrying out of this is that memory gets sized before anything gets shopped for, and arithmetic disqualifies options faster than any vendor brochure. VRAM is three terms — parameters, cache and overhead — and all three are computable on paper in an afternoon. Jakarta will have far more capacity in 2028. What your team can serve this quarter is decided by the term you did not budget for.
Sources