---
title: "Why the Local-Cloud Loop Matters"
date: "2026-08-27"
author: "Pierre Brunelle"
tags:
  - Pixeltable Cloud
  - Developer Experience
  - MLOps
  - Local LLM
  - AI Infrastructure
  - Multimodal AI
description: "Cloud-only platforms trained teams to rent a cluster before they could iterate. Pixeltable is one engine on a laptop and in Cloud: local first, then the same app.py — mix local models, cloud APIs, or full cloud execution."
url: "https://www.pixeltable.com/blog/why-local-cloud-loop-matters"
---

# Why the Local-Cloud Loop Matters

**Summary:** Snowflake, Databricks, and Kafka-style products made a generation of teams rent a cluster before they could iterate. That is the right shape for a shared warehouse. It is the wrong shape for multimodal AI, where the productive loop is closer to machine learning: explore a slice of data, change a transform, look at the failures, try again. Pixeltable unifies storage, orchestration, and serving into one framework, so the same engine runs on a laptop and in Cloud. The CDLC — the continuous development lifecycle — is a local-first development loop: apply one `app.py`, iterate, then promote that file. You can run local execution with cloud APIs, local execution with local models, or full cloud execution, and move between those setups without restaging the world.

 
## The Cluster Tax

 
Cloud data platforms earned their place. A warehouse that many teams query, a lakehouse that many jobs write, a log that many services publish to — those are shared production systems. The natural unit of work is a cluster. Local is an SDK talking to that cluster, or a notebook attached to it.

 
The cost shows up the moment you want to *develop*. Reproducing Snowflake, Databricks, or a Kafka topology on a laptop is not a weekend project. So teams buy a second cluster and call it staging. Staging drifts. Staging is expensive. Staging is where you wait for a queue so you can find out that a UDF failed on one video.

 
That tax is not malice. Those products optimized for shared production data, not for a multimodal laptop loop. Video, frames, transcripts, and embeddings are awkward guests in a warehouse: too large to casually clone, too derived to treat as a SQL extra, too experimental to schedule as a nightly job. If the engine only exists as a cloud, iteration inherits the cloud's latency, bill, and permission model.

 
We have written about [iterating on data instead of infrastructure](/blog/iterate-on-data-not-infrastructure) inside one catalog. This post is about *where* that catalog is allowed to live. If it cannot live on your machine, you do not have a development loop. You have a reservation system.

 
## Branching Is a Cloud Answer. The Loop Is an ML Answer.

 
The database industry noticed the same pain and shipped branching. Copy-on-write clones, Neon-style branches, warehouse zero-copy clones: get an isolated cloud database without waiting for a full restore. That is a good answer to "I need a sandbox of production SQL."

 
It is still a *cloud* answer. The branch is another remote. Your media is still in the warehouse's object store. Your transforms still run where the platform runs. You have isolation. You do not have a laptop.

 
An ML-style loop wants different things:

 

 - A **small slice of media** you can actually look at

 - **Fast recompute** when you change a model or a prompt, not a job you submit

 - **Failed-row inspection** on the same machine that wrote the schema — `pxt dashboard` on localhost, not a ticket to platform

 - The **same declarations** when you are ready for Cloud, not a rewrite into the warehouse dialect

 

 
That is closer to how people actually train and evaluate models than to how people branch Postgres. Database branching copies a remote. A local-first development loop lets you close the feedback cycle on the data in front of you, then promote. For why an HTTP handler next to a branched database is still not a multimodal table, see [Neon Functions vs Pixeltable computed columns](/blog/neon-functions-vs-pixeltable-computed-columns).

 
## One Artifact, Two Runtimes

 
Unification is what makes the loop possible. If storage is S3, orchestration is Airflow, and retrieval is a vector database, "run it locally" means reproducing three clouds. If those are one catalog, "run it locally" means `pip install pixeltable`.

 
The artifact is one Python file: tables, computed columns, indexes, and HTTP routes. You apply it to a local target, serve it, and apply the same file to Cloud with the same three update verbs. `pxt service run` is local only.

 
```bash
pxt service example --out app.py
pxt schema update app.py my_app
pxt service update app.py my_app
# same file, hosted
pxt db update pxt://org:db
pxt schema update app.py pxt://org:db
pxt service update app.py pxt://org:db
```

 
Nothing in that sequence is "export a replica and hope the other environment has the same operators." Promotion is the schema you already iterated. Serve is the same file against a local dir or `pxt://`. That is the product loop we describe as Declare → Experiment → Serve, and it is why pricing can say [host the same app you run locally](/pricing).

 
The catalog itself can live under `PIXELTABLE_HOME` on a machine you control, including in Docker. See [Docker volumes and PIXELTABLE_HOME](/blog/pixeltable-docker-volumes-pixeltable-home) and the [local dashboard](/blog/pixeltable-local-dashboard-browse-debug-pipelines) for browsing lineage and failed computed columns without standing up an admin app.

 
## Three Hybrid Setups You Actually Want

 
Local versus cloud is not a boolean. Multimodal work is a mix of where *compute* runs and where the *model* runs. Because transforms are columns, you change the function, not the pipeline.

 
### Local execution, cloud APIs

 
The catalog is on your laptop. Inserts and incremental recompute happen there. The column calls OpenAI, Gemini, or another hosted model. You pay for tokens, not for a staging warehouse. This is the default when you want frontier quality and a tight loop on a handful of videos or documents.

 
### Local execution, local models

 
Same catalog. Swap the function for Ollama, llama.cpp, or vLLM. Media never leaves the machine. This is the privacy and cost loop: iterate on prompts and chunking against open weights, then decide whether production should stay offline. We documented the Ollama path in [Run local LLMs with Pixeltable](/blog/ollama-local-llm-pixeltable).

 
```python
# same column shape; swap the provider
summary = openai.chat_completions(
 messages=[{'role': 'user', 'content': title}],
 model='gpt-4o-mini',
).choices[0].message.content

# later, same table, local model
summary = ollama.chat(
 messages=[{'role': 'user', 'content': title}],
 model='llama3.2',
).message.content
```

 
### Full cloud execution

 
When the slice is no longer a slice — more media, more concurrent inserts, a team that should not share a laptop catalog — apply the same `app.py` to `pxt://org:db`. The declarations do not change because the engine did not change. You are not translating a notebook into a Databricks job so staging can resemble prod.

 
### Balancing the three

 
Cost, privacy, latency, and GPU availability pull in different directions. A useful default:

 

 - **Explore locally** with a cheap or local model on a sample.

 - **Validate** the same columns against a cloud API on that sample.

 - **Promote** the file when the schema is stable, and keep coming back to the laptop when the next experiment is cheaper there.

 

 
The loop is bidirectional. You promote to Cloud. You also pull a production *shape* back — the same models, the same columns — onto a local catalog with a smaller insert set. That is how you debug a bad row without cloning a cluster.

 
## Why Unification Is the Prerequisite

 
You cannot reproduce five cloud services locally in a way that stays honest. You can run one catalog. That is why unifying storage, orchestration, and serving is not a packaging story. It is what makes a local-first development loop possible at all.

 
Once the engine is the same in both places, the lifecycle is boring in the way Git is boring:

 

 - Explore a slice of media on the laptop.

 - Change a column or an index.

 - Recompute only what the lineage says changed.

 - Inspect failures in the local dashboard.

 - Promote the same `app.py` to Cloud.

 - Come back to the laptop for the next experiment, including hybrid model choices.

 

 
That is the continuous development lifecycle without a staging cluster as the unit of progress. Experimentation inside the catalog is covered in [iterate on your data, not your infrastructure](/blog/iterate-on-data-not-infrastructure). The persona version of shrinking the surface — Lovable for non-technical builders, Pixeltable for developers — is [Making Multimodal More Lovable](/blog/making-multimodal-more-lovable). The declaration in that file is class-based `TableModel`: [Never Fuck With Your Backend Anymore](/blog/never-fuck-with-your-backend-anymore).

 
## People Also Ask

 
**Why not just use a staging Databricks workspace?** Staging is a second cloud. It helps when the engine only exists remotely. It does not give you a laptop loop over video and embeddings, and it does not make "change this column" incremental. If your workload is SQL on a lakehouse, staging may be enough. If your workload is multimodal derivation, you want the engine itself to run locally. See [Databricks LTAP/HTAP and the multimodal data plane](/blog/databricks-ltap-htap-multimodal-data-plane-pixeltable).

 
**Is this the same as database branching?** No. Branching isolates a remote database. A local-cloud loop runs the same engine on your machine and in Cloud. You can still isolate data by using a smaller local catalog. You do not need a clone of production to change a computed column.

 
**Can I mix local models and cloud APIs?** Yes. Computed columns are functions. Point one column at Ollama and another at Gemini, or swap a provider when you promote. Orchestration does not change because it was never a separate DAG.

 
**What gets promoted — the data or the app file?** The app file. `pxt schema update app.py pxt://org:db` applies tables, computed columns, indexes, and routes. You insert production media against the hosted catalog. You do not zip a laptop dataset and call that deploy. Retired publish/replicate APIs are not the path.

 
## Keep the Loop Close

 
Cloud-only platforms made iteration a reservation. Branching made isolation cheaper without making development local. Multimodal AI needs the loop machine learning already knew: a slice of data, a change, a look at what broke, then promotion of the thing you actually ran.

 
Unify the engine. Run it on the laptop. Promote the same file. Come back. That is why the local-cloud loop matters.

 

 - **[The Unified Multimodal Backend Agents Build With](/blog/unified-multimodal-backend-agents-build-with)**: the identity essay — one file is the backend

 - **[Making Multimodal More Lovable](/blog/making-multimodal-more-lovable)**: the sibling essay on persona and surface area

 - **[Never Fuck With Your Backend Anymore](/blog/never-fuck-with-your-backend-anymore)**: class-based `TableModel` and the 2026 recap

 - **[I Vibe-Coded a Google Photos Clone. Then I Tried AWS.](/blog/i-vibe-coded-google-photos-clone-then-tried-aws)**: Mac to Cloud is the same file — AWS and the Supabase worker are the hangover

 - **[Get started](/get-started.md)**: install, Skill, and the one-file loop

 - **[Pricing](/pricing)**: host the same app you run locally

 - **[Pixeltable documentation](https://docs.pixeltable.com)**