From 6422760b024668cd84295f784633daa28d6010dd Mon Sep 17 00:00:00 2001 From: adela Date: Mon, 2 Mar 2026 18:07:24 +0100 Subject: [PATCH 1/8] add convex vs supabase --- content/blog/convex-vs-supabase.md | 159 ++++++++++++++++++ .../blog/convex-vs-supabase/banner.webp | Bin 0 -> 23784 bytes 2 files changed, 159 insertions(+) create mode 100644 content/blog/convex-vs-supabase.md create mode 100644 public/content/blog/convex-vs-supabase/banner.webp diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md new file mode 100644 index 00000000..290320a5 --- /dev/null +++ b/content/blog/convex-vs-supabase.md @@ -0,0 +1,159 @@ +--- +title: 'Convex vs Supabase: Which Backend Platform Should You Choose?' +author: Adela +updated_at: 2026/03/02 18:00:00 +feature_image: /content/blog/convex-vs-supabase/banner.webp +tags: Comparison +keypage: true +description: 'A detailed comparison of Convex and Supabase covering architecture, real-time capabilities, data model, pricing, and schema management to help you choose.' +--- + +Convex and Supabase are both "backend in a box" platforms, but built on fundamentally different ideas. Supabase wraps PostgreSQL with auth, storage, and real-time subscriptions into one managed service. Convex is a reactive document database where TypeScript functions are your entire backend (no SQL, no ORM, no separate caching layer). + +Choose Convex for real-time collaborative apps built TypeScript-first; choose Supabase for SQL power, Postgres extensions, or self-hosting. + +## Quick comparison + +| Feature | Convex | Supabase | +|---------|--------|----------| +| **Database type** | Reactive document store | PostgreSQL (relational) | +| **Query language** | TypeScript functions | SQL | +| **Real-time** | Built-in, reactive by default | WAL-based subscriptions | +| **Schema definition** | TypeScript schema validation | SQL migrations | +| **Auth** | Built-in (JWT, OAuth) | Built-in (email, OAuth, SSO, MFA) | +| **File storage** | Built-in | S3-compatible, built-in | +| **Edge functions** | Convex Actions (TypeScript) | Edge Functions (Deno) | +| **Vector search** | Built-in | pgvector extension | +| **Open source** | Backend open-sourced Feb 2025 | Fully open-source, self-hostable | +| **Self-hosting** | Not available | Available | +| **Free tier** | Yes (compute + storage limits) | Yes (500MB DB, 50K MAUs) | +| **Paid plan starts** | Usage-based | $25/month | +| **GitHub stars** | [~10K](https://github.com/get-convex/convex-backend) | [~97K](https://github.com/supabase/supabase) | + +## Architecture + +**Supabase** is a managed PostgreSQL platform. When you create a Supabase project, you get a dedicated Postgres instance alongside auth, real-time, file storage, and edge functions, all connected through a single API layer. The database is standard Postgres, which means any Postgres-compatible tool, ORM, or extension works with it. Supabase instances do not pause on paid plans, so there are no cold starts. + +**Convex** takes a different approach. Under the hood, Convex runs a custom transactional document store built on top of a SQL engine, but that SQL layer is completely hidden. You write queries and mutations as pure TypeScript functions that run server-side inside Convex's infrastructure. The platform tracks every data dependency for every active query function. When a document changes, Convex automatically reruns any function that depends on it and pushes the update to connected clients. There is no separate pub/sub configuration, no cache invalidation logic, and no WebSocket setup on your end. + +The result is two very different mental models: Supabase feels like a database with services attached; Convex feels like a reactive backend runtime where the database is an implementation detail. + +## Data model and querying + +**Supabase** gives you full PostgreSQL. That means tables, foreign keys, indexes, views, stored procedures, and complex multi-table queries with joins and aggregations. If you need to analyze a year of order history or run a report across five tables, Postgres handles it natively. Teams that already know SQL are productive from day one. + +**Convex** uses a document model. Data is stored as typed documents in tables, and you query it through TypeScript functions: + +```typescript +// Convex query: fetch messages for a channel +export const listMessages = query({ + args: { channelId: v.id("channels") }, + handler: async (ctx, args) => { + return await ctx.db + .query("messages") + .withIndex("by_channel", (q) => q.eq("channelId", args.channelId)) + .order("desc") + .take(50); + }, +}); +``` + +There is no SQL, no ORM to configure, and TypeScript types flow end-to-end from the database through to your frontend components automatically. The tradeoff is expressiveness: Convex queries are simpler to write for common app patterns but cannot match Postgres for analytical queries, complex joins, or anything that benefits from a mature SQL ecosystem. + +For teams building standard CRUD apps, both approaches work equally well. For teams with data-heavy workloads or existing SQL knowledge, Supabase's Postgres has a clear edge. For teams building TypeScript-first frontends who want minimal backend boilerplate, Convex's model removes significant friction. + +## Real-time capabilities + +This is where the two platforms diverge most sharply. + +**Supabase** real-time works through PostgreSQL's Write-Ahead Log. You subscribe to a table or a filtered set of rows, and Supabase notifies your client when inserts, updates, or deletes happen. This works well for event-driven UIs (chat message notifications, live dashboards, activity feeds). The limitation is consistency: because reads and writes travel over different channels, there is no guarantee that a client's subscription update reflects the exact state that a write produced. For most apps, this does not matter. + +**Convex**'s real-time model is different in kind, not just degree. Every query function you write becomes a live subscription automatically. When any data that the function reads changes, Convex reruns the function server-side and delivers the new result to the client, with consistency guarantees, because the re-execution and delivery happen inside the same system. There is no separate subscription API to configure. You write a query; it is reactive. + +The practical result: collaborative apps (multiplayer tools, live editing, presence systems) are noticeably simpler to build on Convex. Apps that only need to be notified of discrete events ("a new row arrived") work fine on either platform. + +## Schema management and migrations + +**Supabase** uses standard SQL migrations. You write `.sql` files through the Supabase CLI, apply them locally, and push to production. Because it is Postgres, the full range of `ALTER TABLE`, `CREATE INDEX`, and similar DDL statements are available. Schema changes are explicit, versioned, and auditable. + +For teams that want governance around schema changes (review workflows, CI/CD gating, approval policies, and audit logs), [Bytebase](https://www.bytebase.com/) integrates directly with Supabase's PostgreSQL database. This is particularly useful in team environments where multiple engineers are proposing schema changes and you need a structured process before they reach production. + +**Convex** defines schemas in TypeScript using its `defineSchema` function: + +```typescript +// convex/schema.ts +import { defineSchema, defineTable } from "convex/server"; +import { v } from "convex/values"; + +export default defineSchema({ + messages: defineTable({ + channelId: v.id("channels"), + body: v.string(), + author: v.string(), + }).index("by_channel", ["channelId"]), +}); +``` + +Schema changes are deployed alongside code. There is no separate migration file: update the schema definition and Convex handles the rest. This is fast for solo developers but less auditable than SQL migration files in large teams. + +## Authentication and security + +Both platforms include auth out of the box. + +**Supabase** Auth supports email/password, magic links, OAuth (Google, GitHub, and others), phone/SMS, SSO, and MFA. Authorization is enforced through PostgreSQL Row Level Security (RLS): you write SQL policies that control which rows each user can read or write. This keeps security logic close to the data and is easy to audit, though it requires familiarity with SQL policy syntax. + +**Convex** Auth provides JWT-based authentication with similar provider support. Authorization is enforced through query/mutation function logic in TypeScript: you check the user's identity inside the function before touching the database. Developers who think in code rather than SQL policies find this pattern easier to follow, though it scatters security logic across function files rather than centralizing it in the database layer. + +Neither approach is objectively better; it depends on where your team is more comfortable reasoning about access control. + +## Pricing + +Both platforms offer a free tier suitable for prototypes and personal projects. + +**Convex** free tier includes a compute and storage allowance, but projects are not automatically paused for inactivity. Paid plans are usage-based, billed on function execution time and storage volume. There is no fixed monthly floor on the starter paid tier; billing is strictly pay-as-you-go. This can make Convex cheaper than Supabase for very low-traffic apps, but unpredictable for apps with spiky or sustained high-query loads. + +**Supabase** free tier gives you 500MB database storage, 1GB file storage, and 50K monthly active users per project. Free-tier projects pause after 7 consecutive days with no database activity, which is a friction point for demos and staging environments where developers check in occasionally. The Pro plan is $25/month per project (with included resource limits), the Team plan is $599/month, and Enterprise is custom-priced. + +At small scale (a personal app or early startup), both platforms cost roughly the same or less than $30/month. At medium scale (10K MAUs, 20GB database, moderate function usage), Supabase Pro is typically $27-$50/month with overages; Convex's cost depends heavily on how query-heavy your app is. Compute-intensive apps with many concurrent subscriptions may find Convex more expensive at scale than a fixed Supabase Pro plan. + +One practical difference: Supabase's pricing model is predictable because it maps to database size and user counts, metrics teams already track. Convex bills on function execution time, which requires more effort to forecast before a product launches. + +## Open source and self-hosting + +**Supabase** has been fully open-source since its launch and can be self-hosted using Docker. The [GitHub repository](https://github.com/supabase/supabase) has nearly 98K stars. For organizations that cannot use managed cloud services due to compliance or data-residency requirements, Supabase is the only option between the two. + +**Convex** open-sourced its backend infrastructure in February 2025 ([GitHub](https://github.com/get-convex/convex-backend), ~10K stars), but self-hosting is not yet a supported option. The open-source release means you can inspect the code, but running your own Convex instance is not a realistic path for most teams. If avoiding vendor lock-in is a requirement, this is a meaningful constraint. + +## When to choose Convex + +- Your app is built primarily in TypeScript/React and you want type safety from database to UI with zero configuration +- Real-time collaborative features (multiplayer, live editing, presence) are central to your product, not an afterthought +- Your team has limited backend experience and you want to avoid SQL schemas, ORMs, and migration management +- You are building an AI application that needs vector search and reactive data updates in the same system + +## When to choose Supabase + +- You need full SQL power (complex queries, joins, aggregations, stored procedures) +- Your team already knows PostgreSQL and wants to stay in that ecosystem +- Self-hosting or data-residency compliance is a requirement +- You are building a product with a large and growing dataset where analytical queries matter +- You want access to the broader Postgres extension ecosystem (PostGIS, pgvector, TimescaleDB, etc.) +- You need a predictable monthly bill rather than usage-based pricing + +## FAQ + +**Is Convex open source?** +Convex open-sourced its backend in February 2025. The source code for the server infrastructure is available on GitHub, but self-hosting is not officially supported. Supabase is fully open-source and self-hostable. + +**Can Supabase do real-time like Convex?** +Supabase has real-time subscriptions through PostgreSQL's Write-Ahead Log. It works well for event-driven notifications. Convex's reactive model is more automatic (every query becomes a live subscription) and provides stronger consistency guarantees. For deeply collaborative apps, Convex's approach requires less setup. + +**Does Convex use SQL?** +No. Convex queries and mutations are written as TypeScript functions. There is no SQL, no ORM, and no migration files. Schema is defined in TypeScript and deployed alongside your application code. + +**Which is better for AI applications?** +Both platforms support vector search. Supabase uses the `pgvector` PostgreSQL extension; Convex has built-in vector storage alongside its document database. Convex's reactive model is an advantage for AI apps that need real-time data updates (e.g., streaming chat with live context), while Supabase's full Postgres gives more flexibility for complex retrieval pipelines and hybrid search. + +--- + +If you are already evaluating Supabase and want to understand how it compares to AWS-managed Postgres, see [Supabase vs AWS: Feature and Pricing Comparison](/blog/supabase-vs-aws-pricing/). For a broader comparison of the Firebase-vs-Supabase debate that often comes up alongside Convex discussions, see [Supabase vs Firebase](/blog/supabase-vs-firebase/). If TypeScript ORM choice is your next decision after picking a backend, [Drizzle vs Prisma](/blog/drizzle-vs-prisma/) covers that comparison in depth. For questions about the underlying database, [PostgreSQL vs MongoDB](/blog/postgres-vs-mongodb/) explains the relational-vs-document tradeoffs in more detail. diff --git a/public/content/blog/convex-vs-supabase/banner.webp b/public/content/blog/convex-vs-supabase/banner.webp new file mode 100644 index 0000000000000000000000000000000000000000..1949865ed3636ad35a36ab159b7a708feea4c7a6 GIT binary patch literal 23784 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

pw`S7+S zDlu73=n3A4OdeZ_nLn~I3XO=)DiS$mIQeMnpevpPN>7C`R`*n_#+-LgtBt!4Kzr6~ zLG1k{oSHeBkNVUIhk+H@VW%SN8NCB4UDVOy4&M$6$%O+b8N*07}fO_!w-q3CFj_!(ZjC0e1QQl*waL)MKy z)kbP3j=&E9tgsKiR8G*10MU-H|25}&pO|olkIG>1_x#1a85pSO*rbAjaE&Q#{M!A| zehUUCxcOG&&%S>>Kr;O?4fbyvemh?r1Qmt4;2zZ|rDi^)y9QSyX!(j67Kp1G~=@m|3 z1;_GB(?Z=S5TkwD+Qc`UW0-;i0>LuP6hlCQA{uoQcN&vIKH>i|;e9Q|5Cw znYXX#`Es(N)poh{ys$O5b{Hi!>DFGtDHhnQJBsl_LTJr{ZbUt&ATjxE0Nh+#F{`~wiD4Fa(^W;eO!{)E#G zaLgF2%7P;Ct@eb)Rb0stgZ-qP&6f+udw;f~5uh}jWgcDURV@`;)zX(pd+ z9N?IkG7h{W@a|T+lbGP`?N=>YMDqy{uDgXqYY<@al+bwqpe|9=z1)06eruCt=9o@b z+Rw(qutLZRYJjneh$>*?>=I5$!nApv8a#s~5UcbW*-8W8lSKz{7YyuCjdfZq&ls7O z1yuFpYs569!erDKK4#vARIRiD?%&3&*Eoks`*k-FV_J#sVL3-An#1P;?V6#zCb!}U zy=GWEA1~%=(Q-Adnf$6FV$xc!jYIn8jt!EyZ0hmBZ)$$cZOAg}DGob+|BRPL^>J-W zNstLt^^wY-;FXaTbfb>dG-f5(pCXHJD-X>Bc`CN3H>zMjJNNF#?gT|5-Q|&BS;S~t zFjRs9<}vRrF%=uk&!rU&uPuj?Fu&buTbfYrmeU&N7ayvGY^G)c;q%i1F(`sk0ICH5 zJxLOs0Ob|29B%$NwUT6UJF}hI(Mcvu^c6(#t>T^`rYy%b{+{n`dLm@600;nI=^*j* zzF}HH-Vh+RX8RH`Icl7wG&T&Xe;jhIhoRYDx#UiSZ}2Kg|V+AR@5T#{vGC}?D999&}<+x zzVQ1aVE^UpGpTpk5-cc&nWg9h<%29!>)`M_%9GT*km@EVn|FIC-J9|Y=egZ1+L~FI zAEOTHHcIQHbC=#k8R@9oNh=1b68PlDi}p@)G9WV%r|*DRth&KGioQ^C>C9Dk)r3|v z&9kBMLn?Le{Ctx(0aCc-Hs5vMa_4gj{kh|9&$jDhMnneToHMof^|d{pVs9E$!df)Q z3mRrA74SO{aILGh)i#}?FL-asPbFQjvEreQXz$foFlQkH0!A61 zZZ5(q0pOupzKAGuBR7T_^F0v^F<{~mSRpzM%$9}}#5BkIckk`2`(CUf0bPPoGO2(8 z$;D5tzEvr^xGhMd9U**VDNVIHn` zMNnJK9mEd(QuzHjV?C{-q%>);7X6CNlfB{53u7l$6J88^19)(^bW-2*}eJ&jdRAGSi+*%xymjR$_jvx9ZTnK6`$C(z@ zSs&{rl->XrmOe=*?qbGQ*fgS?^`gVsDDc7yh*^9t=!YD$jKa1CTwaHgkyE^9LLtdQ zs`2+8*^a+df}KkcF&zU|@hIw8ZF4T1Y>}f4jtQdPBZ!E_1i-Xn(&LV?vr09YK+Qi0@>J)dO>M&D%m9F@lr_e% zvE%mM{2VBYU1b1Df21Euv(}ky$5evj*QORn_XLr3q&wg{Ge3-$Bc_tA7N<7_U}qq+ z=W~WXVl}duvMEpjz_E(P6L!_)Jc|zi3k%B@s(a6?+LDRsv&XBx)Us+7FaQ8hZA$(a z987kIH~^MnRgmZm!(SoInrG8_hqO`2rU5;nh(}s$H%{4y#`HOso?@G)bOXho(|h>3 zTY7^hGbT`RW6@Hx=jjVE23=!~&u4MP%sE~Qw$TU~EW3(uqhuIN#WOMuDhuuLgxHSO)fa6lWhNo-Lg0d3g#L>1q{L9!<0tSUa$**4q07PuwI|RGu zy!X*0#=PEU0k1P#vzsiHcsz9#04Cv2MTTw=KERr>OR=aE*7LHZT8}9Me>hb{s~cAWyapL)Jj7V-XOQ zQ#zn?T^Xh{ZjQ$4pqH{HcT$nz9vXN{mNGC z#g|P~CgAku>oI~aRz2|Cu!W^%kQLD(%9t41iC+S)a*uN@@n8^{!H^g>iRm)wUdvXW z%n-CcXmwAV$r2ZUBT?SR+4=jxwWB!~T(L`4)k)@MaZ7rA60D7N(HdV z(v8mq#%mjk9s22X%fwMdjUF>S7d9rMu^}>JK7IsnV_yywM)sR;q$aR=>Sw=oB z#QR6}-kn#2u!&F7h<;#q0FJ1{WKN3?vGI%cu(T}YP$O(Aw8BJ;9&`udP5HA?)2QEavf{=dq6~5tpf2pom;xD=YeKyl!5dXn!U7(e-eeI+Wk;{A+$gDio3W2hRPY0iGE zlM3&7Qdxz@=ez2nP`&SQSTY~yc@nsvdlqH1}fN<1^RRj97MS|pd^R1&*}=!an7{h@s!6F z&%-x2d3>^Xbv&vvOW&8e{mB-QsE?Lf^}(q^go;##(tgJqcRVT!X|w<}wa(=i+2RRD z`a&-Q?bJ~ogLNkj1U!hGena1sO0sTHXSNPbugaSs!^&n#Qt8>3X19=zvOtugpH!8; zWkl!l7=p?L1v+MmUS0`yh;diQx6hYa9QS>4mZJD2u`{;Q{5H2o*VUCFzyXr!R%N;d zQ`7g<8rTG-t^MYExNuLvB6ECLBb8W?w z8j1BK#fEA+KTX^k>$MqPKhPmUbkI#x%&I@-3tF5;2>YzHlX2~WBP7ohjCW@nq>F3O z{Nh9}0LlQ{{9!zdyGT5WvHK?O6tlik%41WIK(h?GOeqb0$byh|&fa$`R zG7(irk*UbiJ&%H~f6%N5?-hZC;dK4+d}v@d>k5(@pyP&XI0~-+?e>Xv-wh})4s%eS z-V@uTy+~+K*gW#F;_bUp_xc&qLL`%mi+iYeJ8}PGCwJyO<*{4sa%4oaJyl#tt0vzX zvaDxmdk6s#1#$$49VbdNH_i%qhvibiyB5gy6BAQ+E*hrq-z;(_?*!Te+)OT-_HUPm3*8RGot@Y_VRNkHC)`^Ksa#$9; z;0+y(wV^z-zn&NHRY5Dddz@?SpW}3qbJ^QY_m0BiP3m~RIXsID5IS8yNqdGLy{cszM+EM1^w952 z#;tlWFMIx9D7Icbjl`2Iu62LrHcbb)XaW?Clx|!Bi@aBB4G)J$pNlfAn3YQFEZk9R z&L~Qib>h=D>;Y{ao!lXgPDUzInG&v0@s`kN93FOyaa^W}N@s;h^pwO}>9geM7k=Wm z&A|NX(Ut$`+d+>nNGW!K&&pCcb~7fB->s;2Z@;&tNFDp|<7=T6r@|#agN~SH{;mgM z3Hyh&q)mjEEoERsp~$0c9`k28=gST>8r0|J2dv1rVm3hgD*kIfRox@3`zzeE(-)0wQ@!{ty%fatyb-E!YCF zf>BffH_oRX+MvuS>a^tC_b8-ymYSbm+hiVt#Hh%@Tyy&o6W;1EN-G-GLa{^Xh%b6) zeEFSC7*osfSP~qNb1xJ@V|7ISlr8XCP+mlALVe!9&hxU_Jt?yXcq!fdjGEc zq@u|;P4k=w5bIHpSmg?Kx7~o^J()gu{U4{h;cxZPw%fa+o4*Qrw^fRx@~@@2_4!LW znhcWN;f%a$OW}Rc3iN=gd*+P#hiOiqpsRh9V#hP4ds(YId0NE ztXr|d9s1?)f3=Kk#jyHvdLy*r1ON?63z-udPB69VqoW9FH{}~lr-G%zgzxq)DOl@a z+~|b-YO(6f`zwHM)1WXKeE(IcbP`#Otxd<(u@+0{^{b01(S_`)bD+Y0B~uA@-$h(} z+HYY&Ev8XzU!SJsu>&~qmyt$hWUZ;jmuJq(yfD#xY-{nIv~BUU$(Ru6G zZRB zPeN*-pepV#n|Jl9S)rW~Z;kZYuX<_`jPij(Pzb(*A65KYK`AO}jTGUG8$25Ss**3F z?-dMo~UW7#BK?U4Ek<4JL%kVr$42 z4(`HT_Og+!kx`Uw9DUW6d}Npc_xL=$G>1e-USQm0@p)>;?w70vz(2Om{mzSa8)E~>`*5VkjC7c-Qw>+&;7{m2uVFq8Lh*Vq1PY=f#l36&~ZtQ=%R-ag?v67hUr9JL={j4#ULs>Pun#`zFUHlHpI6 za0%?FJEM=>cbdfQ`l*5d3iF6tYI4i@1&hNaEUES^oE7y5{YMU)(ya}qB)&i?4nQQU zPaDTfx7e68*DK`htVlx_L#j2H2N zMv-z02ixQ|tVJ4Kf}SRV&VzI@IAw{JuHaa!sNPaX-FvP}5XsK6l)RYyZayp~>73qL zeq*6X?mdYu2e}HO!@to@!PacQt|eDOEpoi*VDd9;b%v($q0)IeKWhOj4tc`iS=NaZ zdm;%NjoHUr1re{gO`dvMr6|&s2BZuGsub%papr%2*9{1r0mJk4f8luF`aKt_8z^ef z>s0vUX~aHnH%m71H~kq#YZXfBIsT%tMw()K*^iJp1kCISxn@6e$r6djGL=ZWQ8SdgmgvQC47KsEP;!39Kp+O79`?c{$^v^|=MVMAfq ze-W$hlz-1Km?@c!FhQqPCo^6r$t2#*r%>t3Yk==})*}NFHO0FO0-rb46k;t`;|ZWq}8i_7eJ`Wh?+t%~@b@UJnhoVbwMpY<^;iW0`acUXPg}RWo>bx}rX# zSwzF^_7hhof1fmsa{+X(Z>~&=B`m8@A36e5!2T(moBC5<3sPFD(7i3A^XiqJ(60V0 z{qfS0k*9xxmqm=C={=t2rQ>Jo5GN^_MfMIrZJHv;)p&9xgVVgJtW)l6Fd)5c2R|A$ zbo*~8Sq`Z-8(LCxPGDdVBaI7>t_(`}&Gv=BI;_aHoE1fxJjZl~tI#vL2HWtN=cdCx zRDUxmwzNr0V(esB-^#w^xCu1DX=mFgt^;SoQ%cR@E^$JUEibv9M7Y9TTT@}}_D1Fe#(aPC_;zz1uS)B5 zvw2fsyWN&?Ebs33kiQ%QQ8{eljt%-CtCqRB)*=c*cF?djkV)>ZT0Y4%=p1s=|X(>-1}#os$)db>Y}R7CBQEs!oZ58p}c&)^pfT2t`) zmXt9Kdv>-g{Nv{TDxqbwrTpmwqrryQ z-&%>|Zjd;qzZoXML?&0f$J;c7uq~Oad%+tP&5ijUyt++!#)2v6qw-T|iw90)`)Qq& z7$Dj6`pS zZ#sBCJIf~@W{@_gg4R94>4J(9vY`=6YZp1p-?p6-_JviPXaYRd=@+`{+76tSs*iHF z;nv_IM)d$t2@yqiW<>tb8!#w4Y!EI@XpB$*CA71|sUAj`)KTawPYr&00@%RKDogK^ zHqicW%D{b9^2OGsroS{An;)hq!<>Z@BA@ zMke)u6jAPUtuOGXIjXuv(5qL(*MV;4kUy8n6K@-u`ZGyUT-dC=;B>s zRff~zgXR$eY7D^nR!9}waq>MnW!k4C(}X2e$ckkt=FO-pFnTTPBF%h_nX(dB`7+@A zWeXx?fjoVGW=nL~GP%$6X8NM#X%5vf8nmr2YV%7gJ1*fNyIherZml@AC#O~jlxD;QBH=d7K?`u9KClv39yuC8soM|{%Y;$3I@DT%U*cv*Hx zcI&AejPqzW^>&}3leFEL;3892G5wJf4cDPRy2NuO4u1Yo+vH^aRj4>Y7)#z;JMxjR zsqgZ6ZKnNQi7=mYHSEM_+5kPp!*0>%OYv{+&ujr{KrVHA;;@6*^EF43nc(C8Qhd7r z1J#MdZ$WI`X#?5H1XZJEZCi+2x4H*nyXX#}?;V^qBq(jKlg=M#IDz*dlvc)1iO~LL zFMRoL8{o=s)Pw=oW-|e~hh-_f?ww?|d%7Tevb+TO1(bxXJ82$`9l9P|Jt;ToG=dey zD_1Mi+;yN%hRX9-zrOg)@&Pyh@t?xBeX1J&ejX(Mp zEC0-IMCd*@Yf^4420#e3)F2f&4I#^DUzQg1uvLoZ{B3xjz-^HKQkQnQ>UGRWYzEh^ zs!0Gkn_@cqj8XWTN)-bm&;L|xyKnfP@mEFp!2c{N4d}B%7M@V33;D=T=^9-r6*dLN z0o=-!K-~OuBbL@{J@??g(qLk)u3d+>Z5{9oVrLM>$$5K+g+f|7L(P_RH!3XWIL2uqYiI4@kM`uA-L^bmgG4w{I^$po z4Yk#V@@vgR?T>j~e|V+#?|01}ZMEmjih z$w>nZvkVodhiIPtX~CJ#^Lh5p74$peHBcM$?+5XnYTTQNPqpGl0kT8l6^{TpFaQ{$ z#2v+G%-|I=trAdX6+iG+6kx^4TtQbaOvXhcSlQf>;#%1jrIZo1;L!=T{s$N29%`1`-QXt?}xW4kEgi4~J6d2mx0W$CZP;F@5lZb%FIWSME5h!c81y$=9jlCp;7!mUl2 z)S^X4lMv(7e{vKeU{_c(sBwFn^pHx8A za5&HK3%+3JwdgipwZ&%R^;$q~xv^(M@0##6&fa7Q~|Vgmg??gO3B^o-+h zWR}Lm-(I@#^eEJmGOzG3Dw~8Of9|OJl%8EuYZ3gD#M>)t^X@)w1R;?@;Xq71-{+2e zm|k5$91IRHv6mmZHoIAt5S=T-TD7<|4C1>SU>JC^*wGPOhp$XeKl7!!T{gz-Dhg<%^+qjcxwF0&Z$b+m8}vIB zthI_z|%? zACdzGQfaY-{IpcOa2s4)lv28?ojCV)8>o)HOyU%KB$|UzC#YMxyoupOi>pvr)fn5Ss`9By{e!SC8_v$?E^25CjN# z7@KnVS4eD0%&x{*eb)Mjt}U;K*sWmP4bu)ny8f^3v)%bHIY#S zJU`Z5E!6-300002cu0`}BC%l8xG5ivaMB28 z(f|Me01o!iYvUmYQ8{M9P%G+U00000060?|W$GIO&j`$97zvtL4FD!=Nrn5SrZ}zV zkQ6DQ2Y{#|ow%Ed0H%Nd0001TC%j?khlw)?E-ZSiKx-AWp&q;)A{(uhNdYeFVeUVO z2(mzj#|Cw}o)zUM#_a?k((zL5B= literal 0 HcmV?d00001 From 64ee3ea553db01fa1a57330e5558d1662323db27 Mon Sep 17 00:00:00 2001 From: Adela Date: Tue, 3 Mar 2026 10:20:31 +0100 Subject: [PATCH 2/8] Update content/blog/convex-vs-supabase.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- content/blog/convex-vs-supabase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index 290320a5..953ee165 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -4,8 +4,8 @@ author: Adela updated_at: 2026/03/02 18:00:00 feature_image: /content/blog/convex-vs-supabase/banner.webp tags: Comparison -keypage: true description: 'A detailed comparison of Convex and Supabase covering architecture, real-time capabilities, data model, pricing, and schema management to help you choose.' +keypage: true --- Convex and Supabase are both "backend in a box" platforms, but built on fundamentally different ideas. Supabase wraps PostgreSQL with auth, storage, and real-time subscriptions into one managed service. Convex is a reactive document database where TypeScript functions are your entire backend (no SQL, no ORM, no separate caching layer). From c6db525682f88976a4a5cd25b8aa7afc2994d2fd Mon Sep 17 00:00:00 2001 From: adela Date: Tue, 3 Mar 2026 10:31:19 +0100 Subject: [PATCH 3/8] update --- content/blog/convex-vs-supabase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index 953ee165..3c46a02e 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -8,7 +8,7 @@ description: 'A detailed comparison of Convex and Supabase covering architecture keypage: true --- -Convex and Supabase are both "backend in a box" platforms, but built on fundamentally different ideas. Supabase wraps PostgreSQL with auth, storage, and real-time subscriptions into one managed service. Convex is a reactive document database where TypeScript functions are your entire backend (no SQL, no ORM, no separate caching layer). +[Convex](https://www.convex.dev/) and [Supabase](https://supabase.com/) are both "backend in a box" platforms, but built on fundamentally different ideas. Supabase wraps PostgreSQL with auth, storage, and real-time subscriptions into one managed service. Convex is a reactive document database where TypeScript functions are your entire backend (no SQL, no ORM, no separate caching layer). Choose Convex for real-time collaborative apps built TypeScript-first; choose Supabase for SQL power, Postgres extensions, or self-hosting. From dd8df538124cb484f665b4843014d6cb3fdf299a Mon Sep 17 00:00:00 2001 From: adela Date: Tue, 3 Mar 2026 14:21:57 +0100 Subject: [PATCH 4/8] update for pricing --- content/blog/convex-vs-supabase.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index 3c46a02e..0d8c85d0 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -110,13 +110,16 @@ Neither approach is objectively better; it depends on where your team is more co Both platforms offer a free tier suitable for prototypes and personal projects. -**Convex** free tier includes a compute and storage allowance, but projects are not automatically paused for inactivity. Paid plans are usage-based, billed on function execution time and storage volume. There is no fixed monthly floor on the starter paid tier; billing is strictly pay-as-you-go. This can make Convex cheaper than Supabase for very low-traffic apps, but unpredictable for apps with spiky or sustained high-query loads. - -**Supabase** free tier gives you 500MB database storage, 1GB file storage, and 50K monthly active users per project. Free-tier projects pause after 7 consecutive days with no database activity, which is a friction point for demos and staging environments where developers check in occasionally. The Pro plan is $25/month per project (with included resource limits), the Team plan is $599/month, and Enterprise is custom-priced. - -At small scale (a personal app or early startup), both platforms cost roughly the same or less than $30/month. At medium scale (10K MAUs, 20GB database, moderate function usage), Supabase Pro is typically $27-$50/month with overages; Convex's cost depends heavily on how query-heavy your app is. Compute-intensive apps with many concurrent subscriptions may find Convex more expensive at scale than a fixed Supabase Pro plan. - -One practical difference: Supabase's pricing model is predictable because it maps to database size and user counts, metrics teams already track. Convex bills on function execution time, which requires more effort to forecast before a product launches. +| | Convex | Supabase | +|---|---|---| +| **Free tier** | Compute + storage allowance, no auto-pause | 500MB DB, 1GB storage, 50K MAUs; pauses after 7 days inactivity | +| **Paid plan** | Usage-based (function execution + storage) | $25/month per project + overages | +| **Team plan** | Custom | $599/month | +| **Enterprise** | Custom | Custom | +| **Billing model** | Pay-as-you-go | Predictable tiered | +| **Self-hosting** | Not available | Available (reduces cost) | + +Supabase's pricing maps to database size and user counts — metrics teams already track — making it easier to forecast. Convex bills on function execution time, which is harder to estimate before launch. At medium scale (10K MAUs, 20GB database), Supabase Pro typically runs $27-$50/month with overages; Convex's cost depends heavily on how query-heavy your app is. ## Open source and self-hosting From bf5863f7292d465b2fd69a570774ad335386be51 Mon Sep 17 00:00:00 2001 From: adela Date: Tue, 3 Mar 2026 14:24:14 +0100 Subject: [PATCH 5/8] update when to choose --- content/blog/convex-vs-supabase.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index 0d8c85d0..4d52b7fa 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -139,7 +139,6 @@ Supabase's pricing maps to database size and user counts — metrics teams alrea - You need full SQL power (complex queries, joins, aggregations, stored procedures) - Your team already knows PostgreSQL and wants to stay in that ecosystem - Self-hosting or data-residency compliance is a requirement -- You are building a product with a large and growing dataset where analytical queries matter - You want access to the broader Postgres extension ecosystem (PostGIS, pgvector, TimescaleDB, etc.) - You need a predictable monthly bill rather than usage-based pricing From 42ba3b6b5c2ee714c2920f4847a51ff5a2bb3c51 Mon Sep 17 00:00:00 2001 From: adela Date: Tue, 3 Mar 2026 16:00:14 +0100 Subject: [PATCH 6/8] update --- content/blog/convex-vs-supabase.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index 4d52b7fa..c26ccb8f 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -159,3 +159,20 @@ Both platforms support vector search. Supabase uses the `pgvector` PostgreSQL ex --- If you are already evaluating Supabase and want to understand how it compares to AWS-managed Postgres, see [Supabase vs AWS: Feature and Pricing Comparison](/blog/supabase-vs-aws-pricing/). For a broader comparison of the Firebase-vs-Supabase debate that often comes up alongside Convex discussions, see [Supabase vs Firebase](/blog/supabase-vs-firebase/). If TypeScript ORM choice is your next decision after picking a backend, [Drizzle vs Prisma](/blog/drizzle-vs-prisma/) covers that comparison in depth. For questions about the underlying database, [PostgreSQL vs MongoDB](/blog/postgres-vs-mongodb/) explains the relational-vs-document tradeoffs in more detail. + +If you have already decided and need to migrate, here are the most useful resources: + +**Supabase → Convex** + +- [Migrating from Supabase and Prisma to Convex](https://dev.to/ricardogesteves/migrating-from-supabase-and-prisma-accelerate-to-convex-jdk) – community walkthrough on dev.to +- [Is BaaS enterprise-ready? Hands-on review of Convex and Supabase](https://senacor.blog/is-backend-as-a-service-baas-enterprise-ready-a-hands-on-review-of-convex-and-supabase/) – independent engineering blog comparison +- [Why I picked Convex over Firebase, Supabase, and Neon](https://stack.convex.dev/why-choose-convex-database-for-backend) – developer story on the Convex blog +- [Migrating data from Postgres to Convex](https://stack.convex.dev/migrate-data-postgres-to-convex) – official Convex migration guide + +**Convex → Supabase** + +No genuine third-party migration stories exist yet — Convex is still relatively new and the community is small. The resources below are official ones from Convex and Supabase: + +- [How hard is it to migrate away from Convex?](https://stack.convex.dev/how-hard-is-it-to-migrate-away-from-convex) – Convex's honest take on lock-in +- [Convex limitations](https://www.convex.sucks/) – Convex's own page on where the platform falls short +- [Migrating to Supabase](https://supabase.com/docs/guides/platform/migrating-to-supabase) – official Supabase migration docs From c5e6d5e972c0229843e3015e54aa5142b21e9e79 Mon Sep 17 00:00:00 2001 From: adela Date: Tue, 3 Mar 2026 16:19:16 +0100 Subject: [PATCH 7/8] update --- content/blog/convex-vs-supabase.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index c26ccb8f..cd526b28 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -158,8 +158,6 @@ Both platforms support vector search. Supabase uses the `pgvector` PostgreSQL ex --- -If you are already evaluating Supabase and want to understand how it compares to AWS-managed Postgres, see [Supabase vs AWS: Feature and Pricing Comparison](/blog/supabase-vs-aws-pricing/). For a broader comparison of the Firebase-vs-Supabase debate that often comes up alongside Convex discussions, see [Supabase vs Firebase](/blog/supabase-vs-firebase/). If TypeScript ORM choice is your next decision after picking a backend, [Drizzle vs Prisma](/blog/drizzle-vs-prisma/) covers that comparison in depth. For questions about the underlying database, [PostgreSQL vs MongoDB](/blog/postgres-vs-mongodb/) explains the relational-vs-document tradeoffs in more detail. - If you have already decided and need to migrate, here are the most useful resources: **Supabase → Convex** @@ -176,3 +174,10 @@ No genuine third-party migration stories exist yet — Convex is still relativel - [How hard is it to migrate away from Convex?](https://stack.convex.dev/how-hard-is-it-to-migrate-away-from-convex) – Convex's honest take on lock-in - [Convex limitations](https://www.convex.sucks/) – Convex's own page on where the platform falls short - [Migrating to Supabase](https://supabase.com/docs/guides/platform/migrating-to-supabase) – official Supabase migration docs + +Related comparisons: + +- [Supabase vs Firebase](/blog/supabase-vs-firebase/) +- [Supabase vs AWS: Feature and Pricing Comparison](/blog/supabase-vs-aws-pricing/) +- [Drizzle vs Prisma](/blog/drizzle-vs-prisma/) +- [PostgreSQL vs MongoDB](/blog/postgres-vs-mongodb/) From 63306aa35ec0b8c1735dd68671ece99bf87a3bd3 Mon Sep 17 00:00:00 2001 From: adela Date: Thu, 5 Mar 2026 17:06:04 +0100 Subject: [PATCH 8/8] update --- content/blog/convex-vs-supabase.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/blog/convex-vs-supabase.md b/content/blog/convex-vs-supabase.md index cd526b28..5f7b56b2 100644 --- a/content/blog/convex-vs-supabase.md +++ b/content/blog/convex-vs-supabase.md @@ -163,7 +163,6 @@ If you have already decided and need to migrate, here are the most useful resour **Supabase → Convex** - [Migrating from Supabase and Prisma to Convex](https://dev.to/ricardogesteves/migrating-from-supabase-and-prisma-accelerate-to-convex-jdk) – community walkthrough on dev.to -- [Is BaaS enterprise-ready? Hands-on review of Convex and Supabase](https://senacor.blog/is-backend-as-a-service-baas-enterprise-ready-a-hands-on-review-of-convex-and-supabase/) – independent engineering blog comparison - [Why I picked Convex over Firebase, Supabase, and Neon](https://stack.convex.dev/why-choose-convex-database-for-backend) – developer story on the Convex blog - [Migrating data from Postgres to Convex](https://stack.convex.dev/migrate-data-postgres-to-convex) – official Convex migration guide