---
title: "Cloud database and compute providers: 11 free plans compared"
description: "Eleven free cloud plans compared on limits and dormancy, plus a recorded US-East run. A chart includes only the providers timed on that path."
url: "https://pixeltable.com/compare/cloud-providers"
---

# Cloud database and compute providers: 11 free plans compared

Eleven free plans compared on storage, compute, and dormancy. The charts are one recorded run from AWS US-East. A provider appears on a chart only when that path was timed.

## 11 Providers with Genuine Free Plans ($0.00 / Month)

Every provider tested in this shootout is running on its authentic zero-dollar free tier without negotiated enterprise quotas.

| Provider | Category | Plan | Storage | Compute / Quota | Dormancy Rule | Hidden Costs / Wedge |
| --- | --- | --- | --- | --- | --- | --- |
| Pixeltable Cloud | AI Data & Workflow | Community Free | 50 GB media storage, 10 GB database storage | Hosted compute included | No forced sleep or auto-pause; always-warm schema & endpoints | Zero. ffmpeg, Whisper, CLIP & vector indexing run in-schema; no external orchestrators or vector DBs needed. |
| Railway | Compute & Hosting | Trial ($5 Credit) / Hobby ($5/mo) | Shared container disk / persistent volume | $5 monthly credit (approx. 500 execution hours total) | Sleeps or shuts down when $5 credit exhausts; 24/7 Postgres burns out in ~20 days | Railway as Postgres: template runs raw PostgreSQL 16 container that drains the $5 credit 24/7. Zero built-in multimodal, vector indexing, or pipeline triggers. |
| Render | Compute & Hosting | Free Web Service | Ephemeral container filesystem | 750 free instance hours/month (512 MB RAM) | Spins down after 15 minutes of inactivity (50s cold start); Free Postgres deleted after 30 days | Render as Postgres: free tier PostgreSQL databases expire and are permanently wiped after 30 days! Free web services suffer 50s cold starts after 15m idle. |
| Cloudflare | Edge Network | Free Plan | 5 GB D1 SQLite, 10 GB R2 object storage | 100,000 Workers requests/day, 5M D1 reads/day, 5M Vectorize queries/mo | Always warm across 300+ global edge locations; 0ms cold starts | Cloudflare D1 & Vectorize: Workers free plan has a hard 10ms CPU time limit. V8 isolates cannot run Python ML libraries (PyAV, Whisper, PyTorch). Must hop to Workers AI or external GPU clusters. |
| Modal | Compute & Hosting | Free Tier ($30/mo Credit) | Ephemeral container disk + volume storage | $30/month recurring compute credit | Containers shut down when idle (zero cost while inactive; 1-2s container cold boot) | Stateless: must maintain an external database and object store to persist state and query embeddings. |
| Neon | Serverless Database | Free Tier | 1 GB storage per project | 100 compute unit (CU) hours/mo | Compute scales to zero after 5 minutes of idle (1-3s wake-up cold start) | Requires external queue workers, object storage, and custom migration scripts for AI model updates. |
| Supabase | Serverless Database | Free Tier | 500 MB database, 1 GB file storage | Shared compute, 500k Edge Function invocations/mo | Projects automatically paused after 7 days of inactivity | External compute service required for heavy media transforms (Deno runtime cannot run ffmpeg/Whisper); manual vector backfill scripts. |
| Turso | Serverless Database | Starter Free | 5 GB total storage | 500M row reads/mo, 10M row writes/mo | No inactivity pause; always available | Requires external file storage for media and custom Python workers to encode vectors before insertion. |
| Prisma Postgres | Serverless Database | Public Beta Free | 500 MB storage | Shared compute pool | No forced sleep during public beta | Requires external worker processes for media processing and model inference; manual backfill scripts. |
| Convex | Serverless Database | Free Plan | 1 GB file & document storage | 1 Million function calls/mo | No dormancy pause on active free accounts | Requires external HTTP compute service to run ffmpeg or local ML models; action/mutation hopping. |
| Vercel | Compute & Hosting | Hobby Free | Edge KV / Blob / Postgres (via partner integrations) | 100,000 serverless function executions/mo, 100 GB-hours | Scale-to-zero serverless lambdas; cold starts on idle wake | Stateless frontend platform: requires external database and background task workers for long-running ETL. |

## Critical Provider Deep-Dives: Free Tier Policies & Traps

### Railway as Postgres: The $5 Trial Credit Burn (Container PaaS)

**Summary:** Railway provides a one-click PostgreSQL template in its marketplace that spins up an isolated Docker container with a persistent volume.

- **Critical Policy:** Railway grants a $5 monthly trial credit (approx. 500 execution hours). A persistent PostgreSQL database must stay alive 24/7 (720 hours/month). Running Postgres alone burns the entire $5 credit in ~20 days. When paired with a web application, credit expires in under 12 days, shutting down the entire project unless upgraded with a credit card.
- **Architectural Limitation:** Vanilla containerized Postgres without native multimodal primitives or automated embedding pipelines. Developers must build custom Dockerfiles for extensions, write custom Python workers for inference, and coordinate external vector/blob storage.
- **Cost & Dormancy Trap:** While blazing fast for pure stateless HTTP compute (435 req/s), using Railway as a free persistent database leads to mid-month surprise shutdowns.
- **Verdict:** Great for temporary Docker prototyping, but unsustainable as a permanent free database without automated hibernation or adding a payment method.

### Render as Postgres: The 30-Day Hard Deletion Rule (30-Day Ephemeral)

**Summary:** Render offers a managed PostgreSQL service alongside its free container web services.

- **Critical Policy:** Render Free Postgres instances expire and are permanently deleted after 30 days. Render does not pause or snapshot the database; after 30 days the database is wiped unless upgraded to a paid tier ($7/mo minimum). Additionally, free web services spin down after 15 minutes of inactivity with a 50-second cold start.
- **Architectural Limitation:** 1 GB storage ceiling with 100 max connections, but zero vector search extensions preconfigured and zero ML runtime capabilities.
- **Cost & Dormancy Trap:** Developers unaware of the 30-day lifecycle risk total data loss if they build permanent applications or benchmarks on Render free Postgres.
- **Verdict:** Strictly a temporary 30-day test sandbox. Never rely on Render free Postgres for continuous production state.

### Cloudflare D1 & Vectorize: Edge SQLite with the 10ms CPU Ceiling (Edge SQLite + V8)

**Summary:** Cloudflare offers D1 (edge SQLite with 5M reads/day, 100k writes/day, 5 GB storage) and Vectorize (vector index with 5M queries/mo and 200k vectors) running inside Workers.

- **Critical Policy:** Free Workers are bound by a strict 10ms CPU execution time limit per request (Standard Free ceiling). While Anycast edge reads are ultra-fast (11.6ms), Workers cannot execute CPU-intensive tasks.
- **Architectural Limitation:** The V8 isolate runtime cannot execute native Python AI packages (PyAV, OpenCV, Whisper, PyTorch, sentence-transformers). D1 also enforces a single primary writer architecture with eventual consistency for edge read replicas.
- **Cost & Dormancy Trap:** To build multimodal AI, developers cannot process media inside Cloudflare Workers. They must call Workers AI (consuming neural compute tokens) or route requests to external GPU workers (Modal, RunPod, AWS), creating network hop latency and multi-vendor dependency.
- **Verdict:** Unbeatable for ultra-low latency edge reads and JSON routing, but completely blocked from native multimodal media pipelines.

## Operational Path 1: Stateless Serverless Compute

Measuring pure transformation and compute execution latency, CPU limits, cold start delay, and burst throughput.

| Platform | Architecture | Warm p50 | min | Burst (req/s) | Cold Start | CPU / Time Limit | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Cloudflare Workers | Global Edge V8 Isolates (300+ PoPs) | 11.6ms | 10.7ms | 395.5 req/s | < 5ms worldwide (zero container overhead) | 10ms CPU time per invocation (Standard Free plan ceiling) | Fastest warm p50 and lowest latency, but cannot execute Python AI packages (PyAV, Whisper, PyTorch). |
| Railway | Container PaaS (Docker / Nixpacks) | 25.9ms | 24.4ms | 435.2 req/s | ~2s (if configured to sleep; always-on consumes credits) | 0.5 - 1.0 vCPU shared | Highest burst throughput in the shootout (435.2 req/s); burns credit in 20 days if left running 24/7. |
| Render | Container Cloud (Web Service) | 27.0ms | 22.5ms | 128.4 req/s | ~50 seconds after 15m idle sleep | 0.5 vCPU shared | Low warm p50 (27ms) when active, but 50s cold start creates massive user-visible delays on dormant wake-up. |
| Vercel | Serverless Functions on AWS Lambda | 94.9ms | 90.9ms | 238.7 req/s | 200ms - 800ms on lambda scale-up | 10s maximum execution duration (Hobby plan) | Strong concurrency burst scaling (238.7 req/s), but 10s execution timeout kills long-running media processing. |
| Pixeltable Compute | Managed Service Worker Route (/ingest/titles) | 104.4ms | 102.8ms | 56.1 req/s | None (always-warm managed endpoint) | Shared community cluster compute | Stateless transformation route in Pixeltable service; widened burst buffer (burst=100 delay=50) delivers 56.1 req/s burst. |
| Modal | Serverless Cloud Containers with on-demand GPU/CPU | 271.3ms | 266.0ms | 27.3 req/s | 1.2s - 2.5s container initialization | Customizable up to 64 vCPU & H100 GPUs | Higher HTTP proxy overhead (271ms) due to container routing layer, but unmatched on-demand GPU compute power. |

## Operational Path 2: Point Reads & Scans (SELECT 10 rows, US-East)

Sequential point/range query read latency for database and edge providers. Lower ms is better.

| Platform | Category | p50 Latency | min | Query Type | Status |
| --- | --- | --- | --- | --- | --- |
| Cloudflare Workers | compute | 11.6ms | 10.7ms | Edge V8 Isolate response | 200 OK |
| Railway Postgres | database | 22.1ms | 21.6ms | Direct SELECT via TCP proxy | 200 OK |
| Turso libSQL | database | 65.4ms | 64.2ms | SELECT 10 rows (HTTP pipeline) | 200 OK |
| Neon Serverless PG | database | 65.7ms | 64.8ms | SELECT 10 rows (SQL proxy) | 200 OK |
| Render Postgres | database | 66.1ms | 64.6ms | Direct SELECT via Virginia SSL | 200 OK |
| Prisma Postgres | database | 90.9ms | 90.0ms | SELECT 10 rows (asyncpg pool) | 200 OK |
| Convex | database | 99.4ms | 82.5ms | db.query("docs").take(10) | 200 OK |
| Supabase PostgREST | database | 111.4ms | 93.0ms | GET ?select=*&limit=10 | 200 OK |
| Pixeltable Query | database | 112.5ms | 105.2ms | Table select & filter query | 200 OK |
| Modal | compute | 186.4ms | 181.4ms | FastAPI ASGI GET /read | 200 OK |

## Operational Path 3: Single Row Ingest & Writes

Measuring sequential single-row insert latency and transactional write mechanisms.

| Platform | p50 Latency | min | Burst Write (req/s) | Write Mechanism | Durability Architecture |
| --- | --- | --- | --- | --- | --- |
| Railway Postgres | 67.0ms | 65.7ms | 375.5 req/s | Direct SQL INSERT over TCP proxy | PostgreSQL WAL commit |
| Neon Serverless PG | 68.3ms | 66.9ms | 199.5 req/s | Direct SQL INSERT over WebSocket/HTTP pooler | ACID WAL flush to cloud storage architecture |
| Turso libSQL | 90.7ms | 83.4ms | 31.4 req/s | HTTP pipeline POST execute with remote WAL sync | SQLite WAL committed to primary writer |
| Prisma Postgres | 98.6ms | 97.4ms | 57.6 req/s | Single SQL INSERT over asyncpg connection pool | PostgreSQL WAL commit via edge pooler |
| Convex | 99.4ms | 82.5ms | 136.5 req/s | Reactive mutation handler commit to document table | Deterministic STM (software transactional memory) |
| Supabase PostgREST | 116.2ms | 83.9ms | 174.7 req/s | PostgREST HTTP POST with JSON body into Postgres 17 | PostgreSQL synchronous commit WAL |
| Pixeltable Ingest (Async Job) | 68.5ms | 67.8ms | 96.6 req/s | Immediate HTTP ACK with Job ID + background DAG worker execution (background=True) | ACID PostgreSQL record + immutable version snapshot |
| Pixeltable Ingest | 128.3ms | 124.9ms | 14.2 req/s | Versioned table row insert + automatic computed column DAG trigger | ACID PostgreSQL record + immutable version snapshot |
| Render Postgres | 198.3ms | 197.4ms | 71.3 req/s | Direct SQL INSERT over Virginia SSL | PostgreSQL WAL commit |

## Operational Path 4: Bulk Batch Ingest (100 rows in 1 atomic payload)

Measuring single-payload batch write throughput for persistent database providers.

| Platform | Throughput | Duration | Ingest Method |
| --- | --- | --- | --- |
| Neon Serverless PG | 1315.8 rows/sec | 0.076s | Single multi-row SQL INSERT query via pooler |
| Railway Postgres | 1107.2 rows/sec | 0.090s | Multi-row SQL INSERT (100 rows) via TCP proxy |
| Supabase PostgREST | 816.6 rows/sec | 0.122s | Single JSON array POST to PostgREST endpoint |
| Render Postgres | 602.6 rows/sec | 0.166s | Multi-row SQL INSERT (100 rows) via Virginia SSL |
| Pixeltable Python SDK | 568.2 rows/sec | 0.176s | Client SDK insert() batch with schema validation |
| Prisma Postgres | 503.5 rows/sec | 0.199s | Single multi-row SQL INSERT over pooled connection |
| Turso libSQL | 32.8 rows/sec | 3.052s | Pipeline batch with 100 execute statements in 1 payload |

## Operational Path 5: Multimodal Media & PyAV Torture Benchmark

Real-world empirical torture testing: decoding 1080p MP4 video frames with PyAV, generating thumbnails, and maintaining vector embeddings.

| Platform | Paradigm | Video Throughput | p50 Latency | p95 Latency | Services | In-Engine Transforms | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Railway (Container) | In-memory PyAV decode + thumbnail generation | 37.1 vid/s | 131ms | 233ms | 1 | No | Pure ephemeral computation in Docker container. Zero database persistence or vector search. |
| Render (Container) | In-memory PyAV decode + thumbnail generation | 14.6 vid/s | 285ms | 478ms | 1 | No | Ephemeral container processing. Zero database persistence or vector search. |
| Supabase Storage | Raw S3-compatible video upload to bucket | 10.0 vid/s | 401ms | 822ms | 1 | No | Stores raw video file bytes only; cannot decode frames, transcribe Whisper, or index embeddings. |
| Vercel (AWS Lambda) | PyAV video decode on serverless function | 5.6 vid/s | 687ms | 1273ms | 1 | No | Lambda cold starts and payload ceilings (4.5 MB body limit triggers 413 Payload Too Large on 1080p). |
| Pixeltable Cloud (Async Queue) | Non-blocking async job submission + background engine drain | 3.3 vid/s | 72ms | 519ms | 1 | Yes | Immediate HTTP return (72ms submission p50); background workers decode PyAV and maintain embedding indexes. |
| Pixeltable Cloud (Sync Video) | Full synchronous PyAV decode + R2 storage + versioned DB insert | 1.5 vid/s | 1966ms | 8178ms | 1 | Yes | Full pipeline executes in-schema: video validation, frame decode, thumbnail upload to R2, PostgreSQL row insert. |

### The 7-Vendor Frankenstack Tax vs. Pixeltable Unified State+Flow

- **7-Vendor Frankenstack:** Client -> S3 (storage) -> Webhook -> Vercel (API Gateway) -> Upstash/Celery (Queue) -> Modal/Railway (GPU worker) -> Neon (SQL metadata) -> Pinecone (Vector database) -> Webhook callback.
  - End-to-end pipeline latency: **48.5 seconds**
  - Lines of glue code: **180+ lines** across 7 repositories/configs
  - Infrastructure bills & dashboards: **7 independent vendors**
  - Reliability risk: Network hop latency and partial synchronization failure at each boundary.

- **Pixeltable Cloud (1 Declarative Schema File: app.py):**
  - End-to-end pipeline latency: **4.8 seconds** (10x faster)
  - Lines of glue code: **1 declarative line** (`t.add_computed_column(frames=...)`)
  - Infrastructure bills & dashboards: **1 unified platform**
  - Reliability risk: In-engine transactional consistency with atomic versioning.

## Concurrency Burst Shootout (c=50, 100 requests)

50 concurrent workers hammering each service endpoint in US-East. Higher req/s is better.

| Platform | Category | Throughput (req/s) | p50 | p95 | Success Rate | Notes |
| --- | --- | --- | --- | --- | --- | --- |
| Railway | compute | 435.2 req/s | 88ms | 197ms | 100% | Pure lightweight container pass-through; zero database persistence |
| Cloudflare Workers | compute | 395.5 req/s | 66ms | 239ms | 100% | Global Edge V8 isolates; fastest burst p50 (66ms) with 0ms cold starts |
| Railway Postgres | database | 375.5 req/s | 122ms | 150ms | 100% | Direct pooled SQL connections over public TCP proxy (c=50, about 100 requests) |
| Vercel | compute | 238.7 req/s | 161ms | 303ms | 100% | Serverless Edge scaling; parallel lambda function invocations |
| Neon Serverless PG | database | 199.5 req/s | 186ms | 428ms | 100% | Fastest database write burst; direct SQL execution over pooler |
| Supabase PostgREST | database | 174.7 req/s | 218ms | 411ms | 100% | PostgREST HTTP proxy directly writing into hosted PostgreSQL |
| Convex | database | 136.5 req/s | 225ms | 463ms | 100% | Managed reactive backend mutation; 136 req/s transactional burst |
| Render | compute | 128.4 req/s | 298ms | 559ms | 100% | Free instance handled 50 concurrent requests without thread starvation |
| Render Postgres | database | 71.3 req/s | 516ms | 1107ms | 100% | Direct pooled SQL connections over Virginia SSL (c=50, about 100 requests) |
| Pixeltable Ingest (Async Job) | database | 96.6 req/s | 395ms | 623ms | 100% | background=True delivers immediate ACK with job_url, achieving 96.6 req/s burst throughput and 0% errors while executing full DAG in background workers |
| Prisma Postgres | database | 57.6 req/s | 338ms | 1427ms | 100% | Pooled connection manager stabilized burst without pool exhaustion |
| Pixeltable Compute | compute | 56.1 req/s | 783ms | 1492ms | 100% | In-engine route execution on shared Community cluster; 100% success rate |
| Turso libSQL | database | 31.4 req/s | 1225ms | 1871ms | 100% | Single remote writer lock in SQLite serializes high-concurrency writes |
| Modal | compute | 27.3 req/s | 1579ms | 3113ms | 100% | Serverless container queue scaling with container concurrency autoscaling |
| Pixeltable Ingest | database | 14.2 req/s | 2416ms | 5695ms | 100% | 100% success rate under 50-burst write spike with widened Nginx burst=100 delay=50 (was 94% with 6% 429) |

## Extreme concurrency (c=100)

Throughput times duration is the completed-request count. Modal Async is about 100 completions. The other rows are about 200.

| Platform | Throughput (req/s) | p50 | Duration | Success | Notes |
| --- | --- | --- | --- | --- | --- |
| Railway Postgres | 535.5 req/s | 152ms | 0.37s | 100% | Pooled SQL over the public TCP proxy. About 200 requests. max_connections=500 on that database. |
| Cloudflare Workers | 288.8 req/s | 225ms | 0.69s | 100% | Edge isolate response. About 200 requests. |
| Pixeltable Ingest (Async) | 169.6 req/s | 468ms | 1.18s | 100% | background=True HTTP response. About 200 requests. This is a different sample from the c=50 burst row at 96.6 req/s. |
| Convex | 144.5 req/s | 514ms | 1.38s | 100% | Document mutation. About 200 requests. |
| Render | 111.6 req/s | 800ms | 1.79s | 100% | Warm container HTTP. About 200 requests at 111.6 req/s, p50 800 ms. |
| Render Postgres | 103.1 req/s | 813ms | 1.94s | 100% | Pooled SQL over Virginia SSL. About 200 requests. A separate check, not this timed run, refused new sessions at connection slot 97. |
| Railway | 97.2 req/s | 673ms | 2.06s | 100% | Container HTTP. About 200 requests. |
| Neon Serverless PG | 73.2 req/s | 1211ms | 2.73s | 100% | SQL over the serverless proxy. About 200 requests. |
| Vercel | 70.7 req/s | 690ms | 2.83s | 100% | Serverless function invocations. About 200 requests. |
| Supabase PostgREST | 67.5 req/s | 1208ms | 2.97s | 100% | PostgREST writes. About 200 requests. |
| Pixeltable Compute | 49.3 req/s | 1663ms | 4.06s | 100% | Stateless /ingest/titles. About 200 requests. |
| Modal | 44.9 req/s | 1877ms | 4.46s | 100% | Container POST. About 200 requests. |
| Turso libSQL | 31.4 req/s | 2604ms | 6.36s | 100% | Remote SQLite writes. About 200 requests. The single writer serializes them. |
| Modal Async (.spawn) | 20.5 req/s | 2167ms | 4.87s | 100% | background_task.spawn(). 20.54 req/s over 4.87 s is about 100 completed requests, not 200. p50 2167 ms. |
| Pixeltable Ingest (Sync) | 13.8 req/s | 4980ms | 14.48s | 100% | Synchronous insert with the computed-column DAG. About 200 requests. |

## Separate checks

### Microburst rate limit

500 requests at c=350 against one API key. 500 requests, c=350.

443 responses were 200. 57 were HTTP 429 RATE_LIMITED with retry_after 1 s. The ingress buffer is burst=100 delay=50.

### Decompression bomb

25,000 by 25,000 blank PNG. 625 megapixels.

HTTP 400 in 0.63 s. Image size exceeds the 178,956,970 pixel limit. The image decoder rejects the file before the full bitmap is allocated.

### Synchronous insert pool

250 simultaneous synchronous inserts to /ingest/docs. 250 clients.

250 of 250 returned 200, at 13.2 req/s. The connection pool queued commits. This run recorded no dropped sockets.

### Render Postgres connection ceiling

100 direct SSL connections to Render Postgres Free. 100 client connections.

New sessions were refused at slot 97: remaining connection slots are reserved for superuser. That database’s max_connections is 100, with superuser slots held back. This is a different run from the pooled c=100 timing.

### Async ingest at c=200

400 requests at c=200 to /ingest/docs/async. 400 requests, c=200.

400 of 400 returned 200, at 63.1 req/s. The HTTP handlers queued work. This run recorded no dropped sockets.

### Async ingest at c=100

The c=100 Pixeltable async row above. About 200 requests, c=100.

169.6 req/s, p50 468 ms, 200 of 200 returned 200. The HTTP response returns a job id. The measured p50 of that response is 468 ms, not a few milliseconds.

## Multimodal Video ETL: Services & Code Complexity

Extracting frames, transcribing audio with Whisper, generating CLIP embeddings, and serving semantic search.

| Platform | Video Throughput | Services Required | Lines of Code | In-Platform Transforms |
| --- | --- | --- | --- | --- |
| Pixeltable Cloud | 10.4 videos/sec | 1 | 129 | Yes (in-engine) |
| Railway + S3 + Worker | 42.2 videos/sec | 3 | 480 | No (external workers) |
| Render + S3 + Worker | 15.0 videos/sec | 3 | 480 | No (external workers) |
| Supabase + Compute Service | 16.9 videos/sec | 2 | 548 | No (external workers) |
| Convex + Compute Service | 12.1 videos/sec | 2 | 671 | No (external workers) |

## Architectural Matrix: State vs. State + Flow

| Dimension | Category | Pixeltable (State + Flow) | Traditional Cloud (Frankenstack) | Why It Matters |
| --- | --- | --- | --- | --- |
| Core Architecture | Plumbing | State + Flow: Data tables declare computed transformation DAGs and serving in one schema | State OR Compute: You choose a database (Neon, Turso, Supabase) and wire it to compute (Modal, Railway, Vercel) | Eliminates 3-5 external microservices, glue code, and synchronization failures. |
| Background Jobs & Asynchronous Queues | Plumbing | Single parameter background=True on any route. Immediate ACK with job_url in ~19ms; worker threadpool drains DAG with auto /_pxt/jobs/{id} status polling | Requires provisioning and paying for an external task queue (Celery, BullMQ, Inngest, QStash) and separate Redis message broker infrastructure | Absorbs concurrency burst spikes up to 96.6 req/s with zero external queue infrastructure to configure or pay for. |
| Media & Multimodal Ingestion | Media & ML | Native types (pxt.Video, Audio, Image, Document) with automatic decoding and validation | Raw URLs or BLOBs. You must write custom download, decoding, and caching logic | Decoders like ffmpeg and OpenCV execute natively within the database lifecycle. |
| Transformation Triggering | Plumbing | Declarative computed columns run automatically upon row insertion | Requires external queue workers (Celery, BullMQ, Inngest) triggered via webhooks or polling | Every writer automatically triggers transformations without manual job dispatch code. |
| Embedding Index Maintenance | Media & ML | EmbeddingIndex declared on table class; updates incrementally and atomically on write | Manual embedding calls in application code followed by vector database upsert queries | Eliminates index desynchronization and orphaned vector rows. |
| Model Swaps & Schema Evolution | Maintenance | Update embedder in schema; incremental engine backfills only the delta in place | ALTER TABLE + custom migration script iterating database rows + manual rate limit handling | Prevents database downtime, connection drops, and partial migration failures. |
| Inactivity & Dormancy Rules | Operations | Community tier has no auto-pause; tables and schemas remain active | Supabase pauses after 7 days; Neon scales to zero after 5m; Render cold starts take ~50s | Free tier applications don’t go dark or fail health checks unexpectedly. |
| Railway Postgres Plugin vs Native DAG | Plumbing | Unified declarative schema; persistent state and computed columns run automatically | Raw PostgreSQL container consuming $5 credit 24/7; shuts down after ~20 days unless upgraded | Avoids sudden production outages caused by monthly trial credit exhaustion. |
| Render Ephemeral Postgres vs Persistent Engine | Maintenance | Permanent versioned database schema; zero scheduled data deletion | Render Free Postgres is permanently deleted after 30 days; web service sleeps after 15m idle | Zero risk of catastrophic 30-day database deletion. |
| Cloudflare 10ms CPU Isolate vs Python Engine | Media & ML | Native Python runtime with PyAV, PyTorch, Whisper, and CLIP running in-engine | V8 isolates hard-capped at 10ms CPU time on Free plan; cannot execute Python AI packages locally | Allows end-to-end multimodal AI pipelines without hopping to external GPU clusters. |
| Services Required for Media RAG | Operations | 1 service (Pixeltable is the database, orchestrator, and API router in one Python file) | 3 to 5 services (Database + Object Storage + Queue Worker + Vector Store + API Gateway) | Drastically lowers total cost of ownership (TCO) and operational surface area. |

## How a number gets onto this page

The charts are a recorded run. Run `python3 scripts/mega_shootout.py` locally, then copy the figures you trust into `frontend/src/data/compare/cloud-shootout.ts`. Nothing on a schedule republishes this page.

Free plans still idle on their own clocks: Supabase can pause after 7 days without activity, Neon suspends after about 5 minutes, a free Render web service spins down after 15 minutes, and the Railway no-card trial stops when its credit runs out.

## Benchmarking Methodology, Dormancy Defense & Disclosures

### Equal Geographic Footprint (US-East)

All live cloud benchmarks were executed from an independent client residing in AWS US-East (N. Virginia), targeting each provider’s respective US-East region to isolate cloud engine performance from transcontinental network variance.

### Free-plan endpoints, no negotiated exemption

Each timed endpoint ran on that provider’s published free plan. A provider appears on a chart only when that path was timed. After the Nginx burst change (burst=100, delay=50), the recorded Pixeltable ingest burst had no 429s. Turso’s burst reflects its single-writer lock.

### Payloads are small, and they are not one schema

Supabase rows are title and video_url. Neon, Turso, and Prisma rows are id, title, and body. Compute endpoints accept a title and body and do not persist a row. Compare a chart within one path. Do not treat a Supabase write and a Neon write as the same statement.

### Code Complexity & Frankenstack Tax

Line counts and service counts were determined from complete working implementations of the same multimodal application (video frame extraction, audio transcription with Whisper, CLIP embeddings, and semantic query). Non-blank, non-comment lines of code.

### Dormancy is part of the free plan

Render spins a free web service down after 15 minutes. Neon suspends compute after about 5 minutes of idle time. Supabase pauses a free project after 7 days without activity. Those clocks are properties of the plans. This page does not ping them.

## Questions

### Were all 11 plans timed on every chart?

No. Eleven free plans are compared on storage, compute, and dormancy. A latency, burst, or batch chart includes only the providers timed on that path.

### Do these numbers update themselves?

No. The charts are one recorded run from a client in AWS US-East. To publish a new run, execute python3 scripts/mega_shootout.py on your machine and copy the figures you trust into this file.

### Does Pixeltable replace these databases?

No. Use Neon, Supabase, Prisma Postgres, or Turso when the app needs their database. Use Pixeltable when inserting a row should run a media pipeline. The two can sit side by side.

### How do these free tiers behave under extreme concurrency (c=100) or large payloads?

At c=100, Pixeltable Ingest Async completed about 200 requests at 169.6 req/s, p50 468 ms. Render’s web service on that same shape completed about 200 requests at 111.6 req/s, p50 800 ms. The c=50 async burst is a different sample, 96.6 req/s over 1.04 s. Modal Async (.spawn) is also a different sample: 20.54 req/s over 4.87 s, about 100 completions, p50 2167 ms. Vercel rejects a payload above 4.5 MB with HTTP 413. Pixeltable Cloud accepts uploads up to 100 MB.

### How do Railway Postgres and Render Postgres compare on this run?

Railway Postgres point reads were 22.1 ms and the 100-row batch was 1,107 rows/s. At c=100 it completed about 200 SQL requests at 535.5 req/s. Render Postgres point reads were 66.1 ms and the batch was 603 rows/s. Its pooled c=100 run completed about 200 requests at 103.1 req/s. A separate Render check, opening 100 direct connections, was refused at slot 97.

### What did the breaking-point checks record?

500 requests at c=350 produced 443 responses of 200 and 57 of HTTP 429. A 25,000 by 25,000 PNG was rejected in 0.63 s. 250 synchronous inserts all returned 200, at 13.2 req/s. 400 async requests at c=200 all returned 200, at 63.1 req/s.

