Pixeltable and Mixpeek
Updated
Which is better, Pixeltable or Mixpeek?
It depends. Mixpeek belongs when you want a managed multimodal retrieval API: connect a bucket, extract scenes, speech and OCR, and search over HTTP without running models. Pixeltable belongs when the clip, the timestamp, the index and HTTP should live in one app.py you own. Keep Mixpeek if the hosted retriever is the product. Pixeltable Cloud is Limited Beta. As of 2026-10-23.
Mixpeek is a managed retrieval API: connect a bucket, extract scenes, speech and OCR, and search over HTTP. Pixeltable is the application schema those results can live on. Often complementary, not exclusive: call Mixpeek when the hosted retriever is the product, and keep the clip in a Video column you own when the table is the product.
pip install 'pixeltable[serve]'Managed retrieval API vs the table
| Side | Pixeltable | Mixpeek |
|---|---|---|
| At a glance |
|
|
What each actually owns
Mixpeek wins a hosted multimodal extraction and retrieval API with no models to run. Pixeltable wins the owned catalog, incremental insert, and HTTP beside the clip. Last reviewed: Oct 2026. Sources: mixpeek.com, mixpeek.com/video-search, docs.mixpeek.com/docs/overview/quickstart (accessed 2026-10-23).
| Feature | Pixeltable | Mixpeek |
|---|---|---|
| What it is | Application schema: store, transform, index, serve | Managed multimodal retrieval API |
| Where the clip lives | A Video column you query, version, and attach other columns to | An existing bucket Mixpeek can read in place, or a Mixpeek bucket you upload into |
| Who runs the models | You, locally or on Cloud (Limited Beta) | Mixpeek, unless you bring your own vectors or deploy BYO-Cloud |
| Insert a new file | Insert a row; frames and the index run for that clip | Upload or connect the object, trigger the collection, poll the task |
| Search API | column.similarity(...) on the frame view you own | retrievers.execute against a hosted retriever |
| Images, PDFs, HTTP you own | Same schema: Image, Document, FastAPIRouter | Same API family for video, image, audio, documents; not an application table |
| Self-host | pip install pixeltable; Cloud is Limited Beta | Your own cloud (BYO-Cloud) (mixpeek.com FAQ, accessed 2026-10-23) |
Index a folder of videos and search by text
Pixeltable: frame_iterator view and CLIP EmbeddingIndex. Apply with pxt schema update app.py video_lib. Mixpeek: the quickstart creates a Mixpeek bucket, uploads into it, triggers the collection once, polls tasks.get, creates a retriever, then retrievers.execute with inputs query_text. Connecting an existing bucket is a separate FAQ path. Snippets from docs.mixpeek.com/docs/overview/quickstart (accessed 2026-10-23); not executed here (needs a Mixpeek API key and plan).
Pixeltable
import pixeltable as pxtfrom pixeltable.functions.huggingface import clipfrom pixeltable.functions.video import frame_iteratorfrom pixeltable.serving import FastAPIRouterTableModel = pxt.model_base()clip_embed = clip.using(model_id='openai/clip-vit-base-patch32')class Videos(TableModel, name='videos'):title: pxt.Stringvideo: pxt.Videoclass Frames(TableModel,name='frames',base=Videos,iterator=frame_iterator(video=Videos.video, fps=1),):__indexes__ = [pxt.EmbeddingIndex(frame, embedding=clip_embed)]@pxt.querydef search_video(query: str, limit: int = 5):sim = Frames.frame.similarity(string=query)return (Frames.order_by(sim, asc=False).limit(limit).select(title=Videos.title, frame_attrs=Frames.frame_attrs, score=sim))api = FastAPIRouter(name='video_lib')api.add_insert_route(Videos, path='/videos', inputs=[Videos.title], uploadfile_inputs=[Videos.video])api.add_query_route(path='/search', query=search_video)
Mixpeek
import osfrom mixpeek import Mixpeekclient = Mixpeek(api_key=os.environ['MIXPEEK_API_KEY'])ns = client.namespaces.create(namespace_name='video-demo')client.namespace = ns['namespace_id']bucket = client.buckets.create(bucket_name='demo-videos',bucket_schema={'properties': {'video': {'type': 'video'}}},)# This quickstart creates a Mixpeek bucket and uploads into it.# An existing S3, GCS, or Azure bucket is the separate FAQ path.col = client.collections.create(collection_name='video-scenes',source={'type': 'bucket', 'bucket_ids': [bucket['bucket_id']]},features=['video_search'],)client.buckets.upload(bucket['bucket_id'],blobs=[{'property': 'video','type': 'video','data': 'https://example.com/lecture.mp4',}],)result = client.collections.trigger(col['collection_id'])task = client.tasks.get(task_id=result['task_id'])# Repeat tasks.get until task['status'] is COMPLETED or COMPLETED_WITH_ERRORS.# Do not call collections.trigger again to poll.ret = client.retrievers.create(retriever_name='video-search',input_schema={'query_text': {'type': 'text', 'required': True}},collection_identifiers=[col['collection_id']],stages=[{'stage_name': 'search','stage_type': 'filter','config': {'stage_id': 'feature_search','parameters': {'searches': [{'feature_uri': 'mixpeek://universal_extractor@v1/gemini-embedding-2','query': {'input_mode': 'text', 'value': '{{INPUT.query_text}}'},'top_k': 50,}],'final_top_k': 20,},},}],)results = client.retrievers.execute(ret['retriever_id'],inputs={'query_text': 'person at a whiteboard'},)for doc in results['documents']:print(doc['document_id'], doc.get('start_time'), doc['score'])
When each belongs
Use Pixeltable when
- You need the clip next to other columns
Transcripts, detections, documents, and HTTP in one file. Mixpeek can still be the retriever you call from a computed column or a route.
- A coding agent writes the app
One app.py to review. pip install pixeltable. Pixeltable Cloud is Limited Beta, not GA.
Use Mixpeek when
- A managed video search API is the product
You want extraction and retrieval over HTTP without running CLIP or Whisper. Pixeltable is extra if the API response is enough.
- You already pay for Mixpeek
Keep it. Point Pixeltable at the same bucket when you also need an owned table; otherwise stay on their SDK. Docs: https://www.mixpeek.com/docs/overview/quickstart
Making the right choice
And, not or
- Do not migrate off Mixpeek just to complete the stack. Keep it if the hosted retriever is the contract.
- The homepage FAQ says Mixpeek can read an existing S3, GCS, Azure, or S3-compatible bucket in place (accessed 2026-10-23). The code sample uses the quickstart: a Mixpeek bucket you upload into.
- Managed path: namespaces.create, buckets.create, collections.create with features, upload, trigger, retrievers.execute (quickstart, accessed 2026-10-23).
- Build starts at $25/mo plus usage for both MVS and Managed (mixpeek.com pricing, accessed 2026-10-23). Confirm current rates on their site.
Frequently asked questions
More comparisons
- Three-way compare: Pixeltable vs Supabase vs Convex
- 11 free cloud database & compute tiers compared
- Pixeltable vs Neon
- Supabase alternative: Pixeltable vs Supabase
- Pixeltable vs Prisma Postgres
- Pixeltable vs Turso
- Pixeltable vs Convex
- Pixeltable vs Modal
- Pixeltable vs Cloudflare
- Pixeltable vs Railway
- Pixeltable vs Render
- Pixeltable vs Fly.io
- Pixeltable vs Cohesivity
- Pixeltable vs LangChain
- Pixeltable vs LanceDB
- Pinecone alternative: Pixeltable vs Pinecone
- Pixeltable vs Weaviate
- Pixeltable vs Twelve Labs
- Pixeltable vs Daft
- Pixeltable vs Airflow
- Pixeltable vs Label Studio
- Pixeltable vs Voxel51
Keep the clip. Call a retriever if you need one.
Declare a Video table and a frame view. Apply with pxt schema update. Use Mixpeek when a managed video search API is the product.