← All writing
aiengineeringlocal-ai

I turned an old Mac into my own AI server

LAMA started as a weekend experiment with an M1 Pro. It ended with a local model, a real network service, and a much better understanding of what "local AI" actually means.

I had an M1 Pro MacBook sitting around and one question: how much AI can I actually run on this thing?

Not through an API. Not by sending a prompt to somebody else's data center. On the Mac, in my apartment, using its own memory and GPU.

That question turned into LAMA: Local AI Machine Assistant.

Running locally. Built by Lamadrid.

First, I had to stop treating "AI" as one thing

This was the useful part.

Before touching local models, words like model, runtime, agent, context and inference had a tendency to collapse into one big blob called AI. Building the stack myself forced the pieces apart.

The model is the brain. Right now that's Qwen 3.5 9B.

Ollama is the runtime. It loads the model and exposes an API.

The M1 Pro is the machine doing the compute.

And LAMA is becoming the system around all of that. The interface, configuration, local network access and, eventually, the useful stuff on top.

That distinction sounds obvious once you know it. I didn't really know it until I could point at every layer running on my desk.

The little M1 did better than I expected

The machine is a 2021 M1 Pro with 16 GB of unified memory and a 16-core GPU. Nothing exotic.

I loaded Qwen 3.5 9B in Q4_K_M quantization, roughly a 6.6 GB model package, through Ollama. Generation landed around 21.7 tokens per second with the model running on the GPU.

Then I started changing one thing at a time.

At a 4K context, Ollama reported a runtime footprint around 5.5 GB. At 16K it was about 6.0 GB. At 32K, 6.6 GB. At 64K, 7.8 GB. No swap during those tests.

That made context windows real for me. "Supports 262K context" is a capability on a spec sheet. "How much context is sensible on this machine?" is an engineering question.

Same with reasoning. With thinking enabled, one test generated 4,064 tokens and took a little over three minutes. With thinking disabled, the comparable answer generated 299 tokens and finished in about 19 seconds including a cold load. The raw generation rate barely changed.

The model wasn't suddenly slow because it was thinking. It was doing a lot more work.

Then localhost stopped being enough

Running a model in Terminal is cool for about ten minutes.

I wanted the M1 to behave like a server and my M5 Air to behave like a client.

So the architecture became:

M5 Air → Wi-Fi → M1 Pro → Ollama → Qwen → Metal GPU → response.

The first request from the M5 failed.

Good.

That failure taught me more than another successful ollama run would have. Ollama was listening on localhost, which meant the service existed only from the M1's point of view. Binding it to 0.0.0.0:11434 made it reachable on the local network.

A curl from the M5 returned the model metadata. Then another request generated a response on the M1 and sent it back across the room.

Tiny thing. Very satisfying.

The annoying bug was the best lesson

I wanted the server to survive a reboot without me opening Terminal.

The first setup looked correct. macOS started Ollama. A LaunchAgent set OLLAMA_HOST=0.0.0.0:11434. The variable existed. The job had run successfully.

And after a reboot, the M5 still couldn't connect.

The problem was timing.

Ollama had already started before the environment variable was set. Processes inherit their environment when they start. Changing the environment afterward does not travel backward in time and mutate an already-running process.

Restart Ollama after setting the variable and everything worked.

There was the bug.

The final design is simpler. macOS launchd directly owns ollama serve, and the OLLAMA_HOST variable belongs to that job. RunAtLoad starts it. KeepAlive keeps it alive.

Then came the test that mattered: reboot the M1, don't open Terminal, don't manually start Ollama, wait, and call the API from the M5.

Qwen came back.

That was the moment the experiment became infrastructure.

So what is LAMA now?

Right now, LAMA is small.

It is an M1 Pro acting as a persistent local AI server, an Ollama runtime, a Qwen model, and another Mac successfully talking to it over my LAN.

The next layer is the fun one: give it a face.

I want to build a simple LAMA web interface so the M5, an iPhone or another device can talk to the server without living in curl. After that come the interesting questions around models, memory, files, tools and agents.

But I don't want to skip the boring layers to get there.

That's kind of the point of this project.

I could have installed a polished UI and called it done. Instead I now know what the model is, what the runtime is, where the memory goes, what a token costs, what localhost means, why a port matters, how a macOS service starts, and exactly why my first persistence setup failed.

The local AI server is useful.

Understanding the machine underneath it might be the more valuable thing I built.

Lamadrid Labs © 2026