Skip to content
JavaAgentic

Type at least two characters. Try “RAG”, “pgvector” or “tool calling”.

Spring AI with Ollama (Local LLMs)

Run local LLMs in Spring Boot with Spring AI and Ollama: setup, model selection, offline development, cost and privacy trade-offs, and when a local model is the right call.

Intermediate4 min readUpdated
On this page

Local models are not just a privacy feature — they change your development loop. No API key, no per-call cost, no network dependency in tests. This tutorial covers running Ollama with Spring AI, and is honest about the quality trade-off.

Key Takeaways

  • Local models give you free, offline, private inference — at a quality cost.
  • Switching Spring AI from OpenAI to Ollama is a dependency and config change; your code is unchanged.
  • Best used for development, privacy-sensitive workloads, and cost optimisation of high-volume simple tasks.
  • Local embeddings are an excellent default for development, removing cost and latency from ingestion.

Setting up Ollama

Install Ollama, then pull a model:

# Install from ollama.com, then:
ollama pull llama3.2          # a small, fast general model
ollama pull nomic-embed-text  # a local embedding model
ollama serve                  # serves on http://localhost:11434

Wiring it into Spring AI

pom.xml
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
application.yml
spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        options:
          model: llama3.2
          temperature: 0.2
      embedding:
        options:
          model: nomic-embed-text

Your service code is identical to the OpenAI version — that is the whole point of the ChatModel abstraction:

@Service
public class LocalChatService {
 
    private final ChatClient chatClient;
 
    public LocalChatService(ChatClient.Builder builder) {
        this.chatClient = builder.build();   // no idea it is talking to Ollama
    }
 
    public String ask(String question) {
        return chatClient.prompt().user(question).call().content();
    }
}

Profiles for local vs hosted

application-local.yml
spring:
  ai:
    ollama:
      chat:
        options:
          model: llama3.2
application-prod.yml
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o-mini

Run locally with --spring.profiles.active=local; deploy with prod. One codebase, two providers.

Choosing a local model

SizeRuns onGood forNot good for
1-3BLaptop CPUClassification, routing, simple extractionComplex reasoning
7-8B16GB RAM, better with GPUGeneral chat, RAG answeringHard multi-step tasks
13B+Dedicated GPUHigher-quality reasoningAnything without a GPU budget

Start small. A 3B model handles a surprising amount of routine work — intent classification, simple extraction, first-line RAG answering — at zero marginal cost.

Local embeddings: the easy win

Even if you use a hosted chat model, local embeddings are worth it for development. Spring AI supports in-process ONNX models that need no server:

spring:
  ai:
    embedding:
      transformer:
        onnx:
          model-uri: <all-MiniLM-L6-v2 onnx model>

This removes cost and network latency from your ingestion pipeline entirely, which makes iterating on chunking and retrieval far faster.

When a local model is the right call

  • Privacy and compliance — data that cannot legally or contractually leave your infrastructure.
  • High-volume simple tasks — classifying millions of items where hosted per-call cost adds up and a small model is good enough.
  • Development and testing — free, offline, fast.
  • Air-gapped environments — where there is no external network at all.

When it is not

  • Frontier reasoning — the hardest tasks still need the best hosted models.
  • Tiny teams without ops capacity — running and scaling model inference is real operational work; a hosted API removes it.
  • Bursty low-volume traffic — you pay for idle hardware; a hosted API bills per use.

The pragmatic pattern many teams land on: local models for the easy, high-volume, or sensitive 80%, and a hosted model for the hard 20%. Routing between them is covered in small language models.

Next

Frequently Asked Questions

Why run a local LLM instead of a hosted API?
Three reasons: cost (local inference is free after hardware), privacy (data never leaves your infrastructure, which matters for regulated or sensitive content), and offline development (your test loop needs no network and no API key). The trade-off is quality — local models you can run on ordinary hardware are less capable than the frontier hosted models.
How do I switch Spring AI from OpenAI to Ollama?
Swap the starter to spring-ai-starter-model-ollama and configure spring.ai.ollama.base-url and the model name. Your ChatClient code does not change, because it depends on the ChatModel interface. This makes it easy to develop against a local model and deploy against a hosted one, or vice versa.
What hardware do I need to run Ollama?
Small models (1-3B parameters) run acceptably on a modern laptop CPU. Mid-size models (7-8B) benefit from 16GB+ of RAM and are much faster with a GPU. Larger models need a dedicated GPU with substantial VRAM. Start with a small model and only scale up the hardware if quality demands it.
Can I use local embeddings too?
Yes, and it is often a better default than a hosted embedding model for development. Ollama serves embedding models, and Spring AI also supports in-process ONNX embedding models that need no external service at all. Local embeddings remove cost and latency from your ingestion and test loops.

Related tutorials