Skip to main content

Convex Backend

OpenSync’s entire backend runs on Convex. There is no separate server, no Docker containers, and no infrastructure to manage. Convex provides the database, serverless functions, real-time subscriptions, HTTP endpoints, file storage, and scheduled jobs.

One-click deploy

The fastest way to set up the backend: Deploy to Convex This creates:
  • A new Convex project linked to your account
  • All database tables with their schemas and indexes
  • Serverless functions for queries, mutations, and actions
  • HTTP endpoints for the sync API (/sync/session, /sync/message, /sync/batch, /search, etc.)
  • Search indexes for full-text search
  • Vector indexes for semantic search
  • Scheduled function support for background embedding generation

Manual deploy

1. Install the Convex CLI

npm install -g convex

2. Clone and initialize

git clone https://github.com/waynesutton/opensync
cd opensync
npm install
npx convex dev
On first run, the CLI prompts you to:
  1. Sign in to your Convex account (or create one).
  2. Create a new project.
  3. Push the schema, functions, and indexes.
npx convex dev runs in watch mode. It pushes changes to your development deployment every time you save a file in the convex/ directory.

3. Set environment variables

npx convex env set WORKOS_API_KEY sk_your_key
npx convex env set WORKOS_CLIENT_ID client_your_id
npx convex env set OPENAI_API_KEY sk-your-key  # Optional, for semantic search

4. Deploy to production

npx convex deploy
This pushes your functions and schema to the production deployment. Production deployments have a separate URL from development.

Database schema

The Convex backend defines these tables:
TablePurposeKey fields
usersUser accountsworkosId, email, name, apiKey
sessionsAI coding sessionsuserId, externalId, source, model, totalTokens, cost
messagesMessages within sessionssessionId, externalId, role, textContent
partsMessage content blocksmessageId, type (text, tool-call, tool-result)
sessionEmbeddingsVector embeddings for sessionssessionId, embedding (1536-dim), textHash
messageEmbeddingsVector embeddings for messagesmessageId, embedding (1536-dim)
apiLogsAPI request logsuserId, endpoint, statusCode
dailyWrappedDaily activity summariesuserId, date, stats
docPagesDocumentation page metadataslug, title, content
docEmbeddingsDocumentation search embeddingsdocPageId, embedding

Indexes

Key indexes defined in the schema:
TableIndexFieldsPurpose
sessionsby_useruserIdList sessions for a user
sessionsby_user_externaluserId, externalIdDedup during sync
sessionsby_user_and_sourceuserId, sourceFilter by tool
messagesby_sessionsessionIdList messages in a session
messagesby_external_idexternalIdDedup during sync
Search indexes enable full-text search on sessions.searchableText. Vector indexes enable cosine similarity search on sessionEmbeddings.embedding.

HTTP endpoints

The sync API is defined in convex/http.ts. These are the endpoints that plugins call:
EndpointMethodPurpose
/sync/sessionPOSTCreate or update a session
/sync/messagePOSTCreate or update a message
/sync/batchPOSTBulk sync sessions and messages
/searchPOSTFull-text, semantic, or hybrid search
/healthGETHealth check (no auth required)
/api/sessionsGETList sessions
/api/sessions/:idGETGet session with messages
/api/exportGETExport sessions in eval formats
/api/contextGETGet context for RAG
All endpoints except /health require an Authorization: Bearer osk_... header.

Convex dashboard

Access your project at dashboard.convex.dev:
  • Data tab: Browse and edit documents in any table
  • Functions tab: See all deployed functions, their execution logs, and errors
  • Logs tab: Real-time function execution logs with timing and error details
  • Settings tab: Environment variables, deployment URLs, and project configuration

Scaling

Convex handles scaling automatically:
AspectHow it scales
FunctionsScale to zero when idle, scale up under load
DatabaseStorage grows with usage, no provisioning needed
Real-timeWebSocket connections managed by Convex infrastructure
HTTP endpointsHandle concurrent requests without configuration
The free tier includes 1 million function calls per month, which is sufficient for most individual developers. Teams with higher usage can upgrade through the Convex dashboard.

Monitoring

Function logs

Check dashboard.convex.dev > Logs for:
  • Function execution times
  • Error stack traces
  • Write conflict retries
  • Scheduled function results

Common issues

Write conflicts: If you see retry logs for mutations, check the write conflict patterns documentation. OpenSync’s mutations are designed to be idempotent, but rapid syncing from multiple plugins can occasionally trigger retries. Slow queries: Queries that scan many documents without using an index will be slow. All OpenSync queries use indexes by design, but custom modifications should follow the same pattern.

Next steps