Skip to content

Scalability: Handle long chat histories sustainably #7

Open

Description

@melvincarvalho

Problem

Chat rooms like Solid Chat Global (solidweb.org) will grow indefinitely. Current implementation:

  • Loads entire chat document on mount
  • Keeps only last 100 messages in memory (line 1502: slice(-100))
  • No way to view older messages
  • Single file grows unbounded

Solid Chat Spec Approach

The spec recommends time-based sharding:

/chat/
  index.ttl        # Chat metadata
  2024/
    01/
      15/chat.ttl  # Messages for Jan 15, 2024
      16/chat.ttl
    02/
      ...

Proposed Solutions

1. Time-Sharded Storage (Recommended)

Store messages in daily files per spec:

// Write to dated file
const today = new Date().toISOString().slice(0, 10).replace(/-/g, '/')
const dayFile = `${chatRoot}/${today}/chat.ttl`

Pros: Natural archiving, efficient loading, spec-compliant
Cons: More complex querying, need to discover day files

2. Paginated Loading

Only load recent messages, fetch more on scroll:

// Initial: load last 7 days
// On scroll to top: load previous 7 days
// Keep max N days in memory, evict oldest

3. Virtual Scrolling

Only render visible messages in DOM:

// Use IntersectionObserver or virtual-scroller
// Keep all messages in memory, render ~50 at a time
// Recycle DOM nodes on scroll

4. Index File

Create lightweight index for efficient discovery:

# index.ttl
<#index> a :ChatIndex ;
  :hasDay [ :date "2024-01-15" ; :messageCount 42 ] ;
  :hasDay [ :date "2024-01-16" ; :messageCount 108 ] .

Implementation Plan

Phase 1: Virtual Scrolling (Quick Win)

  • Implement virtual list rendering
  • Only render visible messages + buffer
  • Removes current 100-message limit

Phase 2: Pagination

  • Add "Load earlier messages" button
  • Fetch in chunks (e.g., 50 messages)
  • Memory management (evict old chunks)

Phase 3: Time-Sharded Storage

  • Migrate to daily files on write
  • Discover and load day files on read
  • Create migration path for existing single-file chats

Phase 4: Index & Discovery

  • Generate index file on write
  • Use index for efficient day discovery
  • Enable jumping to specific dates

Metrics to Track

  • Initial load time vs message count
  • Memory usage vs message count
  • Scroll performance (FPS)
  • Network requests per session

References

Current Workaround

The slice(-100) in longChatPane.js:1502 prevents memory issues but loses history access.

Activity

  1. melvincarvalho commented on Jan 9, 2026

    @melvincarvalho
    ContributorAuthor

    Alternative: Monthly Sharding

    For moderate-activity rooms like Solid Chat Global, monthly files may be better than daily:

    /chat/
      index.ttl
      2024/
        01.ttl    # ~300KB-1MB per month
        02.ttl
      2025/
        01.ttl
    
    Approach Files/Year Typical Size Discovery
    Daily 365 10-50KB Complex
    Monthly 12 300KB-1MB Simple
    Yearly 1 3-15MB Trivial

    Trade-offs:

    • ✅ Fewer HTTP requests than daily
    • ✅ Simpler file discovery (YYYY/MM.ttl)
    • ✅ Natural monthly rollover
    • ⚠️ Larger files than daily (but still manageable)
    • ⚠️ Can't archive by day granularity

    Recommendation: Start with monthly for general use, allow daily for high-volume rooms via config.

  2. melvincarvalho commented on Jan 9, 2026

    @melvincarvalho
    ContributorAuthor

    Spec Check: Daily is Mandated

    After reviewing the Solid Chat spec, daily files are required for spec compliance:

    "Chat messages are written directly by the participants into a series of chat files organized by date."
    "The URI must be created from the UTC date of the message"

    Required structure:

    /chat/YYYY/MM/DD/chat.ttl
    

    Mitigating Daily File Overhead

    Since we must use daily, optimize with:

    1. Parallel loading - Fetch last 7 days concurrently
    2. Immutable caching - Old day files never change, cache aggressively
    3. Index file - Quick discovery without directory listing
    4. Lazy loading - Only fetch older days on scroll

    Interoperability

    Using daily ensures compatibility with:

    • SolidOS chat-pane
    • Other Solid chat implementations
    • Future ecosystem tools

    Monthly would break interop, so daily + smart loading is the way forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions