Migration snapshot
DecliningPlatform
a Kuzzle
Kuzzle (France, Apache 2.0) is active and committed commits exist in 2025–2026 (sdk-javascript updated Dec 2025), but in 2025 the company explicitly pivoted to IoT/Data/Hypervision verticals: 'we took time to structure.' Generic BaaS positioning has narrowed sharply; community and documentation coverage for general web-app patterns is declining.
Typical timeline
6–10 weeks
Typical cost
$13K–$25K (agency, fixed)
Why teams leave a Kuzzle
Teams that chose Kuzzle as a general-purpose BaaS are finding the platform has repositioned toward IoT and Hypervision — the general web-app ecosystem, community support, and documentation coverage have de-prioritized since 2025.
IoT pivot — general web-app support is de-prioritized
Since 2025 ('2025 was an important year… we took time to structure'), Kuzzle's product roadmap, documentation, and community focus have moved to IoT/Hypervision verticals. If you're building a standard web app, you're working against the platform's direction.
Heavy operational stack for web apps
Kuzzle requires Node.js + Elasticsearch + Redis — three processes to operate, monitor, and maintain. For most web applications, Supabase's managed PostgreSQL provides equivalent functionality with a fraction of the operational burden.
Elasticsearch document model creates relational impedance
Kuzzle uses Elasticsearch as its primary store, optimized for search and analytics rather than relational CRUD. Apps that need foreign keys, joins, and transactions fight the architecture constantly — Elasticsearch is a mismatch for standard relational data patterns.
Smaller community and fewer integrations than alternatives
Compared to Supabase, Appwrite, or PocketBase, Kuzzle has fewer Stack Overflow answers, fewer third-party integrations, and less community tooling for standard web-app patterns — compounding the IoT pivot by leaving general web-app developers with fewer resources.
No built-in relational model
Kuzzle uses document collections over Elasticsearch, creating the same document-to-relational impedance mismatch as Appwrite — teams needing complex relational queries must either denormalize heavily or fight the document model.
What can you actually take with you?
Your data lives in your own Elasticsearch cluster and exports cleanly via elasticdump or snapshot to S3. Application code (plugins, controllers) is standard Apache 2.0 Node.js — yours to take. The Elasticsearch-to-PostgreSQL ETL is the real migration challenge, not data lock-in.
| Asset | Can you export it? | How | Notes |
|---|---|---|---|
| Data | Yes | Stored in your own Elasticsearch cluster; standard ES export/backup methods: snapshot to S3, `_reindex` API, or elasticdump (NPM tool); you own the ES cluster entirely | No vendor data lock-in; Kuzzle never holds data outside your Elasticsearch instance; elasticdump produces JSON files suitable for ETL to PostgreSQL |
| Code | Yes | Kuzzle backend is Apache 2.0 and self-hostable via Docker/K8s; your application plugins and controllers (Node.js) are standard code you own and can copy out at any time | Your business logic code is portable; the Kuzzle engine itself is not migrated but your plugin/controller code is standard Node.js |
| Design/UI | No | n/a — Kuzzle is a headless backend with no UI layer | Your frontend application is entirely separate code you own; Kuzzle Back Office is the platform's admin UI |
| Logic/Workflows | Partial | Kuzzle plugins and controllers are Node.js modules — standard code, portable to Deno Edge Functions or Next.js API Routes with minor runtime adjustments | Kuzzle-specific protocol layer (realtime pub/sub, document event hooks, Kuzzle SDK calls) requires rework against new platform APIs; pure business logic ports cleanly |
| Users & Auth | Partial | Built-in user management stores user records in Elasticsearch (exportable via elasticdump); user data migrates; password hash export NOT documented — plan forced password reset | User emails and metadata export cleanly; password hashes are not confirmed as portable; communicate a password-reset flow to your users before cutover |
Swipe the table sideways to see the full breakdown.
Where each piece moves in code
The target stack is Next.js (App Router) + Supabase PostgreSQL — replacing Kuzzle's Elasticsearch + Redis + Node.js triple-process setup with a managed single-database platform; Kuzzle plugins port to Supabase Edge Functions or API Routes.
a Kuzzle
Kuzzle collections (Elasticsearch indexes)
In code
Supabase PostgreSQL tables
ES documents → SQL rows; nested objects → PostgreSQL JSONB columns or normalized child tables; arrays → junction tables
a Kuzzle
Kuzzle REST API
In code
Next.js API Routes or Supabase auto-generated REST API
Supabase auto-generates REST from your PostgreSQL schema; custom business logic lives in API Routes
a Kuzzle
Kuzzle Realtime (pub/sub, document subscriptions)
In code
Supabase Realtime channels (WebSockets)
Supabase Realtime supports Broadcast (pub/sub), Presence, and database change listeners — functional equivalent of Kuzzle's subscription system
a Kuzzle
Kuzzle plugins and controllers (Node.js)
In code
Supabase Edge Functions (Deno) or Next.js API Routes
Node.js logic is largely portable to Deno with minor adjustments; replace Kuzzle SDK calls with Supabase SDK
a Kuzzle
Kuzzle Auth (local + OAuth)
In code
Supabase Auth
OAuth providers reconfigure; user email records migrate from Elasticsearch; passwords require reset
a Kuzzle
Kuzzle document storage (Elasticsearch indexed documents)
In code
Supabase tables (JSONB for unstructured data) or normalized PostgreSQL schema
Unstructured or semi-structured docs use JSONB; structured relational data gets proper columns and foreign keys
a Kuzzle
Elasticsearch search features (full-text, geo, aggregations)
In code
PostgreSQL full-text search (tsvector), pgvector, or dedicated Algolia/Typesense integration
If your app uses heavy ES search features, plan replacements explicitly; Postgres full-text covers basic cases; complex geo or aggregation queries may need Typesense
The migration roadmap
The Elasticsearch-to-PostgreSQL ETL is the most demanding phase — plan it before anything else. Everything else (logic port, realtime, auth) follows the standard BaaS migration pattern.
Phase 1: Audit and data snapshot
1 week- Snapshot the Elasticsearch cluster to S3 immediately — full data backup before any migration work begins
- Export collection (index) mappings via GET /your-index/_mapping for every collection
- Document all Kuzzle controllers and plugins with their route definitions and trigger types
- List all realtime subscriptions your frontend uses: channels, filters, document subscriptions
- Audit which Elasticsearch features the app actively uses: full-text search, geo queries, aggregations, percolate
Watch out: Elasticsearch-specific field types (geo_point, percolate, completion, token_count) have no direct PostgreSQL equivalent — flag these early
Phase 2: Schema design (ES documents → PostgreSQL)
1–2 weeks- Map each Elasticsearch index to a PostgreSQL table schema; flatten simple attributes to columns
- Decide for each nested object: JSONB column (flexible but less queryable) or normalized child table (relational)
- Map ES arrays to junction tables or JSONB arrays depending on query patterns
- Plan search replacement: PostgreSQL tsvector for basic full-text; Typesense/Algolia for complex search needs
- Write sample PostgreSQL DDL and validate with your most complex query patterns
Watch out: This phase is intellectually demanding — complex Elasticsearch mappings with nested types can take 1–2 weeks to correctly normalize
Phase 3: ETL — Elasticsearch to PostgreSQL
1–2 weeks- Use elasticdump to extract all documents as JSON per collection
- Write transformation scripts to convert ES JSON documents to PostgreSQL-compatible row format
- Load transformed data into Supabase via COPY, INSERT batches, or pg_bulkload
- Validate data integrity: row counts, sample record comparison, JSONB field completeness
- Run ETL on a copy first; production ETL only after validation passes
Phase 4: Logic port — plugins and controllers
2 weeks- Rewrite Kuzzle controllers as Next.js API Route Handlers (app/api/[route]/route.ts)
- Port Kuzzle plugins to Supabase Edge Functions (Deno); replace Kuzzle SDK calls with Supabase SDK
- Migrate Kuzzle Auth to Supabase Auth; configure OAuth providers; plan password-reset campaign
- Replace Kuzzle realtime subscriptions with Supabase Realtime channel subscriptions in frontend code
Watch out: Kuzzle plugins using Kuzzle-internal APIs (not standard Node.js) require a rewrite rather than a port; pure business logic functions port cleanly to Deno with minor adjustments
Phase 5: Cutover
1 week- Run new stack in parallel with Kuzzle pointing at the migrated PostgreSQL database
- Update frontend API endpoints and Kuzzle SDK calls to Supabase SDK equivalents
- Validate all Realtime subscriptions in staging environment
- Execute password-reset campaign for all active users; decommission Kuzzle + Elasticsearch + Redis
Three ways to migrate — honestly
Every path has a real trade-off. Here is what each costs, how long it takes, and where it bites.
DIY with AI tools
$0–$500 + time
3–6 months part-time
Fits
Developers comfortable with Elasticsearch, ETL scripting, and TypeScript who have a relatively flat document schema and minimal Elasticsearch-specific search features in use
Risks
The Elasticsearch-to-PostgreSQL ETL is the hardest part to DIY — nested document schemas, field type mismatches, and data integrity validation require careful scripting; mistakes lose data silently
Freelancer
$4K–$10K
6–10 weeks
Fits
Teams with a moderate number of collections (under 20), simple document structures, and Kuzzle plugins that are mostly standard Node.js business logic with minimal Kuzzle-internal API usage
Risks
Complex Elasticsearch mappings or heavy use of ES-specific features (geo, aggregations) can balloon the ETL scope beyond initial estimates; ensure freelancer has proven ES-to-Postgres ETL experience
Agency (RapidDev)
Done-for-you$13K–$25K fixed
6–10 weeks
Fits
Teams with production Kuzzle deployments, complex ES document schemas, active realtime subscriptions, or Elasticsearch search features that need a replacement strategy; fixed price covers ETL, logic port, realtime migration, and cutover
Risks
Minimal — fixed-price scope includes ES snapshot, schema design, ETL validation, plugin port, and parallel-run cutover. Free scoping call at rapidevelopers.com.
The real risks — and how to defuse them
Elasticsearch-to-PostgreSQL ETL complexity — nested objects, arrays, and ES-specific field types (geo_point, percolate) require custom transformation
Mitigation: Start ETL design early with representative sample documents; write and validate transformation scripts before bulk import; run a full dry-run ETL with row count and field completeness verification before production cutover
Loss of Elasticsearch search strengths — full-text search, geo queries, and aggregations have no direct PostgreSQL equivalent
Mitigation: Audit which ES search features your app actively uses before committing to a pure Postgres target; plan explicit replacements: PostgreSQL tsvector for basic full-text, pgvector for semantic search, Typesense or Algolia for complex search needs
Kuzzle realtime protocol differences — Kuzzle WebSocket message format differs from Supabase Realtime channel API
Mitigation: Abstract realtime behind a client service layer before migration; document all active realtime channels and subscription filters; test Supabase Realtime equivalents in staging before touching frontend
IoT-pivoted community support — Kuzzle maintainers and community are less responsive to general web-app migration questions
Mitigation: Rely on Kuzzle's Apache 2.0 source code and official docs, not community support, for deep technical questions; the source is readable and the ES cluster is yours to inspect directly
Password hashes not documented as portable — existing users need a password-reset flow
Mitigation: Plan the password-reset campaign as a first-class phase, not an afterthought; collect user emails early; use magic links for first post-migration login to minimize friction
Should you actually migrate?
Migrating is a real project. Sometimes staying is the right call — here is the honest split.
Stay if
- Your application is an IoT or Hypervision platform that genuinely benefits from Kuzzle's multi-protocol API (MQTT, WebSocket, HTTP), geofencing, and device management — this is now Kuzzle's primary, best-supported use case
- You need real-time pub/sub at scale and Kuzzle's event pipeline handles it reliably for your workload — the platform's realtime capabilities are a genuine strength
- You're self-hosting Kuzzle successfully under Apache 2.0 with a stable stack and your operational team is comfortable with Elasticsearch — the license and data ownership are clean
Migrate if
- Your app is a general web application (CRUD, auth, file storage, relational data) and you're working against Kuzzle's IoT-centric evolution to get basic web-app features — the platform has moved on from your use case
- The Elasticsearch + Redis + Node.js operational burden exceeds your team's capacity and you'd prefer Supabase's managed Postgres with zero infrastructure overhead
- You need relational joins, foreign keys, or complex SQL queries — Elasticsearch's document model creates ongoing impedance for standard relational patterns
Our honest verdict
Kuzzle is legitimate open source with real IoT strengths, and your data is yours. Migrate when your use case is a general web application — the platform's 2025 IoT pivot means your long-term support path as a general web app narrows with each release cycle.
Do this today: pre-migration checklist
Whatever path you choose, protect yourself first. Work through this before you touch a line of code.
Snapshot your Elasticsearch cluster to S3 today
This is your complete data backup — documents, mappings, and settings; take it before any migration work begins and verify the snapshot restores cleanly
Export every collection mapping via GET /your-index/_mapping
Index mappings define field types and structures; they are the schema specification you need to design the PostgreSQL DDL equivalents
Document all Kuzzle controllers and plugins with their route definitions
Controllers and plugins are your API surface; a complete inventory with input/output shapes sizes the API Route rebuild before scoping begins
List all realtime subscriptions your frontend uses
Realtime subscriptions are the most disruptive client-side change; knowing every channel and filter before migration prevents broken real-time features at cutover
Audit which Elasticsearch features your app actively uses
Full-text search, geo queries, aggregations, and percolate queries all need explicit replacement plans — these have no automatic PostgreSQL equivalent
Inventory every Kuzzle SDK call in your frontend and mobile code
Each SDK call is a migration touchpoint; knowing the full list prevents missed API updates at cutover
Check which Kuzzle plugins use Kuzzle-internal APIs vs standard Node.js
Pure Node.js business logic ports cleanly to Deno Edge Functions; plugins that call Kuzzle-internal APIs require a rewrite rather than a port — this distinction drives scope
Frequently asked questions
Can I export my Kuzzle data?
Yes. Your data lives in your own Elasticsearch cluster — Kuzzle never holds it separately. Use elasticdump (an NPM tool) to extract all documents as JSON per collection, or use Elasticsearch's native snapshot API to back up the full cluster to S3. Data lock-in is not the challenge; the Elasticsearch-to-PostgreSQL transformation is.
Can I export my Kuzzle application code?
Yes. Kuzzle is Apache 2.0 open source, and your plugins and controllers are standard Node.js code you wrote and own. Copy them out of your project directory at any time. The Kuzzle engine itself isn't portable, but your business logic code is — and it ports cleanly to Deno Edge Functions or Next.js API Routes with minor adjustments.
How long does a Kuzzle migration take?
Typically 6–10 weeks with a dedicated team. The Elasticsearch-to-PostgreSQL ETL and schema design is the most time-intensive phase — complex nested document mappings can take 1–2 weeks alone. After that, plugin/controller ports and realtime migration are relatively mechanical. A small app with flat document schemas and minimal ES search features can finish in 4–6 weeks.
What happens to my users and passwords when I migrate from Kuzzle?
User email records and metadata export from Elasticsearch via elasticdump. Password hash export is not documented as a confirmed feature — plan a forced password-reset flow for all users post-migration. Collect user emails before cutover so you can send reset links. OAuth users (Google, GitHub) re-authorize with the new provider config and don't need password resets.
Is Kuzzle still actively maintained?
Yes, with an important caveat: Kuzzle is active and commits occurred in 2025–2026 (sdk-javascript updated Dec 2025), but the company's focus has pivoted to IoT/Hypervision verticals since 2025. If your app is an IoT platform, Kuzzle is well-supported. If it's a general web application, the community and documentation coverage for your use case is narrowing.
What replaces Kuzzle's Elasticsearch search features after migration?
It depends on what you use: for basic full-text search, PostgreSQL's tsvector and tsquery are built-in and often sufficient. For semantic/vector search, pgvector adds embedding-based similarity search. For complex search with faceting, autocomplete, and geo queries similar to Elasticsearch's strengths, integrate Typesense or Algolia alongside your Supabase PostgreSQL database. Audit your actual search features before choosing — many apps use only basic full-text search.
Should I migrate to Supabase or stay on Elasticsearch?
Migrate to PostgreSQL (Supabase) if your app is primarily CRUD, auth, and relational data — Elasticsearch was never the right fit for this, and you'll gain simpler operations and better relational query support. Stay with Elasticsearch (or add it as a dedicated search layer alongside Postgres) only if your app's core functionality depends on Elasticsearch's search and analytics strengths: full-text ranking, geo queries, or aggregation pipelines.
How much does a Kuzzle migration cost with an agency?
RapidDev offers fixed-price Kuzzle migrations at $13K–$25K depending on complexity — primarily the number of collections, document schema complexity, and active Elasticsearch search features requiring replacement. The fixed scope covers ES snapshot, schema design, ETL validation, plugin port, realtime migration, and cutover. Book a free scoping call at rapidevelopers.com.
We migrate no-code apps to production code
- Fixed price — $13K–$25K (agency, fixed)
- No data loss, no downtime
- You own 100% of the code
30-min call. Quote within 48 hours.