Skip to content

[Tracking] Make docs.plus faster and cheaper: web bundle, infrastructure and monthly cost #571

Open

Description

@HMarzban

Summary

docs.plus loads more JavaScript than it needs, and its infrastructure is sized far above today's traffic. This tracker reviews both, measures first, then splits the work into child issues. The goal is a faster first load for every visitor and a lower monthly bill, with no loss of reliability.

Every number below was measured on 2026-10-21. Nothing here is a fix yet.

1. Web speed: the webapp bundle

From the next build output of main at 17a67c262:

What Size
First Load JS shared by every page 1.82 MB
chunks/pages/_app-*.js (on disk, before compression) 5.05 MB
One more shared chunk (b843dff3-*.js) 5.09 MB
Home page (/) First Load JS 3.76 MB
/mcp and /oauth/consent First Load JS 3.74 MB each
  • next-pwa reports that both 5 MB chunks are too large to precache, so the offline cache cannot hold them.
  • The home page loads twice the JavaScript of a pad page. A landing page should be the lightest page.
  • apps/webapp/CLAUDE.md already notes that <BottomSheet /> on every route pulls about 44 static chains into the editor stack.

Steps

  1. Run a bundle analyzer on the production build. List the 10 largest modules in _app and in the 5.09 MB chunk.
  2. For each one, decide whether it must be in _app, or can load with next/dynamic on first use. Trace from _app.tsx, not from a page.
  3. Set a budget, for example First Load JS under 1 MB for / and for a pad, and add a check that fails the build when it grows past it.
  4. Measure the result with Lighthouse on a mid-range phone profile: LCP, TBT and total transfer size, before and after.

2. Infrastructure: right-size the servers

The production host, read-only, at 10:50 UTC:

What Value
CPUs / RAM 4 / 15 GB, with 10 GB available
Load average 0.06, 0.25, 0.50
Running containers 25
Disk 158 GB, 76% used
Docker build cache 34.6 GB, of which 29.4 GB can be reclaimed
Docker images 13.1 GB, of which 12.1 GB can be reclaimed
  • Signed-in use is very low today: 2 active sessions in 24 hours, and 7 users sent a heartbeat in 7 days.
  • The monitoring stack uses more memory than the app. Prometheus, Grafana, Loki, Alloy, GlitchTip and cAdvisor hold about 1.5 GB. The webapp and rest-api replicas hold about 560 MB together.
  • Every app service runs 2 replicas for blue-green deploys.
  • The production database cluster also hosts staging and other projects (Tighten production access: Spaces key, Spaces CORS, shared database cluster, default grants #570).

Steps

  1. Add a scheduled clean-up of the Docker build cache and old images, so the disk does not fill. Today about 41 GB can be reclaimed.
  2. Read 30 days of CPU, memory and disk from Grafana. Then decide the smallest host size that keeps peak use under 60%.
  3. Decide whether the observability stack stays on the app host, moves to a smaller host, or moves to a hosted free tier.
  4. Check the managed database plan against its real size and connection count.

3. Monthly cost

The maintainer fills in this table from each billing page. No figure is guessed here.

Service What it runs Monthly cost
DigitalOcean droplet app, Traefik, Redis, observability, CI runner to fill
DigitalOcean managed PostgreSQL shared cluster to fill
DigitalOcean Spaces + CDN editor media to fill
Supabase auth, chat, realtime, storage to fill
Email (Resend) sign-in and notification mail to fill
Domains, GitHub, other to fill

Steps

  1. Fill the table, and mark the three largest lines.
  2. For each of those, write one cheaper option with its trade-off. Examples: a smaller droplet, Spaces lifecycle rules for old media, or a lower Supabase compute tier.
  3. Rule which options to take, then file each one as a child issue in this milestone.

Out of scope

Acceptance criteria

  • The bundle analysis is posted, with the top modules and a ruling for each.
  • A bundle budget check runs in CI.
  • The host clean-up is scheduled, and disk use is under 60%.
  • The cost table is filled, and each ruled saving has its own child issue.
  • A before-and-after Lighthouse result is posted for / and one pad.

Activity

  1. added this to the v2.4.0 milestone on Oct 21, 2026
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

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions