Skip to content

perf: indexes + remove slug roundtrip, encode doc URLs as short IDs - #98

Merged
Alimedhat000 merged 2 commits into
mainfrom
perf/db-indexes-slug-roundtrip
Aug 28, 2026
Merged

perf: indexes + remove slug roundtrip, encode doc URLs as short IDs#98
Alimedhat000 merged 2 commits into
mainfrom
perf/db-indexes-slug-roundtrip

Conversation

@Alimedhat000

@Alimedhat000 Alimedhat000 commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes two performance/bloat issues and improves URL UX.

1. Missing DB indexes → seq scans

getDocs filters by Document.authorId and Collaborator.some { userId }. With no index on those columns, Postgres does full table scans. EXPLAIN on the dev DB (49 docs) confirmed:

  • Seq Scan on documents filtered by authorId
  • Seq Scan on collaborators filtered by userId

Under k6 with 1k docs this dominates, not Yjs/CPU. Added 4 indexes:

  • Document @@index([authorId])
  • Collaborator @@index([userId])
  • CollaborationRequest @@index([userId]) and @@index([documentId])

After: Index Scan using documents_authorId_idx. Migration 20260829200000_add_performance_indexes — 0-risk, additive.

2. slugIDtoFullID redundant roundtrip → ~2× WS DB load

After #45 the helper does findUnique where id=slugId and returns it unchanged — the WS documentName is already the full UUID (client sends doc.id via useCollab/paths.getHref, validated by getDocumentPermission). Every dbPersistence.fetch/store paid an extra DB query for zero value.

  • Deleted server/src/utils/slugIDtoFullID.ts and its test (only used in dbPersistence).
  • dbPersistence now uses documentName directly as id.

3. Bare UUIDs in URLs → opaque short IDs

/app/doc/<uuid> exposes internal IDs. Switched to 22-char base64url short IDs (Google/Notion/Linear style) without DB lookup:

  • Added reversible utils uuidToShortId/shortIdToUuid in server/src/utils/short-id.ts (Node Buffer) and client/src/utils/short-id.ts (browser btoa/ fallback, no extra dep).
  • paths.app.document.getHref encodes UUIDs; DocumentPage decodes the :id param via resolveDocumentId with a try/catch that redirects to 404 on malformed input (avoids unhandled 500).
  • Backward compatible: both UUID and short ID are accepted in the route.

Add missing indexes that caused seq scans in getDocs:

- Document.authorId (owned docs lookup)
- Collaborator.userId (collaborated docs via Collaborator.some)
- CollaborationRequest.userId and documentId (request lookups)
- Delete slugIDtoFullID helper that doubled WS DB load: it did
  findUnique where id=documentName and returned it unchanged
  (documentName is already the full UUID after #45). dbPersistence
  now uses documentName directly in fetch/store.

- Add reversible shortId utils (UUID <-> 22-char base64url):
  server/src/utils/short-id.ts and client/src/utils/short-id.ts.
  No DB lookup, opaque IDs like Google/Notion style.

- Encode links via paths.getHref (uuidToShortId) and decode in
  document route with try/catch that redirects to 404 on malformed
  short ID instead of 500.
@Alimedhat000
Alimedhat000 merged commit f1a4b4e into main Aug 28, 2026
2 checks passed
@Alimedhat000
Alimedhat000 deleted the perf/db-indexes-slug-roundtrip branch August 29, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant