Practice AI Projects for Free with Ollama Cloud Models

Every AI project needs an AI API. That part is unavoidable — you need a model to generate text, classify intent, summarize documents, or write code. The question is which API you point at while you are still figuring things out.For a long time I just reached for a paid provider. It worked, but it came with two problems I did not love.The first was **cost**. I could not tell in advance what a week of experimenting would cost. A retry loop here, a longer prompt there, and suddenly the bill is a number I did not plan for. There is no natural ceiling when you are the one writing the calls.The second was **key handling**. A paid API key is a secret that has to live somewhere. It lives in an environment variable, then in a `.env` file, then maybe in a shell profile, and one careless `git add` away from being public. If you are experienced you have rituals for this. If you are new to AI development, this is exactly the kind of sharp edge that ends a project early.Local models solve both problems. No bill, no key in your repository. But local inference has its own catch: it needs hardware. Running a 30B-class model on a machine without a serious GPU means the model is loaded into system RAM and partially onto the CPU, and your laptop fans spin up, the machine gets hot, and every other program slows down. On a modest development box, "run it locally" quietly becomes "run it locally and lose your afternoon".## The middle groundWhat I actually wanted was something with the ergonomics of a local model and the capability of a big one, without the bill and without handling a paid credential.**Ollama cloud models** give exactly that. A model tagged `-cloud` does not download any weights to your machine. Instead, your local Ollama server keeps a small manifest and proxies the request to Ollama's hosted inference. You keep talking to `http://localhost:11434`, the API surface stays identical, and the inference happens on someone else's GPU.The setup is three steps.## 1. Install OllamaDownload the installer for your platform from [ollama.com/download](https://ollama.com/download), or on Linux and macOS:```bash curl -fsSL https://ollama.com/install.sh | sh ```On Windows the installer puts `ollama` on your PATH. Verify it:```bash ollama --version ```## 2. Sign in and load a free cloud modelCloud models require an Ollama account. Sign in once:```bash ollama signin ```This prints a URL, you confirm in the browser, and your machine stores a key pair locally. Note what this key is *not*: it is not a paid API credential for a third-party provider, and it never gets embedded in your application code.Now load a cloud model:```bash ollama pull gemma4:31b-cloud ```Watch the size column afterwards:```bash $ ollama list NAME ID SIZE MODIFIED gemma4:31b-cloud ef09f235533c - Less than a second ago ```That `-` in the SIZE column is the point. A normal model shows something like `20 GB` because the weights were downloaded to your disk. A cloud model downloads a manifest of a few hundred bytes and nothing else. You get a 31B-parameter model with a 256K context window without giving up 20 GB of disk space or a single minute of GPU time.You can also chat with it directly to sanity-check it:```bash ollama run gemma4:31b-cloud ```## 3. Call it through the local OpenAI-compatible APIThis is the part that makes it useful for real projects. Ollama exposes an OpenAI-compatible endpoint at `http://localhost:11434/v1`, so the official OpenAI Python SDK works against it unchanged. You only change the base URL and the model name.```bash pip install openai ``````python from openai import OpenAIclient = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama", # required by the SDK, but not checked by Ollama )response = client.chat.completions.create( model="gemma4:31b-cloud", messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Summarize the CAP theorem in three sentences."}, ], )print(response.choices[0].message.content) ```That `api_key="ollama"` placeholder deserves a note. The OpenAI SDK refuses to send a request without an API key, so something has to be there. Ollama's local server does not validate it. Nothing secret is being smuggled into your project, and if you commit this file to Git, you have committed nothing sensitive.One detail that catches people out: **use the `-cloud` suffix in the model name.** Through the local server, `gemma4:31b-cloud` resolves to the hosted model, while `gemma4:31b` returns `model not found` because that tag refers to local weights you never downloaded. The hosted API at `ollama.com` uses the shorter name; the local proxy uses the one shown by `ollama list`.You can verify the raw endpoint with curl, which is handy when debugging:```bash curl http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "gemma4:31b-cloud", "messages": [{"role": "user", "content": "Say hello in one sentence."}] }' ```## Things worth knowing**Free is not unlimited.** The free tier includes a monthly allowance of starter usage credits and access to starter models, with a limited number of concurrent requests. When you outgrow it, you either add usage credits or move to a paid plan. Ollama meters cloud usage per token at each model's published rate, and gemma4 sits at $0.14 per million input tokens and $0.40 per million output tokens, so the credits drain slowly for normal experimentation. Check [your usage](https://ollama.com/settings/usage) and the [pricing page](https://ollama.com/pricing) for current numbers — the tiers change fairly often.**"Cloud" means the prompt leaves your machine.** This is the honest tradeoff. Ollama states that cloud prompts and responses are never logged and never used for training, and that it requires no-logging, no-training, zero-retention terms from the hosting providers it works with. That is a policy promise, not something you can verify from your desk. If a specific prompt is sensitive enough that you need to prove it never left, pull a local model instead — `ollama pull gemma4:e2b` runs fully offline. The `-cloud` suffix is the only signal that tells you where the inference happens, so keep it visible in your model names.**Cloud models are not local models.** `ollama ps` shows the difference clearly: a local model lists a size and a processor (`42 GB`, `100% GPU`), a cloud model shows neither, because your GPU never woke up.**The same setup works for coding agents.** Ollama can configure a coding agent to point at a cloud model in one command, which is useful if you want to drive an agent against a large model without a subscription:```bash ollama launch claude --model gemma4:31b-cloud ollama launch codex --model gemma4:31b-cloud ollama launch opencode --model gemma4:31b-cloud ```## Where I landedI now develop every AI feature against a cloud model first. The economics are right for practice: no subscription, no per-token meter I have to watch, no provider key in my repository. When a feature graduates to something real — with real users, real traffic, and a latency budget — switching to a paid endpoint is a two-line change, because the code already speaks the OpenAI protocol. The `base_url` and `model` are the only things that differ.That is the whole trick. `http://localhost:11434/v1` behaves exactly like a hosted API, so you can treat "no paid provider yet" as a configuration detail rather than a blocker. Pick a model name, point the SDK at localhost, and start building.

Read More

A Data Safety Incident in My App

I recently dealt with a data safety incident in an app I built with help from DeepSeek. For a while, the app could show an outdated local snapshot when it failed to load the latest server data. The screen looked normal, but a later save could treat that old snapshot as current and overwrite newer records. Some saved household data had to be restored manually.The immediate failure was only part of the problem. The app had no clear way to distinguish fresh, authoritative data from a local fallback, and its save behavior could replace more server data than the user had actually changed. A temporary sync problem had quietly become a data integrity problem.## What I changedI changed the app so ordinary saves update the records they receive instead of replacing an entire collection. Full replacement is now reserved for an explicit setup operation. I also reduced the number of separate database operations needed to load and save data, making the sync path less fragile as the amount of data grows.Most importantly, the client now knows whether its data has been confirmed by the server. If it has not, changes that could overwrite server data are blocked, and the interface makes the sync problem visible with a retry option. The app also records completed migrations on the server, so they do not depend on one browser's local storage.I added recovery and deployment safeguards, too: regular backups, diagnostics, and a smoke check that can catch an unexpected drop in saved records before a release is considered healthy.## What I learnedI used DeepSeek while building the app, and it helped me move quickly. But AI assistance does not change who is responsible for the behavior that ships. I still need to understand the assumptions in generated code, especially around persistence, retries, and what happens when a request fails.The biggest lesson is that cached data must not quietly impersonate confirmed data. A screen can look perfectly healthy while its underlying state is stale. And a save operation should not be more destructive than the user's intent: updating a few records should not put unrelated records at risk.I also learned to test failure paths as carefully as the happy path. A failed sync, a larger-than-usual dataset, or a fresh browser should be ordinary test scenarios, not surprises discovered after deployment. Backups and deployment checks matter, but the strongest protection is making unsafe writes impossible in the first place.This incident was stressful, but it pushed me to make the app more honest about its state and more careful with user data. Building quickly is useful; building systems that fail safely is part of finishing the work.

Read More

I switched from Postman to Bruno for API testing

I recently switched from Postman to [Bruno](https://www.usebruno.com/) for API testing and development. After using Postman for years, this change has been surprisingly refreshing. Here's why I made the switch and what I like about Bruno.## Why I left PostmanPostman is a powerful tool, but over time, a few things started bothering me:- **Cloud-first mentality**: Everything pushes you toward cloud storage and syncing. While you can work locally, it feels like a second-class citizen. - **Performance**: Postman can feel sluggish, especially when dealing with large collections or complex environments. - **Pricing**: The free tier is decent, but paid features can add up if you want team features and advanced functionality. - **Bloat**: There's a lot of UI and features I rarely use, which adds unnecessary complexity.## Why Bruno clicked for meBruno felt like a breath of fresh air because it's built differently:### Local-first, file-based collectionsBruno stores your API collections as plain text files (JSON or TOML format). This means: - Collections live in your project directory, not in the cloud - You can version control them with Git - No vendor lock-in or syncing confusion - It's simple and transparent### Lightweight and fastBruno is lightweight and snappy. The UI is clean and focused on what matters: building and testing API requests.### Open source and transparentBruno is [open source on GitHub](https://github.com/usebruno/bruno), which gives me confidence in the tool's longevity and the ability to contribute or fork if needed.### Works offlineSince everything is local-first, Bruno works perfectly offline without any cloud dependency or sync issues.### Environment variables and scriptingBruno has solid support for environment variables and pre-request/post-response scripting, similar to Postman but with a simpler interface.## The drawbacksTo be fair, Bruno isn't perfect:- **Smaller ecosystem**: Being newer and more niche, there are fewer integrations and plugins compared to Postman - **Team collaboration**: If you need real-time team collaboration, Postman's cloud features have an advantage - **Learning curve**: If you're used to Postman's specific workflow, there's a bit of adjustment## My workflow nowMy typical workflow with Bruno:1. Create a new collection in my project directory 2. Add requests organized by feature or endpoint 3. Define environment variables for different scenarios (dev, staging, production) 4. Write pre-request scripts to generate dynamic data or tokens when needed 5. Commit the collection to Git alongside my codeThis feels more aligned with how I work. Collections are part of my project, not separate artifacts floating in the cloud.## VerdictIf you value simplicity, local-first workflows, version control integration, and don't need heavy team collaboration features, Bruno is worth trying. It's especially great if you're already comfortable with tools that store config as files (like Docker Compose, Terraform, etc.).Give Bruno a shot—you might find it's the API testing tool you didn't know you were missing.

Read More

I built a time logger app for freelancers

I created a new app for people who need to track exactly how much time they spend on client work. It is especially useful for freelancers who juggle multiple clients and projects and need clean records for billing.## Why I built itI wanted something focused and lightweight: start tracking quickly, organize work by client and project, and turn tracked time into invoices and reports without extra setup.## Key features### Log time by project and clientTrack time entries against specific clients and projects so every billable hour is attached to the right work.### Manage clientsCreate and manage your client list in one place, making it easier to organize ongoing and completed work.### Manage projects with hourly rateSet up projects with a name and hourly rate. This helps calculate totals accurately for invoices and reports.### Share log details via URLNeed to show work details quickly? Share time log details using a simple URL.### Generate invoices and reportsConvert tracked time into invoice-ready summaries and clear reports for clients or your own records.### Simple, fresh, responsive UIThe app is designed to stay clean and fast on both desktop and mobile.## Screenshots Dashboard view Manage project details Client management Invoice and report view Shared log detailsIf you are freelancing and want a practical way to track time, share proof of work, and bill confidently, this app is built for you.## Try it now[Open Time Logger](https://tl.momane.com)## ThanksBig thanks to Cloudflare, Neon, and Resend, their generosity and support make this happen.

Read More

I created a new app called IronTrack

IronTrack is my new mobile app for anyone who wants a simple, motivating way to plan gym sessions and track every workout. I built it to remove the friction between "I should train" and "I did train" by making plans easy to create and logging fast and reliable.## Why I built IronTrackI wanted one place to plan workouts, stick to them, and see progress without a dozen taps. IronTrack focuses on the essentials: smart plans, manual control, streaks, and precise tracking for every set.## Key features### AI plan generatorTell IronTrack your height, weight, age, and goal, and it builds a plan for you. This is great if you want a quick, reasonable starting point without spending hours researching routines.### Manual plan builderPrefer full control? Build a plan by hand. Add exercises, customize sets and reps, and tweak things anytime.### StreaksConsistency matters. IronTrack shows your streaks so you can keep the momentum and see your habits build over time.### Detailed workout trackingLog every workout with time, reps, weight, and exercise name. IronTrack keeps it clean and fast, so you can stay focused on training.## Screenshots Dashboard IronTrack Plans Tracking workout Exercise details Finish screen History screen AI plan builder Chinese version Workout history Exercise library## How to get started1. Create a plan with AI or build one manually. 2. Start your workout and log time, reps, and weight as you go. 3. Keep your streak alive and watch your history grow.## ShoutoutsBig thanks to Cloudflare, GitHub, and Neon for their generous free tiers. They made it much easier to ship IronTrack and keep costs low while I built and tested the app.If you want a clean, focused gym tracker that still feels smart, IronTrack is for you. I would love feedback and feature requests as I keep improving it.

Read More